KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > codehaus > aspectwerkz > annotation > instrumentation > asm > CustomAttributeHelper


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.instrumentation.asm;
9
10 import org.objectweb.asm.attrs.Annotation;
11 import org.objectweb.asm.attrs.RuntimeInvisibleAnnotations;
12 import org.objectweb.asm.Attribute;
13 import org.codehaus.aspectwerkz.util.Base64;
14 import org.codehaus.aspectwerkz.util.UnbrokenObjectInputStream;
15 import org.codehaus.aspectwerkz.annotation.AnnotationInfo;
16 import org.codehaus.aspectwerkz.exception.WrappedRuntimeException;
17
18 import java.io.ByteArrayInputStream JavaDoc;
19
20 /**
21  * Helper class to wrap a custom annotation proxy (1.3/1.4 javadoc annotation) in a RuntimeInvisibleAnnotations.
22  * <br/>
23  * The proxy is wrapped in a AnnotationInfo object which is serialized
24  * and base64 encoded (ASM issue on array types in RIV).
25  *
26  * @author <a HREF="mailto:alex@gnilux.com">Alexandre Vasseur</a>
27  */

28 public class CustomAttributeHelper {
29
30     /**
31      * Annotation parameter - as if it was a single value Tiger annotation
32      */

33     private final static String JavaDoc VALUE = "value";
34
35     /**
36      * Extract the AnnotationInfo from the bytecode Annotation representation.
37      *
38      * @param annotation must be a valid RIV, of type CustomAttribute.TYPE
39      * @return
40      */

41     public static AnnotationInfo extractCustomAnnotation(final Annotation annotation) {
42         byte[] bytes = Base64.decode((String JavaDoc) ((Object JavaDoc[]) annotation.elementValues.get(0))[1]);
43         return extractCustomAnnotation(bytes);
44     }
45
46     /**
47      * Extract the AnnotationInfo from the base64 encoded serialized version.
48      *
49      * @param bytes
50      * @return
51      */

52     private static AnnotationInfo extractCustomAnnotation(final byte[] bytes) {
53         try {
54             Object JavaDoc userAnnotation = new UnbrokenObjectInputStream(new ByteArrayInputStream JavaDoc(bytes)).readObject();
55             if (userAnnotation instanceof AnnotationInfo) {
56                 return (AnnotationInfo)userAnnotation;
57             } else {
58                 // should not occur
59
throw new RuntimeException JavaDoc(
60                         "Custom annotation is not wrapped in AnnotationInfo: " + userAnnotation.getClass().getName() +
61                         " [" + AnnotationInfo.class.getClassLoader().toString() + " / " +
62                         userAnnotation.getClass().getClassLoader().toString() + " / " +
63                         Thread.currentThread().getContextClassLoader()
64                 );
65             }
66         } catch (Exception JavaDoc e) {
67             throw new WrappedRuntimeException(e);
68         }
69     }
70
71     /**
72      * Create an Annotation bytecode representation from the serialized version of the custom annotation proxy
73      *
74      * @param bytes
75      * @return
76      */

77     public static Annotation createCustomAnnotation(final byte[] bytes) {
78         Annotation annotation = new Annotation();
79         annotation.type = CustomAttribute.TYPE;
80         annotation.add(VALUE, Base64.encodeBytes(bytes));
81         return annotation;
82     }
83
84     /**
85      * Helper method to find the first RuntimeInvisibleAnnotations attribute in an Attribute chain.
86      * <br/>If no such RIV exists, a new one is created (empty) and added last in the chain.
87      * <br/>If the chain is null, a new sole RIV (empty) is created
88      *
89      * @param attribute
90      * @return the RuntimeInvisibleAnnotations to add Annotation to
91      */

92     public static RuntimeInvisibleAnnotations linkRuntimeInvisibleAnnotations(final Attribute attribute) {
93         RuntimeInvisibleAnnotations runtimeInvisibleAnnotations = null;
94         Attribute lastAttribute = attribute;
95         for (Attribute loop = attribute; loop != null; loop = loop.next) {
96             lastAttribute = loop;
97             if (loop instanceof RuntimeInvisibleAnnotations) {
98                 return runtimeInvisibleAnnotations = (RuntimeInvisibleAnnotations) loop;
99             }
100         }
101         // not found, link a new one to lastAttribute
102
runtimeInvisibleAnnotations = new RuntimeInvisibleAnnotations();
103         runtimeInvisibleAnnotations.next = null;
104         if (attribute != null) {
105             // if arg is null, we are just adding this annotation as the sole attribute
106
lastAttribute.next = runtimeInvisibleAnnotations;
107         } else {
108             //attribute = runtimeInvisibleAnnotations;
109
}
110         return runtimeInvisibleAnnotations;
111     }
112 }
113
Popular Tags