今日更新
技术新闻
精彩专题
IBM软件技术专区
微软开发专区
技术文档中心
编程语言
网络通信
网络安全
LINUX/UNIX
软件工程与管理
数据库开发
WEB开发
企业应用与开发
移动开发
资源中心
原创专栏
开放系统世界
人才与培训
技术天地论坛
厂商列表
社区推荐

· 女性身体内部人体受孕..
· 十部顶级的变态与情色..
· 感情放纵让我毁了两个..
· 当我撞见姐姐和男友在..
· 卖淫少女惨遭泄愤民工..
· 偷拍街上的走光mm绝对..
· 百度打击google的广告
· 港娱乐圈与黑社会揭秘
赛迪网>>技术应用>>上首页
关键字: Eclipse Java
来  源: IBM DW
扩展Eclipse的Java开发工具(四)
作者:Dan Kehn 发文时间:2004.05.24
接上一篇:扩展Eclipse的Java开发工具(三)

怎样分析 Java 代码以进行修改?

JDT 提供了几个工具来帮助您分析代码。本文有意选择了最简单的 IScanner 接口进行演示,它的作用域也最有限。这个接口属于 JDT 工具箱,可以通过 JDT 的 ToolFactory 类访问它。其 createScanner 方法返回一个扫描程序,该扫描程序会简化对一串 Java 代码作标记的工作。它不处理任何特别困难的操作,只是对所返回的标记进行简单的解析和分类。例如,它指出下一个标记是 public 关键字,其后的标记是一个标识符,再后面的标记是左圆括号,等等。随后,只有当您希望分析一小段代码(您明确理解想要在这段代码中得到什么)时,这个扫描程序才是合适的。您决不会使用扫描程序分析整个 Java 源代码;因为您会转而使用一些对编译器迷而言十分熟悉的工具:JDT 的抽象语法树(Abstract Syntax Tree,AST)框架。

与简单的扫描程序不同,AST 理解语言元素(它们不再只是“标记”)之间的关系。它可以识别象局部变量、实例变量、表达式以及 if 语句等六十多种不同的语言元素。它将帮助您进行涉及范围广泛的重构,或难以满足对标记进行一对一分类的模糊程度特别高的重构。要更清晰地了解何时使用扫描程序与何时使用 AST 之间的差别,请考虑清单 10 中的代码。

清单 10. 模糊的变量引用

public class Foo {
  int foo = 1;
  
  public int foo(int foo) {
      return foo + this.foo;
  }
  
  public int getFoo() {
    return foo;
  }
}


如果作为重构的一部分,您希望查找对实例变量 foo 的引用,那么就会明白一个单纯的解析会使区分本地引用和实例变量引用成为一个难题。AST 创建了完整的分析树,其中表示了 Java 源代码的每个元素并对这些元素进行了区分。在这个特例中,不同的类会考虑“foo”引用的上下文,将“foo”引用表示成 AST 的节点(如 FieldDeclaration、SimpleName 和 ThisExpression),因此您会很轻松地识别它们。

正如前面提到的,本文将只讨论我们所选择的简单例子。对于比较复杂的修改和分析示例,请参阅参考资料一节。现在,让我们回到我们前面跳过的用省略号表示的代码。这个代码将使用 IScanner 的实例以确定并替换源代码中确定成员可视性的关键字。我们将处理的可视性修饰符是 public、private、protected 和 final。通过采用“蛮力”方法,我们可以简化这个解决方案,即,采用两个步骤就可以完成。首先删除方法特征符中所有的可视性修饰符(或至少扫描查找它们,如果找到,就删除),然后插入所希望的修饰符。特别地:

如果在方法特征符中找到 public、private 或 protected,就删除它们。

插入所请求的可视性修饰符(对于包可视性的情况,不作任何操作,因为这是缺省操作;即没有任何修饰符)。

final 修饰符很简单。因为所希望的行为就是插入和除去这个修饰符,所以如果它存在,我们除去它;否则就插入它。清单 11 中的代码只显示了一个例子,它无条件地将成员的可视性从 pubilc 改成 private。在与本文相关的解决方案中,您将看到每个操作的公共代码都被移到了抽象超类中。它基本上与下面的代码相同,只不过稍作了整理以避免冗余。

清单 11. 扫描是否有 pubilc 关键字

ICompilationUnit cu = member.getCompilationUnit();

if (cu.isWorkingCopy()) {
  IBuffer buffer = cu.getBuffer();
  
  IScanner scanner =
    ToolFactory.createScanner(false, false, false, false);
  scanner.setSource(buffer.getCharacters());
  ISourceRange sr = member.getSourceRange();
  scanner.resetTo(
    sr.getOffset(),
    sr.getOffset() + sr.getLength() - 1);

  int token = scanner.getNextToken();
  while (token != ITerminalSymbols.TokenNameEOF
      && token != ITerminalSymbols.TokenNameLPAREN)
    token = scanner.getNextToken();

    if (token == ITerminalSymbols.TokenNamePUBLIC) {
      buffer.replace(
        scanner.getCurrentTokenStartPosition(),
        scanner.getCurrentTokenEndPosition(),
        scanner.getCurrentTokenStartPosition() + 1,
        "private");
      break;
    }
  }
  cu.reconcile();
}


注:ITerminalSymbols 定义了扫描程序可以返回的标记名称,它们对应于 Java 语法的标准标记。您可以进一步查询扫描程序以询问当前标记在缓冲区中开始和结束的具体位置,它出现在哪一行上,当然还有标记本身(特别是象 ITerminalSymbols.TokenNameStringLiteral 和 ITerminalSymbols.TokenNameIdentifier 这样的例子,它们不是保留的关键字)。

