KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > Annotations


1 /***
2  * ASM examples: examples showing how ASM can be used
3  * Copyright (c) 2000-2005 INRIA, France Telecom
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  * 3. Neither the name of the copyright holders nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
28  * THE POSSIBILITY OF SUCH DAMAGE.
29  */

30 import java.lang.reflect.InvocationTargetException JavaDoc;
31 import java.lang.reflect.Method JavaDoc;
32 import java.util.ArrayList JavaDoc;
33 import java.util.List JavaDoc;
34
35 import org.objectweb.asm.AnnotationVisitor;
36 import org.objectweb.asm.ClassAdapter;
37 import org.objectweb.asm.ClassReader;
38 import org.objectweb.asm.ClassWriter;
39 import org.objectweb.asm.Label;
40 import org.objectweb.asm.MethodAdapter;
41 import org.objectweb.asm.MethodVisitor;
42 import org.objectweb.asm.Opcodes;
43 import org.objectweb.asm.Type;
44
45 public class Annotations {
46
47     public static void foo(final @NotNull
48     String JavaDoc arg)
49     {
50         System.out.println(arg);
51     }
52
53     public static void main(final String JavaDoc[] args) throws Exception JavaDoc {
54         System.out.println("Calling foo(null) results in a NullPointerException:");
55         try {
56             foo(null);
57         } catch (Exception JavaDoc e) {
58             e.printStackTrace(System.out);
59         }
60
61         final String JavaDoc n = Annotations.class.getName();
62         final ClassWriter cw = new ClassWriter(true);
63         ClassReader cr = new ClassReader(n);
64         cr.accept(new ClassAdapter(cw) {
65
66             public MethodVisitor visitMethod(
67                 final int access,
68                 final String JavaDoc name,
69                 final String JavaDoc desc,
70                 final String JavaDoc signature,
71                 final String JavaDoc[] exceptions)
72             {
73                 final Type[] args = Type.getArgumentTypes(desc);
74                 MethodVisitor v = cv.visitMethod(access,
75                         name,
76                         desc,
77                         signature,
78                         exceptions);
79                 return new MethodAdapter(v) {
80
81                     private List JavaDoc params = new ArrayList JavaDoc();
82
83                     public AnnotationVisitor visitParameterAnnotation(
84                         final int parameter,
85                         final String JavaDoc desc,
86                         final boolean visible)
87                     {
88                         AnnotationVisitor av;
89                         av = mv.visitParameterAnnotation(parameter,
90                                 desc,
91                                 visible);
92                         if (desc.equals("LNotNull;")) {
93                             params.add(new Integer JavaDoc(parameter));
94                         }
95                         return av;
96                     }
97
98                     public void visitCode() {
99                         int var = ((access & Opcodes.ACC_STATIC) == 0) ? 1 : 0;
100                         for (int p = 0; p < params.size(); ++p) {
101                             int param = ((Integer JavaDoc) params.get(p)).intValue();
102                             for (int i = 0; i < param; ++i) {
103                                 var += args[i].getSize();
104                             }
105                             String JavaDoc c = "java/lang/IllegalArgumentException";
106                             String JavaDoc d = "(Ljava/lang/String;)V";
107                             Label end = new Label();
108                             mv.visitVarInsn(Opcodes.ALOAD, var);
109                             mv.visitJumpInsn(Opcodes.IFNONNULL, end);
110                             mv.visitTypeInsn(Opcodes.NEW, c);
111                             mv.visitInsn(Opcodes.DUP);
112                             mv.visitLdcInsn("Argument " + param
113                                     + " must not be null");
114                             mv.visitMethodInsn(Opcodes.INVOKESPECIAL,
115                                     c,
116                                     "<init>",
117                                     d);
118                             mv.visitInsn(Opcodes.ATHROW);
119                             mv.visitLabel(end);
120                         }
121                     }
122                 };
123             }
124         }, false);
125
126         Class JavaDoc c = new ClassLoader JavaDoc() {
127             public Class JavaDoc loadClass(final String JavaDoc name)
128                     throws ClassNotFoundException JavaDoc
129             {
130                 if (name.equals(n)) {
131                     byte[] b = cw.toByteArray();
132                     return defineClass(name, b, 0, b.length);
133                 }
134                 return super.loadClass(name);
135             }
136         }.loadClass(n);
137
138         System.out.println();
139         System.out.println("Calling foo(null) on the transformed class results in an IllegalArgumentException:");
140         Method JavaDoc m = c.getMethod("foo", new Class JavaDoc[] { String JavaDoc.class });
141         try {
142             m.invoke(null, new Object JavaDoc[] { null });
143         } catch (InvocationTargetException JavaDoc e) {
144             e.getCause().printStackTrace(System.out);
145         }
146     }
147 }
148
Popular Tags