| |
在Eclipse中创建新的重构功能 |
|
时间: 2005-12-05 来自:ibm |
 |
|
|
总体结构和流程
在Eclipse中,一个重构操作主要由以下三个部分组成:
1. RefactoringWizard类:RefactoringWizard提供了向导式的用户界面来引导用户完成重构工作。不需要我们做任何工作,Eclipse已经通过RefactoringWizard为我们提供了预览页面、条件检查页面以及Undo/Redo等功能。我们需要继承这个类从而为重构过程提供特定的用户界面。
2. Refactoring类:Refactoring类完成具体的定位和修改代码功能。为了建立新的Refactoring,我们需要继承这个类并实现重构的逻辑部分。
3. AST和ASTParser:在Refactoring类中,我们需要对代码进行定位和修改,这可以通过AST机制来完成。AST是abstract syntax tree的简称,它能够将Java代码解析成为一个树形结构。在利用了AST树之后,对源代码的修改变成了对AST树的遍历、更改节点属性,以及插入和删除节点等。
一个典型的重构操作流程如下所示:
1. 用户选择要进行重构的对象,通过菜单项或按钮启动重构操作。
2. 创建具体的Refactoring类,弹出RefactoringWizard。
3. RefactoringWizard与用户交互,引导用户输入必要的参数;RefactoringWizard调用Refactoring类的函数进行条件检查。
4. Refactoring类创建AST,并利用其对源代码进行定位和修改。这里进行的修改并不直接应用到源代码上,而是被保存成Change对象,供Refactoring框架使用。
5. RefactoringWizard调用Refactoring类的函数,获得重构内容的详细描述信息(即第4步生成的Change对象),显示在预览界面上,待用户确认。
6. 用户确认后Refactoring框架将修改代码,重构操作结束。
接下来,我们将详细介绍新建重构类型的各个步骤。
创建插件工程
在大家对整个系统构架有了一个大概的了解之后,我们的介绍就从创建工程开始。大家都知道Eclipse提供了很好的扩展性,通过创建插件就能把我们要添加的重构功能无缝的插入到Eclipse平台中。创建插件工程的方法在很多地方都有介绍,这里不再详细讲解。
通过菜单 File -> New-> Project,选择Plug-in Project。点击Next,出现对话框,输入项目名称manage.annotation,接受其他选项的默认值。点击Next,出现插件属性设置的对话框,继续接受默认值。点击Next,出现选择插件模板对话框,该工程要在Refactor菜单中添加一个新的菜单项,所以这里我们采用"Hello,World"的插件模板。点击Next,修改"Action类名称"的值为AnnotationManageAction,点击Finish按钮。至此,一个最基本Eclipse工作台的插件工程就被创建出来了。 插件工程创建后,缺省进入Plug-in开发透视图,Plug-in Manifest编辑器自动打开,显示这个插件工程的基本信息,如对其他插件的依赖,扩展点,构建(build)的配置信息等等。由于该工程需要用到其他插件的功能,必须为其添加到其他插件的依赖。在Plug-in Manifest编辑器点击Dependencies页面,在该页面中的Required Plug-ins列表中通过Add按钮添加如下的插件:
清单 2
或者也可以通过直接修改MANIFEST.MF文件完成。操作完成后察看MANIFEST.MF文件,注意Require-Bundle列表中是否出现了新添加的这几项。MANIFEST.MF文件如下:
清单 3
Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Annotation Plug-in Bundle-SymbolicName: manage.annotation; singleton:=true Bundle-Version: 1.0.0 Bundle-Activator: manage.annotation.AnnotationPlugin Bundle-Localization: plugin Require-Bundle: org.eclipse.ui, org.eclipse.core.runtime, org.eclipse.jface.text, org.eclipse.ltk.core.refactoring, org.eclipse.ltk.ui.refactoring, org.eclipse.jdt, org.eclipse.jdt.core Eclipse-AutoStart: true | 在Plug-in Manifest编辑器中打开插件清单文件plugin.xml,可以看到,这个插件扩展了org.eclipse.ui.actionSets扩展点,这是一个基本的Eclipse工作台的扩展点,通过扩展它,插件可以很简单得对Eclipse的菜单、工具条进行扩展。这个plugin.xml是"Hello,World"插件模板的清单文件,我们把它改成适合这个工程的文件。清单如下:
清单 4
<?xml version="1.0" encoding="UTF-8"?> <?eclipse version="3.0"?> <plugin>
<extension point="org.eclipse.ui.actionSets"> <actionSet label="Annotation Action Set" visible="true" id="manage.annotation.actionSet"> <menu label="%Refactoring.menu.label" path="source" id="org.eclipse.jdt.ui.refactoring.menu"> <separator name="reorgGroup"/> </menu> <action class="manage.annotation.actions.AnnotationManageAction" icon="icons/sample.gif" id="manage.annotation.actions.AnnotationManageAction" label="%Annotation.manage" menubarPath="org.eclipse.jdt.ui.refactoring.menu/reorgGroup" toolbarPath="reorgGroup" tooltip="Manage Annotation in Java Project"/> </actionSet> </extension> </plugin> | 该清单文件表明,在Refactor菜单中添加了一个新菜单项"Annotation Manage",并在工具条上相应添加了一个按钮。点击菜单项或者按钮的事件由类"manage.annotation.actions.AnnotationManageAction"处理。
最后需要修改的就是manage.annotation.actions.AnnotationManageAction类。它继承了org.eclipse.ui.IWorkbenchWindowActionDelegate接口,该接口用于处理各种通过扩展点添加的操作。当菜单项或者按钮被点击时,这个类就被Eclipse工作台装载进来,处理转发过来的请求以及接下来的操作。
AnnotationManageAction被创建后,一旦用户的选择部分有所改变,接口的selectionChanged函数就会被触发,告知用户所选择的部分,可以在这个函数中根据用户的选择相应的修改操作的可用性或者其他显示属性。例如在本文的工程中,我们希望只有当用户选择了一个Java模型元素时才能使用这个操作,那么就需要在selectionChanged中添加如下的代码:
清单 5
public void selectionChanged(IAction action, ISelection selection) { if (selection.isEmpty()) select = null; else if (selection instanceof IStructuredSelection) { IStructuredSelection strut = ((IStructuredSelection) selection); if (strut.size() != 1) select = null; if (strut.getFirstElement() instanceof IJavaElement) select = (IJavaElement) strut.getFirstElement(); } else select = null;
action.setEnabled(select != null); } | selectionChanged函数的参数selection记录了用户选择的部分,我们首先判断它的选择部分的数目是否为一,然后判断这个唯一的选择部分是否为Java模型元素,这两个条件任何一个不满足都会导致action.setEnabled(false)的执行,这时会弹出如下的对话框说明操作不可用,同时菜单项和按钮都会显示成灰色,直到用户选择了合适的部分时,菜单项和按钮才会实显,就可以进行具体的操作了。
 图 4 表明Action目前不能执行的对话框 | 操作的执行是在AnnotationManageAction的run函数中实现的,例如在本文的工程中,就是弹出RefactoringWizard对话框,指导用户完成重构的工作,这些我们将在下面的章节中讲述。
|
|
|
|
|
|
|
|