2013-10-08 109 views
0

我已經定義了一個註解:如何在編譯時驗證註釋?

public @interface AdminMapping { 
    public final static int USER = 100; 
    public final static int COMPANY = 10; 
    public final static int ADMIN = 0; 

    int adminLevel() default AdminMapping.USER; 
    String displayName(); 
    String category() default ""; 
    String hasPermission() default ""; 
    String parentCategory() default ""; 
} 

我想使它所以你不能有一個parentCategory除非你有一個類別....

@AdminMapping(category="Company", displayName="FOO", adminLevel=AdminMapping.USER) 
public static final String MONKEY = "chimp"; 


    @AdminMapping(parentCategory="Company", displayName="BAR", adminLevel=AdminMapping.USER) //NOT VALID Parent without Category 
public static final String HORSE = "zebra"; 

,而我在這如果我可以做到這一點,我也喜歡它,因此類別不等於parentCategory。

我知道如何使用ConstraintValidator來驗證MONKEY和HORSE,但我想驗證實際的AdminMapping條目。這可以在編譯時完成嗎?

任何幫助表示讚賞。

+0

我還沒有嘗試過,以確認你可以做你想做的一切,但我會建議看看寫自己的PMD規則來做檢查。 –

+0

@matthelliwell回答下面的例子中的一部分可能會幫助我很多,並導致接受:) – kasdega

回答

1

使用PMD。 PMD是一個工具,可以解析你的源代碼並讓你檢查它是否符合某些規則。它帶有大量的內置規則,但您可以編寫自己的規則,以便您可以編寫規則來檢查您的註釋是如何定義的。

請參閱this page瞭解如何編寫自己的規則。

例如,編寫一個規則可以很容易地檢查註釋是否同時定義了parentCategory和category。

首先聲明的自定義規則,在規則的XML文件:

<?xml version="1.0"?> 
<ruleset name="My custom rules" 
    xmlns="http://pmd.sourceforge.net/ruleset/2.0.0" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 http://pmd.sourceforge.net/ruleset_2_0_0.xsd"> 
<rule name="NoParent" 
     message="No parent category without category" 
     class="com.test.CategoryRule"> 
    <description> 
     No parent category without category 
    </description> 

</rule> 

然後定義一個Java類,將做實際的執行。

public class CategoryRule extends AbstractJavaRule { 
public Object visit(ASTMemberValuePairs node, Object data) { 

    boolean hasCategory = false; 
    boolean hasParentCategory = false; 

    for (int i = 0; i < node.jjtGetNumChildren(); ++i) { 
     if (node.jjtGetChild(i).getImage().equals("category")) { 
      hasCategory = true; 
     } else if (node.jjtGetChild(i).getImage().equals("parentCategory")) { 
      hasParentCategory = true; 
     } 
    } 

    if (hasCategory && !hasParentCategory) { 
     addViolation(data, node); 
    } 

    return data; 
} 

}

顯然,你需要編寫的代碼更健壯一點在現實中,檢查註釋類型,但希望是足以讓你開始。

1

你需要去註釋參考,並檢查其屬性

AdminMapping mapping = ...; // depends on what your annotation is annotating 

if (mapping.category().isEmpty()) { 
    if (!mapping.parentCategory().isEmpty()) { 
     // we got a beef 
    } 
} 
+0

這可以在編譯時完成嗎? – kasdega

+0

@kasdega不用編寫自己的編譯器。你也許可以爲IDE實現一些代碼檢查器插件。 –