2

equals()メソッドでJPAID属性を使用する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']

JPAIDアノテーションが付けられたフィールドの宣言を見つける方法を知っています。

//FieldDeclaration[../Annotation/MarkerAnnotation/Name[@Image='Id']]

同様に、'id'という名前のフィールドを参照するequals()メソッドで式を見つけることができます。

//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」引数を取ります。

次のセクションでは、そのメソッド内で、「Id」アノテーションが付けられたフィールドの名前とNameが等しいPrimaryExpressionsを選択します。何か助けはありますか?

4

1 に答える 1

1

OK、私はそれを理解しました...これが私が思いついた解決策です:

//MethodDeclaration[
  MethodDeclarator[
    count(FormalParameters/FormalParameter)=1 and
    @Image='equals' and
    FormalParameters/FormalParameter[1]/Type/ReferenceType/ClassOrInterfaceType[@Image='Object']
  ]
]
/Block//PrimaryExpression[
  PrimaryPrefix/@Image=
    ancestor::ClassOrInterfaceDeclaration//FieldDeclaration[
      ../Annotation/MarkerAnnotation/Name/@Image='Id'
    ] /VariableDeclarator/VariableDeclaratorId/@Image
  or
  PrimarySuffix/@Image=
    ancestor::ClassOrInterfaceDeclaration//FieldDeclaration[
      ../Annotation/MarkerAnnotation/Name/@Image='Id'
    ] /VariableDeclarator/VariableDeclaratorId/@Image
]

うまくいくようです。

于 2013-02-05T15:42:53.327 に答える