KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > codehaus > aspectwerkz > annotation > Java14AnnotationInvocationHander


1 /**************************************************************************************
2  * Copyright (c) Jonas Bon?r, Alexandre Vasseur. All rights reserved. *
3  * http://aspectwerkz.codehaus.org *
4  * ---------------------------------------------------------------------------------- *
5  * The software in this package is published under the terms of the LGPL license *
6  * a copy of which has been included with this distribution in the license.txt file. *
7  **************************************************************************************/

8 package org.codehaus.aspectwerkz.annotation;
9
10 import org.codehaus.aspectwerkz.annotation.expression.AnnotationVisitor;
11 import org.codehaus.aspectwerkz.util.Strings;
12
13 import java.lang.reflect.InvocationHandler JavaDoc;
14 import java.lang.reflect.Method JavaDoc;
15 import java.io.Serializable JavaDoc;
16 import java.util.Map JavaDoc;
17 import java.util.HashMap JavaDoc;
18 import java.util.Iterator JavaDoc;
19
20 /**
21  * A Java 1.3 / 1.4 strongly typed Annotation handler.
22  * This proxy handler gets serialized alongside the annotationInfo within the AnnotationC compiled class.
23  *
24  * @author <a HREF="mailto:alex@gnilux.com">Alexandre Vasseur</a>
25  */

