程式扎記: [ Groovy 常見問題 ] Groovy get current methods annotation

標籤

2015年2月24日 星期二

[ Groovy 常見問題 ] Groovy get current methods annotation

Source From Here 
Question 
I created a java interface for my annotation. I am now writing a class and I would like to print the annotation values so it shows in the log message. Is this possible? Here is my test case and let me know if I am doing this wrong: 
  1. @Retention(RetentionPolicy.RUNTIME)  
  2. public @interface TestCase {  
  3.     String someID()  
  4. }  
  5.   
  6. class Checkout{  
  7.     @TestCase(someID="12345")  
  8.     def "a dynamic method name"() {  
  9.         // My test steps.....  
  10.     }  
  11. }  
How-To 
Use StackTraceUtils.sanitize to get the current method and use reflection to iterate through the annotations: 
  1. import java.lang.annotation.Annotation  
  2. import java.lang.annotation.Retention  
  3. import java.lang.annotation.RetentionPolicy  
  4. import java.lang.reflect.Method  
  5. import org.codehaus.groovy.runtime.StackTraceUtils  
  6.   
  7. @Retention(RetentionPolicy.RUNTIME)  
  8. public @interface TestCase {  
  9.     String someID()  
  10. }  
  11.   
  12. class Checkout{  
  13.     @TestCase(someID="12345")  
  14.     def "a dynamic method name"() {  
  15.         printTestCaseId()  
  16.         // My test steps.....  
  17.     }  
  18.       
  19.     def printTestCaseId() {  
  20.         def stack = StackTraceUtils.sanitize(new Throwable()).stackTrace[1]  
  21.         def method = getClass().declaredMethods.find { it.name == stack.methodName }  
  22.         printf("method=${method}\n")  
  23.         def someID = method.annotations[0].someID()  
  24.         printf("someID=${someID}\n")  
  25.         assert someID == "12345"  
  26.       }  
  27. }  
  28.   
  29. def co = new Checkout()  
  30. co."${'a dynamic method name'}"()  
Execution Result: 
method=public java.lang.Object Checkout.a dynamic method name()
someID=12345

If you want to iterate all methods and corresponding annotations from a class, you can try below sample code: 
  1. import java.lang.annotation.Annotation  
  2. import java.lang.annotation.Retention  
  3. import java.lang.annotation.RetentionPolicy  
  4. import java.lang.reflect.Method  
  5.   
  6. @Foo('class')  
  7. class A{  
  8.     def name = "A"  
  9.           
  10.     @Foo('method')  
  11.     def test()  
  12.     {  
  13.         printf("testing")  
  14.     }  
  15. }  
  16.   
  17. A a = new A()  
  18. printf("%s\nClass %s\n", a.class.annotations[0], a.class.name)  
  19. a.class.declaredMethods.each{ m->  
  20.     printf("\tMethod:%s (%d)\n", m.name, m.annotations.size())  
  21.     m.getDeclaredAnnotations().each{ an->  
  22.         printf("\t\tAnnotation->%s\n", an)  
  23.     }  
  24.     if(m.isAnnotationPresent(NO.class)) {  
  25.         printf("\t\t%s\n", m.getAnnotation(NO.class))  
  26.     }  
  27. }  
Execution result: 
@Foo(value=class)
Class A
Method:setProperty (0)
Method:getProperty (0)
Method:getName (0)
Method:setName (0)
Method:super$1$hashCode (0)
Method:$getCallSiteArray (0)
Method:$getStaticMetaClass (0)
Method:getMetaClass (0)
Method:__$swapInit (0)
Method:class$ (0)
Method:invokeMethod (0)
Method:super$1$clone (0)
Method:super$1$wait (0)
Method:super$1$wait (0)
Method:super$1$wait (0)
Method:setMetaClass (0)
Method:super$1$notify (0)
Method:super$1$equals (0)
Method:$createCallSiteArray_1 (0)
Method:super$1$toString (0)
Method:super$1$getClass (0)
Method:super$1$notifyAll (0)
Method:$createCallSiteArray (0)
Method:super$1$finalize (0)
Method:test (1)
Annotation->@Foo(value=method)
Method:this$dist$invoke$1 (0)
Method:this$dist$set$1 (0)
Method:this$dist$get$1 (0)

Supplement 
Documentation - User Guide - Annotations with Groovy 
Java SE 6 技術手冊 - 第 17 章 Annotation

沒有留言:

張貼留言

網誌存檔

關於我自己

我的相片
Where there is a will, there is a way!