KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > retrotranslator > runtime > impl > MethodDescriptor


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

32 package net.sf.retrotranslator.runtime.impl;
33
34 import java.lang.reflect.*;
35 import java.util.*;
36 import net.sf.retrotranslator.runtime.asm.AnnotationVisitor;
37 import net.sf.retrotranslator.runtime.asm.signature.*;
38 import net.sf.retrotranslator.runtime.java.lang.annotation.Annotation_;
39
40 /**
41  * @author Taras Puchko
42  */

43 public class MethodDescriptor extends GenericDeclarationDescriptor {
44
45     private String JavaDoc name;
46     private String JavaDoc desc;
47     private ClassDescriptor classDescriptor;
48     private LazyValue<Class JavaDoc, Method> method;
49     private LazyValue<String JavaDoc, Class JavaDoc> returnType;
50     private LazyValue<Object JavaDoc, Object JavaDoc> defaultValue;
51     private LazyValue<Class JavaDoc, Constructor> constructor;
52     private LazyValue<TypeDescriptor, Type> genericReturnType;
53     private LazyList<TypeDescriptor,Type> genericParameterTypes;
54     private LazyList<TypeDescriptor,Type> genericExceptionTypes;
55     private LazyList<List<AnnotationValue>, Annotation_[]> parameterAnnotations;
56
57     public MethodDescriptor(ClassDescriptor classDescriptor, int access, final String JavaDoc name, final String JavaDoc desc, String JavaDoc signature) {
58         this.classDescriptor = classDescriptor;
59         this.access = access;
60         this.name = name;
61         this.desc = desc;
62         if (signature != null) new SignatureReader(signature).accept(this);
63         this.returnType = createReturnType();
64         if (name.equals(RuntimeTools.CONSTRUCTOR_NAME)) {
65             this.constructor = createConstructor();
66         } else if (!name.equals(RuntimeTools.STATIC_NAME)) {
67             this.method = createMethod();
68         }
69         parameterAnnotations = createParameterAnnotations();
70     }
71
72     private LazyValue<String JavaDoc, Class JavaDoc> createReturnType() {
73         return new LazyValue<String JavaDoc, Class JavaDoc>(desc) {
74             protected Class JavaDoc resolve(String JavaDoc input) {
75                 return getClassByType(net.sf.retrotranslator.runtime.asm.Type.getReturnType(input));
76             }
77         };
78     }
79
80     private LazyValue<Class JavaDoc, Constructor> createConstructor() {
81         return new LazyValue<Class JavaDoc, Constructor>(classDescriptor.getTarget()) {
82             protected Constructor resolve(Class JavaDoc input) {
83                 for (Constructor constructor : input.getDeclaredConstructors()) {
84                     if (RuntimeTools.getConstructorDescriptor(constructor).equals(desc)) return constructor;
85                 }
86                 return null;
87             }
88         };
89     }
90
91     private LazyValue<Class JavaDoc, Method> createMethod() {
92         return new LazyValue<Class JavaDoc, Method>(classDescriptor.getTarget()) {
93             protected Method resolve(Class JavaDoc input) {
94                 for (Method method : input.getDeclaredMethods()) {
95                     if (method.getName().equals(name) &&
96                             net.sf.retrotranslator.runtime.asm.Type.getMethodDescriptor(method).equals(desc)) return method;
97                 }
98                 return null;
99             }
100         };
101     }
102
103     public String JavaDoc getName() {
104         return name;
105     }
106
107     public String JavaDoc getDesc() {
108         return desc;
109     }
110
111     public Class JavaDoc getReturnType() {
112         return returnType.get();
113     }
114
115     public Object JavaDoc getDefaultValue() {
116         return defaultValue == null ? null : RuntimeTools.cloneNonEmptyArray(defaultValue.get());
117     }
118
119     public static MethodDescriptor getInstance(Method method) {
120         ClassDescriptor classDescriptor = ClassDescriptor.getInstance(method.getDeclaringClass());
121         String JavaDoc desc = net.sf.retrotranslator.runtime.asm.Type.getMethodDescriptor(method);
122         MethodDescriptor methodDescriptor = classDescriptor.getMethodDescriptor(method.getName() + desc);
123         if (methodDescriptor == null) {
124             methodDescriptor = new MethodDescriptor(classDescriptor, method.getModifiers(), method.getName(), desc, null);
125         }
126         methodDescriptor.method.provide(method);
127         return methodDescriptor;
128     }
129
130     public static MethodDescriptor getInstance(Constructor constructor) {
131         ClassDescriptor classDescriptor = ClassDescriptor.getInstance(constructor.getDeclaringClass());
132         String JavaDoc desc = RuntimeTools.getConstructorDescriptor(constructor);
133         MethodDescriptor methodDescriptor = classDescriptor.getMethodDescriptor(RuntimeTools.CONSTRUCTOR_NAME + desc);
134         if (methodDescriptor == null) {
135             methodDescriptor = new MethodDescriptor(classDescriptor, constructor.getModifiers(), constructor.getName(), desc, null);
136         }
137         methodDescriptor.constructor.provide(constructor);
138         return methodDescriptor;
139     }
140
141     public GenericDeclaration getTarget() {
142         return method != null ? method.get() : constructor != null ? constructor.get() : null;
143     }
144
145     public Method getMethod() {
146         return method == null ? null : method.get();
147     }
148
149     public Constructor getConstructor() {
150         return constructor == null ? null : constructor.get();
151     }
152
153     public ClassDescriptor getClassDescriptor() {
154         return classDescriptor;
155     }
156
157     protected TypeVariable findTypeVariable(String JavaDoc name) {
158         TypeVariable variable = getTypeVariable(name);
159         return variable != null ? variable : classDescriptor.findTypeVariable(name);
160     }
161
162     public Annotation_[][] getParameterAnnotations() {
163         return parameterAnnotations.getClone();
164     }
165
166     private LazyList<List<AnnotationValue>, Annotation_[]> createParameterAnnotations() {
167         return new LazyList<List<AnnotationValue>, Annotation_[]>() {
168             protected Annotation_[] resolve(List<AnnotationValue> input) {
169                 return createAnnotations(input);
170             }
171
172             protected Annotation_[][] newArray(int size) {
173                 return new Annotation_[net.sf.retrotranslator.runtime.asm.Type.getArgumentTypes(desc).length][];
174             }
175         };
176     }
177
178     public Type getGenericReturnType() {
179         return genericReturnType == null ? null : genericReturnType.get();
180     }
181
182     public Type[] getGenericParameterTypes() {
183         return genericParameterTypes == null ? null : genericParameterTypes.getClone();
184     }
185
186     public Type[] getGenericExceptionTypes() {
187         return genericExceptionTypes == null ? null : genericExceptionTypes.getClone();
188     }
189
190     protected Annotation_[] createAnnotations(Annotation_[] declaredAnnotations) {
191         return declaredAnnotations;
192     }
193
194     public AnnotationVisitor visitParameterAnnotation(int parameter, String JavaDoc desc, boolean visible) {
195         if (!visible) return EMPTY_VISITOR;
196         List<AnnotationValue> values = parameterAnnotations.get(parameter);
197         if (values == null) {
198             values = new ArrayList<AnnotationValue>();
199             parameterAnnotations.set(parameter, values);
200         }
201         AnnotationValue value = new AnnotationValue(desc);
202         values.add(value);
203         return value;
204     }
205
206     public void visit(String JavaDoc name, Object JavaDoc value) {
207         setDefaultValue(value);
208     }
209
210     public void visitEnum(String JavaDoc name, String JavaDoc desc, String JavaDoc value) {
211         setDefaultValue(new EnumValue(desc, value));
212     }
213
214     public AnnotationVisitor visitAnnotation(String JavaDoc name, String JavaDoc desc) {
215         AnnotationValue value = new AnnotationValue(desc);
216         setDefaultValue(value);
217         return value;
218     }
219
220     public AnnotationVisitor visitArray(String JavaDoc name) {
221         AnnotationArray array = new AnnotationArray();
222         setDefaultValue(array);
223         return array;
224     }
225
226     public SignatureVisitor visitParameterType() {
227         TypeDescriptor descriptor = new TypeDescriptor();
228         if (genericParameterTypes == null) genericParameterTypes = getLazyList();
229         genericParameterTypes.add(descriptor);
230         return descriptor;
231     }
232
233     public SignatureVisitor visitReturnType() {
234         TypeDescriptor descriptor = new TypeDescriptor();
235         genericReturnType = getLazyType(descriptor);
236         return descriptor;
237     }
238
239     public SignatureVisitor visitExceptionType() {
240         TypeDescriptor descriptor = new TypeDescriptor();
241         if (genericExceptionTypes == null) genericExceptionTypes = getLazyList();
242         genericExceptionTypes.add(descriptor);
243         return descriptor;
244     }
245
246     private void setDefaultValue(Object JavaDoc o) {
247         defaultValue = new LazyValue<Object JavaDoc, Object JavaDoc>(o) {
248             protected Object JavaDoc resolve(Object JavaDoc input) {
249                 return resolveValue(input, getReturnType(), MethodDescriptor.this);
250             }
251         };
252     }
253
254 }
255
Popular Tags