高级搜索java代码

时间:2015-08-12 15:52:24

标签: java refactoring

有没有简单的方法在Java代码中获得高级搜索?我将我们的应用程序从Glassfish 2迁移到Glassfish 4.很少有库改变了他们处理输入的方式,我想找到这种特定情况的发生位置。

例如: JPA 1.2

MyEntity some = entityManager.find(MyEntity.class, 1234);
some.setIdMyEntity(null);
entityManager.persist(some);

与上面类似的代码工作方式是使用新的自动生成id持久化新实体(如果适当的注释在实体中)。

JPA 2.2 相同的代码将产生错误

The attribute [idMyEntity] of class [my.package.MyEntity] is mapped to a primary key column in the database. Updates are not allowed.

我理解这种变化背后的原因,我想修复我的应用程序并找到需要尽可能精确修复的地方。

要找到这些,我使用正则表达式\.setId[a-zA-Z]+\(null\);但是有数百甚至数千个匹配,90%是误报。这就是为什么我会搜索可以做类似事情的引擎:

Look for invocation of setter (which is related to field annotated as @Id) 
with argument null on object which is instance of class annotated as @Entity

正如我所说,这只是一个例子,所以基本上我正在寻找的是在Java代码中进行高级搜索的方法。 我们欢迎任何不仅仅是简单的搜索/正则表达式搜索/查找用法功能。

3 个答案:

答案 0 :(得分:1)

答案 1 :(得分:0)

容易吗?您可以考虑我们的Source Code Search Engine (SCSE)

这使您可以使用目标语言(在本例中为Java)的语法编写查询,这有助于减少误报。您可以编写如下查询:

 '.' I=setID* '(' ... 'null' ... ')' ';'

只匹配该形状的代码;特别是,它会忽略注释/ Javadoc和意外看起来像这样的字符串。因此,一些有趣的误报将会消失。这很容易在几分钟内完成并执行。

不那么容易:关于做查询的困难部分"对"是你想知道代码的语义属性,没有纯语法驱动的工具(例如,grap,SCSE)可以做到。

对于后者,您需要一个解析和命名解析Java的工具,并使这些属性可用于匹配的检查。

为了达到这个效果,你可以使用我们的DMS Software Reengineering Toolkit及其完整的Java前端。 DMS 允许您编写与确切语法匹配的模式(此部分没有误报错误)并参考其他语义属性 作为额外的匹配条件(参见"如果"在下面)。

您必须编写一些自定义代码来检查具体内容 语义属性,但你可以写一个DMS模式匹配:

     pattern null_setter(p: access_path): statement =
          " \p ( null ) ; "
     if is_setter_annotated(p,"Id") /\ is_parameter_annotated(p,"Entity");

" is_setter_annotated"和" is_parameter_annotated"是使用与p匹配的语法树的custome函数,在Java前端提供的符号表中查找它,并检查这些属性。 如果你的setter可能需要多个参数,你可能需要几个模式,其中一个参数是有趣的null。

" is_setter_annotated"检查可能有点难以编写,因为它必须检查p的主体的可能非常重要的代码,以找到已经适当注释的字段的赋值。人们可以通过编写其他模式(可能是几个)来检查各种分配,如下所示:

    pattern is_annotated_field_assignment(i: identifier, e:expression): statement
       " \i = \e ; "
    if is_annotated(i);

如果你很懒,你可以以假阳性为代价跳过后者,因为函数调用不是setter的方法,你的选择。

如果只有"(某些)数百......可能的误报,使用DMS并不值得付出努力;听起来很丑陋,你可以穿过你的眼睛,只是在你的正则表达式结果中跋涉。如果它是数千,它可能值得麻烦。你可以编写一个机械程序转换(DMS支持这个),它可以找到并修补破碎的位置,如果修复是常规的。

答案 2 :(得分:0)

我不确定你会得到多少误报,但我怀疑你最好运行搜索/替换正则表达式并浏览整个更改列表,看看是否真的需要更改。我相信您将能够通过包等快速撤消更改。 我总是觉得这种方法比盲目搜索更快,然后确定这是否是正确的代码,然后改变它。

或者,您可以使用Eclipse JDT来修复代码,但我不建议您这样做。即使您习惯使用JDT API,自动化代码转换也不会像听起来那么容易,我怀疑您不知道这些APIS。