我需要查找在其 equals() 方法中使用 JPA ID 属性的 JPA 持久类。例如,以下类将触发 PMD 规则违规:
@Entity
public class Foo
{
@Id
private long id;
public boolean equals(Object o)
{
if (o.getClass().equals(Foo.class)) {
Foo other = (Foo) o;
return o.id == id;
}
return false;
}
}
我知道如何让这个查询的各个部分工作,但不知道如何把它放在一起。因此,例如,我知道如何找到 JPA 持久类(假设使用 JPA 注释):
//ClassOrInterfaceDeclaration/../Annotation/MarkerAnnotation/Name[@Image='Entity']
我知道如何找到使用 JPA ID 注释注释的字段声明:
//FieldDeclaration[../Annotation/MarkerAnnotation/Name[@Image='Id']]
同样,我可以在 equals() 方法中找到一个引用名为“id”的字段的表达式:
//MethodDeclaration[
./MethodDeclarator[@Image='equals'] and
./MethodDeclarator/FormalParameters[1]/FormalParameter/Type/ReferenceType/ClassOrInterfaceType[@Image='Object']
]
/Block//PrimaryExpression/PrimaryPrefix/Name[@Image='id']
我遇到的麻烦是使用表达式查找标有 @Id 注释的字段的名称,并在谓词中使用它来查找使用该字段的 equals() 方法中的行。
这是我对查询的最佳猜测,但它不返回任何节点:
//MethodDeclaration[
./MethodDeclarator[@Image='equals']
and
//MethodDeclarator[count(./FormalParameters)=1]
and
./MethodDeclarator/FormalParameters[1]/FormalParameter/Type/ReferenceType/ClassOrInterfaceType[@Image='Object']
]
/Block//PrimaryExpression/Name[
@Image=ancestor::ClassOrInterfaceDeclaration//FieldDeclaration[
../Annotation/MarkerAnnotation/Name/@Image='Id']/VariableDeclarator/VariableDeclaratorId/@Image
]
前 7 行返回所有名称为“equals”的 MethodDeclarations,并采用单个“Object”参数。
下一部分选择该方法内的任何 PrimaryExpressions,其 Name 等于使用“Id”注释注释的字段的名称。有什么帮助吗?