2017-01-19 14 views
4

getMethods()の方法でITypeのすべてのメソッドにアクセスできます。そのようなIMethodがアクセサーかミューテータ(ゲッター/セッター)かどうかを判断する効率的な方法はありますか? IMethodの名前がprefix ∈ {"get", "set", "is"}とスキームprefix + NameOfAttributeと一致するかどうかのチェックITypeのすべてのIMメソッドのアクセサーとミューテータ(ゲッター/セッター)の特定

は明白なものを検出するために私を助けるだろうが、アクセサまたはミューテータ(ゲッター/セッター)がそのように命名されていない場合、それは動作しません。

良い方法がありますか?

EDIT:私は、ITypeの属性を直接取得/設定するゲッター/セッターメソッドを特定したいだけで、何もしません。

EDIT2:専門用語を使用します:アクセサ&ミューテータ

EDIT3:ここでは私のソリューションは、すべての答えを読んだ後である:

private boolean isAccessor(IMethod method) throws JavaModelException { 
     if (isAccessMethod("get", method) || isAccessMethod("is", method)) { // if name fits 
      return method.getNumberOfParameters() == 0 && !Signature.SIG_VOID.equals(method.getReturnType()); 
     } 
     return false; 
    } 

    private boolean isMutator(IMethod method) throws JavaModelException { 
     if (isAccessMethod("set", method)) { // if name fits 
      return method.getNumberOfParameters() == 1 && Signature.SIG_VOID.equals(method.getReturnType()); 
     } 
     return false; 
    } 

    private boolean isAccessMethod(String prefix, IMethod method) throws JavaModelException { 
     IType type = method.getDeclaringType(); 
     for (IField field : type.getFields()) { // for ever field of IType: 
      if (method.getElementName().equalsIgnoreCase(prefix + field.getElementName())) { 
       return true; // is access method if name scheme fits for one field 
      } 
     } 
     return false; // is not an access method if no field fits 
    } 

重要:このソリューションは、私の要件に適合いくつかの重要なケースを無視しています(accepted answer参照)を参照してください。これはまだメソッドの機能をチェックしませんが、かなりうまく機能します。私が提案したスキームのメソッド名をチェックします。しかし、パラメータの数と戻り値の型がvoidかどうかチェックします。誰かがこれを改善したい場合、ゲッターの戻り値/パラメータータイプがメソッド名と一致したフィールドのタイプと一致するかどうかをチェックすることもできます。

答えて

2

JDTコアでゲッタとセッタを識別するためのサポートはないと思います。

JDTには、フィールド名に基づいてゲッター/セッター名の生成を提供する公開APIしかありません。例えば。 NamingConventionsuggestGetterName()メソッドを見てください。

GetterSetterUtilのような他の内部クラスも、あなたが望む方法を提供しません。

最後に、自分でプロパティアクセサ検出器を作成します。たぶん、私がCollectionに適用できるフィルタとして。 IMethodの名前プレフィックス∈{「GET」、「セット」}を用いてスキームプレフィックス+ NameOfAttributeと一致するかどうかの確認

またisブールプロパティの場合に接頭辞とチェックメソッドのパラメータリストGettersは通常、パラメータを取るのではなく、通常は1つのパラメータを取ります。私は通常、JavaBeans specificationもインデックス付きのプロパティを許可していると言いました。例えば。

void setter(int index, PropertyType value); // indexed setter 
PropertyType getter(int index); // indexed getter 
void setter(PropertyType values[]); // array setter 
PropertyType[] getter(); // array getter 

EDIT

私は私のポストへのご提案に基づいて、自分自身のソリューションを追加しました。

解決策があなたの要件に合っている可能性があります。プロパティは直接のバッキングフィールドを持たないかもしれないことに留意してください。プロパティの概念はもう少し抽象的です。つまり、visibleという名前のプロパティとgetter isVisible()という名前のクラスがある場合、クラスにはフィールドprivate boolean visibleがない可能性があります。

rootPaneからJComponentのプロパティを確認する必要があります。 Introspectorが返すので、それは間違いなく不動産です。

BeanInfo jcomponentBeanInfo = Introspector.getBeanInfo(JComponent.class); 

PropertyDescriptor[] propertyDescriptors = jcomponentBeanInfo.getPropertyDescriptors(); 
for (int i = 0; i < propertyDescriptors.length; i++) { 
    PropertyDescriptor propertyDescriptor = propertyDescriptors[i]; 
    if("rootPane".equals(propertyDescriptor.getName())){ 
    System.out.println("Found property rootPane"); 
    break; 
    } 
} 

Found property rootPane 

を出力します。しかし、あなたが実装を見てみるならば、それは直接バッキング・フィールドを使用しないでください。

public JRootPane getRootPane() { 
    return SwingUtilities.getRootPane(this); 
} 

SwingUtilities.getRootPane

public static JRootPane getRootPane(Component c) { 
    if (c instanceof RootPaneContainer) { 
     return ((RootPaneContainer)c).getRootPane(); 
    } 
    for(; c != null; c = c.getParent()) { 
     if (c instanceof JRootPane) { 
      return (JRootPane)c; 
     } 
    } 
    return null; 
} 

私はこれをより明確にしたいです。

+0

接頭辞についてのヒントのおかげで、私はそれを忘れてしまったでしょう!また、パラメータ数は良い考えです。 – ConveniencePatterns

+0

あなたの提案に基づいて自分の投稿を自分の投稿に追加しました。 – ConveniencePatterns

+1

@ConveniencePatternsただ私の答えを –

1

私のアプローチは、次のようになります。あなたは、各フィールドのIType、その後getElementName()getFields()を使用することができます

for (IMethod m : iType.getMethods()) { 
    if (m.getElementName().substring(0,3).equals("get")) { 
     //do something 
    } else if (m.getElementName().substring(0,3).equals("set")) { 
     //do something else 
    } 
} 

+1

これは私の質問で私が提案したものにかなり似ています。問題は、メソッドがゲッターではなく、 'getXYZ()'という名前である場合、メソッドがゲッターとして誤って宣言されるということです。 – ConveniencePatterns

+0

'getFields()'を呼び出すことで、宣言されたフィールドの配列を取得できます。 次に、各ループに対して...を使用します。for(フィールドフィールド:iType.getFields()) '。 –

+0

ええ、これはまだメソッドの名前だけをチェックします。これは良い解決策になりますが、JDT APIを使ってメソッドの機能をチェックする方法があるかもしれません。 – ConveniencePatterns

関連する問題