有没有简单的方法在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代码中进行高级搜索的方法。 我们欢迎任何不仅仅是简单的搜索/正则表达式搜索/查找用法功能。
答案 0 :(得分:1)
您可以使用Intellij IDEA Structural Search https://www.jetbrains.com/idea/help/structural-search-and-replace-examples.html
答案 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。