版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、在Eclipse中创建新的重构功能(2)扩展Refactoring类通过前面系统构架的介绍,大家知道了Refactoring和RefactoringWizard是完成EClipse重构功能的基础类。在创建好插件工程后,我们就通过扩展Refactoring来实现具体的功能。Refactoring是所有支持代码转化的类的抽象父类,它在整个流程中与RefactoringWizard交互以完成重构的功能,起着非常重要的作用。这些类需要提供以下两类方法:用于条件检查的方法,判断重构操作大体而言能否执行,以及具体的转化能否完成;创建Change对象的方法,Change对象描述了所有将要执行的对当前代码的修
2、改操作。Refactoring类的典型流程如下所示:1. 具体的Refactoring类被创建。2. 获得用户选择的要进行重构的对象,初始化该Refactoring类。这个由具体的实现类给出相应的方法。3. 在重构操作开始执行时,首先调用Refactoring的checkInitialConditions(IProgressMonitor) 基于用户选择的对象做一个的初始检查,这个通常由界面自动执行。返回RefactoringStatus.FATAL表明初始检查没有通过,重构操作不能继续。4. 获得进行重构的其他参数,比如,对重命名操作来说就是指新名字。这个通常是由界面根据用户的输入提供的。由
3、具体的实现类给出相应的方法。5. 获得用户输入参数后,调用Refactoring的checkFinalConditions(IProgressMonitor)进行剩下的检查,这个通常由界面自动执行,返回RefactoringStatus.FATAL表明最后的检查没有通过,重构操作不能继续。6. 调用Refactoring的createChange(IProgressMonitor)获得Change对象,这个通常由界面自动执行,界面可以根据Change对象显示预览界面。基于以上的介绍,为了实现本文工程中的重构操作,我们需要扩展Refactoring类,为它增加一个构造函数,并且具体实现check
4、InitialConditions、checkFinalConditions和createChange三个函数。首先通过菜单File - New-Class弹出创建类的对话框,输入包名manage.annotation.refactor,类名AnnotationRefactoring,输入父类org.eclipse.ltk.core.refactoring.Refactoring,选中继承抽象方法复选框,点击完成按钮,一个扩展了Refactoring的最基本的类AnnotationRefactoring就被创建出来了。首先为其增加构造函数,以用户选择的Java模型元素作为参数。Refactor
5、ing分析这个参数以得到所有相关的可写Java文件,作为重构操作的对象,如果该模型元素包含在Java文件中,则找到包含它的文件节点;如果该模型元素包含Java文件,则找到它的所有子Java文件。构造函数代码如下:清单 6public AnnotationRefactoring(IJavaElement element) while (element.getElementType() IJavaElement.COMPILATION_UNIT) element = element.getParent();if (element = null)return;if (element.getEleme
6、ntType() = IJavaElement.COMPILATION_UNIT) if (!element.isReadOnly()compilationUnits.add(element);if (element.getElementType() IJavaElement.COMPILATION_UNIT)findWritableCompilationUnits(element); 接着完成checkInitialConditions函数,实现初始检查的具体操作。作为示例,在本文工程中我们不进行任何具体的检查操作,只简单得给出初始检查成功的信息,返回RefactoringStatus.IN
7、FO以使重构操作继续执行。checkInitialConditions函数代码如下:清单 7public RefactoringStatus checkInitialConditions(IProgressMonitor pm)throws CoreException, OperationCanceledException return RefactoringStatus.createInfoStatus(Initial Condition is OK!); 接着完成checkFinalConditions函数,实现获得用户输入参数后的后续检查操作。在本文工程中,我们首先收集所有需要添加注释的
8、以test开头的方法,判断是否不存在这样的方法,如果不存在给出出错信息,返回RefactoringStatus.FATAL以结束重构操作;如果存在这样的方法,则给出后续检查成功的信息,返回RefactoringStatus.INFO。checkFinalConditions函数代码如下:清单 8public RefactoringStatus checkFinalConditions(IProgressMonitor pm)throws CoreException, OperationCanceledException collectChanges();if (fChangeManager.s
9、ize() = 0)return RefactoringStatus.createFatalErrorStatus(No testing methods found!);else return RefactoringStatus.createInfoStatus(Final condition is OK!); 最后,创建Change对象的createChange函数是整个重构操作中最核心的代码,它的实现将在下面章节中介绍。使用AST构造Change对象当我们找到了修改的位置时,我们有两个选择:1. 通过IScanner接口扫描代码,然后通过IBuffer接口直接修改代码2. 通过遍历和编辑A
10、ST树进行结构化的修改DeveloperWorks提供的文章扩展Eclipse的Java开发工具中,给出了使用IBuffer接口的例子。现在我们要讲述使用AST来遍历和修改Java源代码的方法。AST是abstract syntax tree的缩写。它是Eclipse中的Java开发环境(JDT)为我们提供的极为强大的源代码解析和编辑工具。在使用AST树提供的功能之前,我们首先要创建AST树。由于AST树的构建是一项费时的操作,JDT缺省情况下不将源代码解析为AST树。下面的代码演示了获得一个ICompilationUnit对应的AST树的过程。在JDT提供的API中,ICompilation
11、Unit接口用于表示一个可以被编译的源代码文件。在我们提供的例子程序中,我们通过下面的代码将整个文件解析成为了一颗AST树。清单 9ASTParser parser = ASTParser.newParser(AST.JLS3);parser.setSource(cu);ASTNode root = parser.createAST(null); AST树中的每个节点都是ASTNode类型,通过Visit模式,我们可以访问一个ASTNode包含的所有节点。下面的代码演示了访问一个AST节点并获得其中所有的MethodDeclaration节点的方法。清单 10private void getM
12、ethods(ASTNode cuu, final List methods) cuu.accept(new ASTVisitor() public boolean visit(MethodDeclaration node) methods.add(node);return false;); 在收集到了所有的MethodDeclaration节点之后,我们就可以通过向AST树中插入和删除节点或者修改已有的节点的方法来修改AST树了。下面的代码演示了使用AST工具为方法添加Test Annotation的功能。清单 11private boolean collectChanges(Compila
13、tionUnit root,MethodDeclaration method) if (method.getName().getFullyQualifiedName().startsWith(test) AST ast = method.getAST();if (needTimeout) NormalAnnotation na = ast.newNormalAnnotation();na.setTypeName(ast.newSimpleName(Test);MemberValuePair pair = ast.newMemberValuePair();pair.setName(ast.new
14、SimpleName(timeout);pair.setValue(ast.newNumberLiteral(500); na.values().add(pair);method.modifiers().add(0, na); else MarkerAnnotation na = ast.newMarkerAnnotation();na.setTypeName(ast.newSimpleName(Test);method.modifiers().add(0, na);return true;return false; 在Refactoring框架中,我们要求对AST树的修改并不立刻反映到源代码
15、中。相反,我们需要一个能记录整个修改过程的Change对象。Refactoring框架将利用这个Change对象来显示Priveiw窗口、进行Undo和Redo等操作。大致上,我们记录对一个AST树的修改从而生成Change对象的过程如以下代码所示。清单 12root.recordModifications();/在这里修改AST树TextEdit edits = root.rewrite(document, cu.getJavaProject().getOptions(true);TextFileChange change = new TextFileChange(, (IFile) cu.
16、getResource();change.setEdit(edits); 最后,由于Refactoring类的createChange方法仅返回一个Change对象,如果我们需要对多个源代码文件进行修改,我们可以利用CompositeChange类将多个Change对象封装成一个Change对象。这个过程可能类似如下代码所执行的流程清单 13public Change createChange(IProgressMonitor pm) throws CoreException,OperationCanceledException Change changes = new ChangefChan
17、geManager.size();System.arraycopy(fChangeManager.toArray(), 0, changes, 0,fChangeManager.size();CompositeChange change = new CompositeChange(Add Override Annotation, changes);return change; 扩展RefactoringWizard 框架Eclipse中的RefactoringWizard框架扩展了Eclipse的Wizard框架,关于Wizard框架的介绍可以在Eclipse的帮助系统中找到,这里我们仅从OO
18、设计和架构的角度探讨一下RefactoringWizard框架。我们从Wizard相关的几个类开始: 1. WizardPage类WizardPage是一个包含了多个界面元素(比如文本框Text,按钮Button)的一个界面组合部分。各个Page之间是独立的,是可以动态加载的。WizardPage类的职责有:组合SWT界面元素,构造出一个界面页。定义本身界面元素的操作行为。在RefactoringWizard框架中预设了两个通用的属性页:PreviewWizardPage和ErrorWizardPage。PreviewWizardPage类是用来预览重构后的修改,对比代码或其他资源的变化。Er
19、rorWizardPage类是用来处理条件检查及错误状态通知的。我们只需扩展RefactoringWizard框架就可以自动获取这两项强大的功能。2. Wizard类一个Wizard就是一个装载一系列WizardPage页的容器,Wizard类的职责有:装载一系列WizardPage,构造出一个复杂的界面。装载领域类来处理具体业务逻辑。(在RefactoringWizard框架中这个类就是Refactoring类)维护WizardPage页之间以及页与领域类之间的数据传递和状态共享。(在这里要补充一点,其实在具体RefactoringWizard框架的实现中有专门的类来分担这部分职责。)我们的
20、界面行为可以千变万化(通过组合不同的WizardPage),而负责处理业务逻辑的领域类也可以独立的变化,你可以随意扩展Wizard的界面功能(对扩展开放),而不用修改现有RefactoringWizard框架(对修改封闭),这正是OO设计的最基本原则OCP(Open-Close Principle)。3. WizardDialog类这个对话框类的主要职责是构造一个完整的GUI界面以及操作界面。它预设了一些按钮(Back,Next,Finish,Cancel)等界面元素,它负责装载Wizard类,操作时通过按钮Back、Next来在多个WizardPage之间切换。下面我们给出Refactori
21、ngWizard框架的架构图:图 5 Refactoring Wizard架构图 从图 5中我们可以看到,如果我们把每一个WizardPage页看作一项业务,那么Refactoring正是处理业务逻辑的控制中心,它封装了所有对业务逻辑的处理,当然它可以在将处理任务委任出去。但请注意,它并不负责实现业务流程,也就是说各业务(各个Page界面)之间的逻辑顺序关系不由它维护。RefactoringWizard框架充分考虑到了应用的可扩展性,它在SWT的MVC(模型视图控制)元架构模式的基础上,添加了一些新的架构元素。MVC模式促使业务逻辑与界面分离,界面与控制行为分离,而RefactoringWiz
22、ard框架增强了界面本身分离的特性,它将一个完整的界面分拆成多个页面,用户可以动态组合这些页面或添加新的页面来扩展界面行为。这种特性界面的动态组合,低耦合,高内聚,封装良好的接口让我们领略到了OO设计的精髓。下面我们通过以下几个步骤来扩展RefactoringWizard框架:扩展RefactoringWizardPage扩展RefactoringWizard启动RefactoringWizard第一步,扩展RefactoringWizardPage:首先我们新建一个类AnnotationRefactoringWizardPage,它需要继承UserInputWizardPage类(其父类是R
23、efactoringWizardPage,而RefactoringWizardPage最终实现了IDialogPage接口)。接下来就是实现IDialogPage接口的createControl()方法,在这个方法里实现你的界面行为,比如我们例子中的TimeOut文本框,代码清单如下:清单 14/* create composite to add UI elements*/public void createControl(Composite parent) / define UIComposite composite = new Composite(parent, SWT.NONE);Gri
24、dLayout lay = new GridLayout();lay.numColumns = 2;composite.setLayout(lay); btnCheck = new Button(composite, SWT.CHECK);btnCheck.setText(Add timeout parameter);GridData gdBtnCheck = new GridData();gdBtnCheck.horizontalSpan = 2;gdBtnCheck.horizontalAlignment = GridData.FILL;btnCheck.setLayoutData(gdB
25、tnCheck);labName = new Label(composite, SWT.WRAP);labName.setText(TimeOut:);GridData gdLabName = new GridData();gdLabName.horizontalAlignment = GridData.BEGINNING;gdLabName.grabExcessHorizontalSpace = true;labName.setLayoutData(gdLabName);txtTimeOut = new Text(composite, SWT.SINGLE | SWT.BORDER);Gri
26、dData gdTxtTimeOut = new GridData();gdTxtTimeOut.horizontalAlignment = GridData.END;gdLabName.grabExcessHorizontalSpace = true;txtTimeOut.setLayoutData(gdTxtTimeOut);txtTimeOut.setText(500);/ init statuslabName.setEnabled(false);txtTimeOut.setEnabled(false);/ add listenerdefineListener();/ 将composit
27、e纳入框架的控制setControl(composite);Dialog.applyDialogFont(composite);在这里我们要特别注意的一点是在定义完我们的界面元素后,需要将自定义的Composite纳入框架的控制,就是这行代码:setControl(composite);在我们处理完输入数据检查后进入下一页面之前,我们需要设置页面完成的状态,以及传递输入数据到领域类Refactoring。我们用以下代码设置好页面完成的状态后,下个页面ErrorWizardPage就会处理显示逻辑:清单 15private void notifyStatus(boolean valid, Str
28、ing message) /设置错误信息setErrorMessage(message);/设置页面完成状态setPageComplete(valid); 传递输入数据通过以下代码来处理:清单 16private void setRefactoring(boolean selection, String text) AnnotationRefactoring refactoring = (AnnotationRefactoring) getRefactoring();refactoring.setNeedTimeout(true);if(selection) refactoring.setTi
29、meout(Integer.valueOf(txtTimeOut.getText().intValue(); 其中getRefactoring()方法是继承自RefactoringWizardPage的方法,由于我们的RefactoringWizard类装载了RefactoringWizardPage和Refactoring类,这个方法是从RefactoringWizard类中获得的,这里面用到了Observer设计模式。至此,我们完成RefactoringWizardPage的扩展。第二步,扩展RefactoringWizard:首先我们新建一个类AnnotationRefactoringW
30、izard,它需要继承RefactoringWizard类,这个类中我们只需要加载定义好的AnnotationRefactoringWizardPage类和AnnotationRefactoring类,当然复杂的处理已经有RefactoringWizard框架处理好了。下面我们在构造函数中加载Refactoring类:清单 17public AnnotationRefactoringWizard(Refactoring refactoring) super(refactoring, WIZARD_BASED_USER_INTERFACE); 然后我们加载我们的AnnotationRefacto
31、ringWizardPage类,只需重载父类RefactoringWizard的addUserInputPages()方法就可以:清单 18protected void addUserInputPages() page = new AnnotationRefactoringWizardPage(refactor annotation);addPage(page); 第三步,启动RefactoringWizard。扩展好RefactoringWizard之后,就需要在用户点击菜单项或是按钮时弹出这个对话框。RefactoringWizard最好使用RefactoringWizardOpenOperation类来打开(当然也可
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 听觉口语师核心技能强化考核试卷含答案
- 2025-2026学年大树说课稿美术
- 聚酯增粘装置操作工安全规程评优考核试卷含答案
- 电气试验工岗位潜力考核试卷含答案
- 2025-2026学年大班七步诗说课稿
- 吉林省吉林市四校2025-2026学年八年级上学期期中测试物理试题(含答案)
- 2026年金属表面处理及热处理加工行业技术路线图报告及未来五至十年龙头崛起与格局重塑
- 2026年水上运输辅助活动行业年度综合研究报告及未来五至十年合规风险与监管应对
- 2026年抽纱刺绣工艺品制造行业市场调查研究报告及未来五至十年垂直整合与横向拓展
- 见证取样监理实施细则
- 江苏省南京市2026-2027年高三上9月月考语文试卷(含答案)
- 2025-2026学年辽宁省点石联考高二10月月考语文试题
- 2026秋季苏教版(新教材)小学科学六年级上册(全册)每课课时练习及答案(附目录p97)
- 2026新教材人教版九年级上册英语:各单元话题作文指导(写作模板+满分范文)
- 公共政策不确定性管理:框架、模型与实践
- 2026年中国广电山东网络有限公司招聘笔试参考题库附带答案详解
- 主播经纪协议模板
- 《储能用压缩空气泡沫灭火系统》
- 《DLT 2855-2024变电站无人机巡检系统》专题研究报告深度
- 贵州省公路占道作业安全技术指南(试行)
- 耳鼻喉嗓音训练
评论
0/150
提交评论