Source Code Cross Referenced for Java5AnnotationInvocationHandler.java in  » Aspect-oriented » aspectwerkz-2.0 » org » codehaus » aspectwerkz » annotation » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Aspect oriented » aspectwerkz 2.0 » org.codehaus.aspectwerkz.annotation 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /**************************************************************************************
002:         * Copyright (c) Jonas Bonér, Alexandre Vasseur. All rights reserved.                 *
003:         * http://aspectwerkz.codehaus.org                                                    *
004:         * ---------------------------------------------------------------------------------- *
005:         * The software in this package is published under the terms of the LGPL license      *
006:         * a copy of which has been included with this distribution in the license.txt file.  *
007:         **************************************************************************************/package org.codehaus.aspectwerkz.annotation;
008:
009:        import org.codehaus.aspectwerkz.reflect.MethodInfo;
010:        import org.codehaus.aspectwerkz.reflect.ClassInfo;
011:        import org.codehaus.aspectwerkz.reflect.impl.asm.AsmClassInfo;
012:        import org.codehaus.aspectwerkz.exception.WrappedRuntimeException;
013:        import org.objectweb.asm.attrs.*;
014:        import org.objectweb.asm.attrs.Annotation;
015:        import org.objectweb.asm.Type;
016:
017:        import java.lang.reflect.InvocationHandler;
018:        import java.lang.reflect.Method;
019:        import java.lang.reflect.Proxy;
020:        import java.lang.reflect.Field;
021:        import java.lang.reflect.Array;
022:        import java.util.List;
023:        import java.util.Collection;
024:        import java.util.ArrayList;
025:        import java.util.Iterator;
026:        import java.util.Map;
027:        import java.util.HashMap;
028:        import java.util.Arrays;
029:        import java.io.Serializable;
030:
031:        /**
032:         * Dynamic proxy handler for ASM Annotations we extract
033:         * The handler resolve the LazyClass to a concrete Class so that the proxy creation does not trigger
034:         * any class loading.
035:         * <p/>
036:         *
037:         * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
038:         */
039:        public class Java5AnnotationInvocationHandler implements 
040:                InvocationHandler {
041:
042:            /**
043:             * The annotation class name
044:             */
045:            private final String m_annotationClassName;
046:
047:            /**
048:             * A list of AnnotationElement containing the annotation instance element values
049:             * (including the defaulted value)
050:             */
051:            private final List m_annotationElements;
052:
053:            /**
054:             * private ctor - see getAnnotationProxy()
055:             *
056:             * @param annotationClassName
057:             * @param annotationElements
058:             */
059:            private Java5AnnotationInvocationHandler(
060:                    String annotationClassName, Collection annotationElements) {
061:                m_annotationClassName = annotationClassName;
062:                m_annotationElements = new ArrayList(annotationElements.size());
063:                for (Iterator iterator = annotationElements.iterator(); iterator
064:                        .hasNext();) {
065:                    m_annotationElements.add(iterator.next());
066:                }
067:            }
068:
069:            /**
070:             * Dynamic proxy based implementation
071:             * toString(), annotationType() and value() have a specific behavior
072:             *
073:             * @param proxy
074:             * @param method
075:             * @param args
076:             * @return
077:             * @throws Throwable
078:             */
079:            public Object invoke(Object proxy, Method method, Object[] args)
080:                    throws Throwable {
081:                String name = method.getName();
082:                if ("toString".equals(name)) {
083:                    StringBuffer sb = new StringBuffer();
084:                    sb.append('@').append(m_annotationClassName);
085:                    sb.append("(");
086:                    String sep = "";
087:                    for (Iterator iterator = m_annotationElements.iterator(); iterator
088:                            .hasNext();) {
089:                        AnnotationElement annotationElement = (AnnotationElement) iterator
090:                                .next();
091:                        sb.append(sep).append(
092:                                annotationElement.name + "="
093:                                        + annotationElement.toString());
094:                        sep = ", ";
095:                    }
096:                    sb.append(")");
097:                    return sb.toString();
098:                } else if ("annotationType".equals(name)) {
099:                    // funny, may explain why 1.5 Annotation intf has annotationType + getClass
100:                    // since a dynamic proxy handler cannot hijack getClass() ..
101:                    return Class.forName(m_annotationClassName, false, proxy
102:                            .getClass().getClassLoader());
103:                } else if ("value".equals(name)) {
104:                    if (m_annotationElements.isEmpty()) {
105:                        return null;
106:                    } else {
107:                        //FIXME !!value can be there with other elements !
108:                        // we could check that we don't have more than one element
109:                        return ((AnnotationElement) m_annotationElements.get(0))
110:                                .resolveValueHolderFrom(proxy.getClass()
111:                                        .getClassLoader());
112:                    }
113:                } else {
114:                    for (Iterator iterator = m_annotationElements.iterator(); iterator
115:                            .hasNext();) {
116:                        AnnotationElement annotationElement = (AnnotationElement) iterator
117:                                .next();
118:                        if (name.equals(annotationElement.name)) {
119:                            return annotationElement
120:                                    .resolveValueHolderFrom(proxy.getClass()
121:                                            .getClassLoader());
122:                        }
123:                    }
124:                    // element not found for such a name
125:                    throw new RuntimeException(
126:                            "No such element on Annotation @"
127:                                    + m_annotationClassName + " : " + name);
128:                }
129:            }
130:
131:            /**
132:             * Build and return a dynamic proxy representing the given ASM Annotation.
133:             * The proxy implements the AspectWerkz Annotation interface, as well as the user type Annotation.
134:             * Each elements of the annotation is proxied if needed or agressively created unless Class types to not trigger
135:             * any nested loading.
136:             *
137:             * Note: JSR-175 does not support Annotation value of N-dimensional array. At most 1 dimension is supported and
138:             * only for a subset of Java types.
139:             *
140:             * @param annotation
141:             * @param loader the classloader of the annotatED component (can be different from the one of the annotation class)
142:             * @return
143:             */
144:            public static org.codehaus.aspectwerkz.annotation.Annotation getAnnotationProxy(
145:                    org.objectweb.asm.attrs.Annotation annotation,
146:                    ClassLoader loader) {
147:                String annotationClassName = Type.getType(annotation.type)
148:                        .getClassName();
149:
150:                // get the ClassInfo for the annoation class to populate the assigned element values
151:                // with lazy value holders from the setted value or the default value if defaulted element
152:                // has been used in the annotation
153:                ClassInfo annotationClassInfo = AsmClassInfo.getClassInfo(
154:                        annotationClassName, loader);
155:                Map annotationElementValueHoldersByName = new HashMap();
156:
157:                // populate with the default values (might be then overriden by setted values)
158:                MethodInfo[] annotationMethods = annotationClassInfo
159:                        .getMethods();
160:                for (int i = 0; i < annotationMethods.length; i++) {
161:                    MethodInfo annotationMethod = annotationMethods[i];
162:                    for (Iterator iterator = annotationMethod.getAnnotations()
163:                            .iterator(); iterator.hasNext();) {
164:                        AnnotationInfo annotationInfo = (AnnotationInfo) iterator
165:                                .next();
166:                        // handles AnnotationDefault attribute that we have wrapped. See AnnotationDefault.
167:                        if (annotationInfo.getName().equals(
168:                                AnnotationDefault.NAME)) {
169:                            Object value = ((AnnotationDefault) annotationInfo
170:                                    .getAnnotation()).value();
171:                            Object valueHolder = getAnnotationValueHolder(
172:                                    value, loader);
173:                            annotationElementValueHoldersByName.put(
174:                                    annotationMethod.getName(),
175:                                    new AnnotationElement(annotationMethod
176:                                            .getName(), valueHolder));
177:                        }
178:                    }
179:                }
180:
181:                // override and populate with the setted values
182:                List settedElementValues = annotation.elementValues;
183:                for (int i = 0; i < settedElementValues.size(); i++) {
184:                    Object[] element = (Object[]) settedElementValues.get(i);
185:                    String name = (String) element[0];
186:                    Object valueHolder = getAnnotationValueHolder(element[1],
187:                            loader);
188:                    annotationElementValueHoldersByName.put(name,
189:                            new AnnotationElement(name, valueHolder));
190:                }
191:
192:                // create a dynamic proxy to embody the annotation instance
193:                try {
194:                    Class typeClass = Class.forName(annotationClassName, false,
195:                            loader);
196:                    Object proxy = Proxy
197:                            .newProxyInstance(
198:                                    loader,
199:                                    new Class[] {
200:                                            org.codehaus.aspectwerkz.annotation.Annotation.class,
201:                                            typeClass },
202:                                    new Java5AnnotationInvocationHandler(
203:                                            annotationClassName,
204:                                            annotationElementValueHoldersByName
205:                                                    .values()));
206:                    return (org.codehaus.aspectwerkz.annotation.Annotation) proxy;
207:                } catch (ClassNotFoundException e) {
208:                    throw new WrappedRuntimeException(e);
209:                }
210:            }
211:
212:            /**
213:             * Turn an ASM Annotation value into a concrete Java value holder, unless the value is of type
214:             * Class, in which case we wrap it behind a LazyClass() object so that actual loading of the class
215:             * will be done lazily
216:             *
217:             * @param value
218:             * @param loader
219:             * @return
220:             */
221:            private static Object getAnnotationValueHolder(Object value,
222:                    ClassLoader loader) {
223:                if (value instanceof  Annotation.EnumConstValue) {
224:                    Annotation.EnumConstValue enumAsmValue = (Annotation.EnumConstValue) value;
225:                    try {
226:                        Class enumClass = Class.forName(Type.getType(
227:                                enumAsmValue.typeName).getClassName(), false,
228:                                loader);
229:                        Field enumConstValue = enumClass
230:                                .getField(enumAsmValue.constName);
231:                        return enumConstValue.get(null);
232:                    } catch (Exception e) {
233:                        throw new WrappedRuntimeException(e);
234:                    }
235:                } else if (value instanceof  Type) {
236:                    // TODO may require additional filtering ?
237:                    return new AnnotationElement.LazyClass(((Type) value)
238:                            .getClassName());
239:                } else if (value instanceof  Annotation) {
240:                    return getAnnotationProxy(((Annotation) value), loader);
241:                } else if (value instanceof  Object[]) {
242:                    Object[] values = (Object[]) value;
243:                    Object[] holders = new Object[values.length];
244:                    boolean isLazyClass = false;
245:                    for (int i = 0; i < values.length; i++) {
246:                        holders[i] = getAnnotationValueHolder(values[i], loader);
247:                        if (!isLazyClass
248:                                && holders[i] instanceof  AnnotationElement.LazyClass) {
249:                            isLazyClass = true;
250:                        }
251:                    }
252:                    if (isLazyClass) {
253:                        // retype the array
254:                        AnnotationElement.LazyClass[] typedHolders = (AnnotationElement.LazyClass[]) Array
255:                                .newInstance(AnnotationElement.LazyClass.class,
256:                                        values.length);
257:                        for (int i = 0; i < holders.length; i++) {
258:                            typedHolders[i] = (AnnotationElement.LazyClass) holders[i];
259:                        }
260:                        return typedHolders;
261:                    } else {
262:                        return holders;
263:                    }
264:                }
265:                return value;
266:            }
267:
268:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.