26 public class Java14AnnotationInvocationHander implements InvocationHandler JavaDoc, Serializable JavaDoc {
27
28     //TODO calculate
29
private static final long serialVersionUID = 1L;
30
31     private String JavaDoc m_annotationClassName;
32     private String JavaDoc m_rawAnnotationName;//nickname f.e. @Before in 1.4
33
private String JavaDoc m_rawAnnotationValue;
34     private final boolean m_isUntyped;
35     private final Map JavaDoc m_elements = new HashMap JavaDoc();
36
37     /**
38      * Constructor that will trigger the parsing if required
39      *
40      * @param annotationInterface
41      * @param rawAnnotationName
42      * @param rawAnnotationValue
43      */

44     public Java14AnnotationInvocationHander(Class JavaDoc annotationInterface, String JavaDoc rawAnnotationName,
45                                             String JavaDoc rawAnnotationValue) {
46         m_annotationClassName = annotationInterface.getName().replace('/', '.');
47         m_rawAnnotationName = rawAnnotationName;
48         m_rawAnnotationValue = rawAnnotationValue;
49
50         // untyped
51
if (annotationInterface.getName().equals(UntypedAnnotation.class.getName())) {
52             m_isUntyped = true;
53         } else {
54             m_isUntyped = false;
55         }
56
57         // for @AfterReturning etc, we allow anonymous style but are using typed annotation
58
// hence the @Around pc is a non supported syntax (should be @Around "pc")
59
// but for compatibility purpose we fake it here.
60
if ((m_annotationClassName.equals("org.codehaus.aspectwerkz.annotation.AfterReturning")
61             || m_annotationClassName.equals("org.codehaus.aspectwerkz.annotation.AfterThrowing")
62             || m_annotationClassName.startsWith("org.codehaus.aspectwerkz.annotation.")
63             || isSingleStringValued(annotationInterface))
64                && !m_isUntyped) {//annotationClassName.equals("org.codehaus.aspectwerkz.annotation.UntypedAnnotation")) {
65
String JavaDoc trimed = m_rawAnnotationValue.trim();
66             if (!isSingleStringValued(annotationInterface) &&
67                 (trimed.startsWith("type")
68                 || trimed.startsWith("pointcut")
69                 || trimed.startsWith("deploymentModel"))) {
70                 ;// not using untyped syntax
71
} else {
72                 if (m_rawAnnotationValue.startsWith("\"") && m_rawAnnotationValue.endsWith("\"")) {
73                     ;
74                 } else {
75                     m_rawAnnotationValue = "\"" + Strings.replaceSubString(m_rawAnnotationValue, "\"", "\\\"") + "\"";
76                 }
77             }
78         } else if (m_isUntyped) {
79             if (m_rawAnnotationValue.startsWith("\"") && m_rawAnnotationValue.endsWith("\"")) {
80                 if (m_rawAnnotationValue.length()>2) {
81                     m_rawAnnotationValue = m_rawAnnotationValue.substring(1, m_rawAnnotationValue.length()-1);
82                 }
83             }
84         }
85
86         // parse the raw representation for typed annotation
87
if (!m_isUntyped) {
88             StringBuffer JavaDoc representation = new StringBuffer JavaDoc("@");
89             representation.append(m_annotationClassName).append('(');
90             if (m_rawAnnotationValue != null) {
91                 // @Aspect perJVM is allowed, while should be @Aspect "perJVM"
92
// for now patch it here...
93
// FIXME
94
if (m_annotationClassName.equals("org.codehaus.aspectwerkz.annotation.Aspect")) {
95                     if (m_rawAnnotationValue.indexOf("name") < 0) {
96                         representation.append(m_rawAnnotationValue);
97                     }
98                 } else {
99                     representation.append(m_rawAnnotationValue);
100                 }
101             }
102             representation.append(')');
103             //TODO support for LazyClass
104
AnnotationVisitor.parse(m_elements, representation.toString(), annotationInterface);
105         }
106     }
107
108     private static boolean isSingleStringValued(Class JavaDoc annotationInterface) {
109         if (annotationInterface.getDeclaredMethods().length == 1) {
110             Method JavaDoc m = annotationInterface.getDeclaredMethods()[0];
111             return (m.getName().equals("value") && m.getReturnType().equals(String JavaDoc.class));
112         }
113         return false;
114     }
115
116     /**
117      * Raw constructor that assumes an already analysed annotation instance
118      * Used for nested annotation
119      *
120      * @param annotationInterface
121      * @param elements
122      */

123     public Java14AnnotationInvocationHander(Class JavaDoc annotationInterface, Map JavaDoc elements) {
124         m_annotationClassName = annotationInterface.getName().replace('/', '.');
125         m_rawAnnotationName = m_annotationClassName;
126         m_isUntyped = false;
127         m_rawAnnotationValue = null;
128
129         m_elements.putAll(elements);
130     }
131
132     public Object JavaDoc invoke(Object JavaDoc proxy, Method JavaDoc method, Object JavaDoc[] args) throws Throwable JavaDoc {
133         String JavaDoc methodName = method.getName();
134         Object JavaDoc returned = null;
135         if ("toString".equals(methodName)) {
136             StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
137             sb.append('@').append(m_rawAnnotationName);
138             sb.append("(");
139             String JavaDoc sep = "";
140             for (Iterator JavaDoc iterator = m_elements.keySet().iterator(); iterator.hasNext();) {
141                 String JavaDoc elementName = (String JavaDoc) iterator.next();
142                 AnnotationElement element = (AnnotationElement) m_elements.get(elementName);
143                 sb.append(sep).append(element.name + "=" + element.toString());
144                 sep = ", ";
145             }
146             sb.append(")");
147             returned = sb.toString();
148         } else if ("annotationType".equals(methodName)) {
149             return Class.forName(m_annotationClassName, false, proxy.getClass().getClassLoader());
150         } else if (m_isUntyped) {
151             if ("value".equals(methodName)) {
152                 returned = m_rawAnnotationValue;
153             } else if ("name".equals(methodName)) {
154                 returned = m_rawAnnotationName;
155             } else if ("annotationType".equals(methodName)) {
156                 returned = Class.forName(m_annotationClassName, false, proxy.getClass().getClassLoader());
157             } else {
158                 throw new RuntimeException JavaDoc(
159                         "No such element on Annotation @" + m_annotationClassName + " : " + methodName
160                 );
161             }
162         } else if (m_elements.containsKey(methodName)) {
163             AnnotationElement element = (AnnotationElement) m_elements.get(methodName);
164             Object JavaDoc valueHolder = element.resolveValueHolderFrom(proxy.getClass().getClassLoader());
165             returned = valueHolder;
166         } else {
167             returned = null;
168         }
169
170         //handle default value for primitive types
171
if (returned == null && method.getReturnType().isPrimitive()) {
172             Class JavaDoc returnedTyped = method.getReturnType();
173             if (boolean.class.equals(returnedTyped)) {
174                 return Boolean.FALSE;
175             } else {
176                 short s0 = 0;
177                 return new Short JavaDoc(s0);
178             }
179         } else {
180             return returned;
181         }
182     }
183
184 // private void readObject(final ObjectInputStream stream) throws Exception {
185
// ObjectInputStream.GetField fields = stream.readFields();
186
// m_value = (String) fields.get("m_value", null);
187
// m_name = (String) fields.get("m_name", null);
188
// }
189

190 }
191
192
Popular Tags