上述代码片段中,向 scanner.setSource 方法提供了编译单元的完整源代码,即 Java 源文件中的所有内容。正如前面提到的,扫描程序并不非常适合于大型分析,所以我们必须将它限制用于只有以目标方法的第一个字符开始,一直到调用 setSourceRange 方法作为结束的那部分源代码。IMember 接口继承了 ISourceReference,ISourceReference 是一个允许您查询包含编译单元内的源代码字符串和源代码位置的接口。这使我们不必确定目标方法在 Java 源代码内开始和结束的位置。原本可以用 AST 实现这一点,而 ISourceReference 接口使 AST 成了多余的工具。由于 Java 方法特征符易于解析,所以 IScanner 接口的解析能力和它很匹配。我们必须做的就是查找 public 关键字,它出现在方法声明的前一个字符之后,参数声明的左圆括号之前,用 private 关键字替换它。当然,在该解决方案中,这个接口将处理所有的可能情况,不管该方法最初是 public、private、protected 还是 package(缺省)。

下一步是什么?

本文设定的目标是向您提供一个对 Eclipse 的 Java 开发环境颇具价值的扩展,这样的扩展增强了这个开发环境的生产率。坦率地说,出于简洁性考虑,我多次跳过了一些细节。该解决方案本身就作了一些简化假设,象只允许在编辑器中对已打开的 Java 源代码进行修改。您可能希望在更完整的实现中取消这个限制。

虽然如此,但我还是希望您能感受到什么是可能的,并确信这样做不是特别困难。本文中我们讨论的是 The Java Developer's Guide to Eclipse 一书某一高级章节的部分内容。该书中有十一个比较浅显的章节讨论了插件开发的基础。象本文一样,大多数章节都包含了一个已文档化的工作解决方案,它可以强化您所学到的知识,大多数内容是以本文中您已看到的相同风格编写的(不过可能没有以这么快的节奏进行讨论!)。

重要:您可能需要向工作空间添加必要的插件,这样解决方案才能编译和运行。选择 Window > Preferences > Plug-in Development > Target Platform,然后选择 Not in Workspace。这将确保解决方案所依赖的基础插件在导入和重新编译过程中可用。

一旦导入完成,您可能需要切换至 Plug-in Development 透视图,在 com.ibm.lab.soln.jdt.excerpt 项目中选择 plugin.xml,然后选择 Update Classpath。这将修改由于 Eclipse 安装路径和解决方案的安装路径不同所引起的编译错误。

关于作者

Dan Kehn 是 IBM 位于美国北卡罗莱纳州 Research Triangle Park 的高级软件工程师。他对面向对象编程的兴趣要追溯到 1985 年,当时这种技术还不象现在这样被广为接受。他拥有广泛的软件开发经验,从事过开发工具(如 VisualAge for Smalltalk)、操作系统性能、内存分析和用户界面设计等方面的工作。Dan 作为面向对象开发项目的顾问走遍了美国,并且还在欧洲工作过四年。他最近的兴趣包括面向对象分析/设计、应用程序开发工具,以及使用 WebSphere Application Server 进行 Web 编程。2001 年 5 月,他加入了 Eclipse Jumpstart 团队,这个团队帮助 ISV 创建基于 Eclipse 平台的商业产品。他和 Jumpstart 团队的其他成员编写了 The Java Developer's Guide to Eclipse,本文中介绍的解决方案就摘自这本书。

(责任编辑:代君利)




赛迪网推出“IT博客”,花不到一分钟就完成注册
评论】 【推荐】 【 】 【打印】 【关闭

·Linux专区· ·黑客攻防·
· Linux下添加硬盘、分区、格式化任务详解
· FreeBSD服务器的安装与优化之优化篇
· 初学者入门:FreeBSD服务器的安装与优化
· 金企鹅杯两岸四地开源软件大赛圆满结束
· 如何提高Linux系统安全性的十大招数
· 构筑Linux防火墙之为个人用户设置防火墙
· 谁更安全?黑客眼中的防火墙与路由器
· 识破骗局 练就识别QQ活动真伪火眼金睛
· 应用安全大有可为:目的、挑战、总结
· 道高一尺魔高一丈:安全防御的动感魅力
· 警惕网络“内”院起火 积极谋求安内之路
· HHCTRL漏洞被黑客利用 疯狂传播木马
·中国信息化· ·成功案例·
· ERP普及化是饮鸩止渴 精细化才是应用之道
· 赛门铁克第八期《互联网安全威胁报告》解析
· 抢食“数字工商” 国产中间件杀出血路
· 从IBM等操作系统的发展看软件创新的启示
· 服务成就蓝色快车 品牌是怎样炼成的?
· 三大技术应用大会合为一体甲骨文上演三重奏
· 南阳教育城域网 拆掉学校间的“围墙”
· 金算盘助申意美步入信息化快车道
· 不为人知的索尼信息化 谁是幕后英雄?
· InforBus/Q在穗高速路联网收费系统中的应用
· J2EE构建最新金融理念和运作模式的网上银行
· 食品安全令人担心 信息化能否保驾护航
*姓  名: 更多资料 了解方案 认识厂商
*单位名称:
*联系电话:
*电子邮件:
    
◆ 相关文章   ◆ 站内热点推荐
· 扩展Eclipse的Java开发工具(三)
· 扩展Eclipse的Java开发工具(二)
· 扩展Eclipse的Java开发工具(一)
· 网管员论坛
· 开发者之家
· WLAN无限未来
· 我是如何掉进C#的……
· 中国“人件”非正式调查

   
合作网站: IBM dW中国网站 LinuxAID 软件工程专家网 中国系统分析员 UMLChina MATRIX Mobile2008 JavaResearch 华储网 UML软件工程组织 中国JAVA手机网 JAVA中文站 金山在线 海量科技