KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > tools > verifier > apiscan > classfile > ASMMethod


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23
24
25 package com.sun.enterprise.tools.verifier.apiscan.classfile;
26
27 import com.sun.corba.ee.org.objectweb.asm.Label;
28 import com.sun.corba.ee.org.objectweb.asm.Opcodes;
29 import com.sun.corba.ee.org.objectweb.asm.commons.EmptyVisitor;
30 import com.sun.corba.ee.org.objectweb.asm.util.AbstractVisitor;
31
32 import java.util.*;
33 import java.util.logging.Level JavaDoc;
34 import java.util.logging.Logger JavaDoc;
35 import java.lang.ref.SoftReference JavaDoc;
36
37 /**
38  * @author Sanjeeb.Sahoo@Sun.COM
39  */

40 class ASMMethod extends EmptyVisitor implements Method {
41
42     private static String JavaDoc resourceBundleName = "com.sun.enterprise.tools.verifier.apiscan.LocalStrings";
43     private static Logger JavaDoc logger = Logger.getLogger("apiscan.classfile", resourceBundleName); // NOI18N
44

45     private SoftReference JavaDoc<ClassFile> owningClass;
46
47     private String JavaDoc descriptor;
48
49     private int access;
50
51     private String JavaDoc signature;
52
53     private String JavaDoc[] exceptions;
54
55     private String JavaDoc name;
56
57     private Set<MethodRef> referencedMethods = new HashSet<MethodRef>();
58
59     private Set<String JavaDoc> referencedClasses = new HashSet<String JavaDoc>();
60
61     // A reference to represent itself
62
private MethodRef methodRef;
63
64     public ASMMethod(
65             ClassFile owningClass, String JavaDoc name, String JavaDoc descriptor, int access,
66             String JavaDoc signature, String JavaDoc[] exceptions) {
67         this.owningClass = new SoftReference JavaDoc<ClassFile>(owningClass);
68         this.name = name;
69         this.descriptor = descriptor;
70         this.access = access;
71         this.signature = signature;
72         if(exceptions==null) {
73             this.exceptions = new String JavaDoc[0];
74         } else {
75             this.exceptions = exceptions;
76         }
77     }
78
79     public ClassFile getOwningClass() {
80         return owningClass.get();
81     }
82
83     public String JavaDoc getName() {
84         return name;
85     }
86
87     public String JavaDoc getDescriptor() {
88         return descriptor;
89     }
90
91     public Collection<MethodRef> getReferencedMethods() {
92         return Collections.unmodifiableCollection(referencedMethods);
93     }
94
95     public Collection<String JavaDoc> getReferencedClasses() {
96         return Collections.unmodifiableCollection(referencedClasses);
97     }
98
99     // TODO: Not yet synchronized.
100
public MethodRef getSelfReference() {
101         if(methodRef==null){
102             methodRef = new MethodRef(owningClass.get().getInternalName(), name, descriptor);
103         }
104         return methodRef;
105     }
106
107     public boolean isNative() {
108         return (access & Opcodes.ACC_NATIVE) == Opcodes.ACC_NATIVE;
109     }
110
111     @Override JavaDoc public void visitFieldInsn(
112             int opcode, String JavaDoc owner, String JavaDoc name, String JavaDoc desc) {
113         logger.entering(
114                 "com.sun.enterprise.tools.verifier.apiscan.classfile.ASMMethod", "visitFieldInsn", // NOI18N
115
new Object JavaDoc[]{AbstractVisitor.OPCODES[opcode], owner, name, desc});
116         addClass(owner);
117     }
118
119     @Override JavaDoc public void visitTryCatchBlock(
120             Label start, Label end, Label handler, String JavaDoc type) {
121         logger.entering(
122                 "com.sun.enterprise.tools.verifier.apiscan.classfile.ASMMethod", "visitTryCatchBlock", // NOI18N
123
new Object JavaDoc[]{type});
124         if(type!=null) { // try-finally comes as null
125
addClass(type);
126         }
127     }
128
129     public void visitMethodInsn(
130             int opcode, String JavaDoc owner, String JavaDoc name, String JavaDoc desc) {
131         logger.entering(
132                 "com.sun.enterprise.tools.verifier.apiscan.classfile.ASMMethod", "visitMethodInsn", new Object JavaDoc[]{ // NOI18N
133
AbstractVisitor.OPCODES[opcode], owner, name, desc});
134         addMethod(owner, name, desc);
135     }
136
137     // things like instanceof, checkcast, new, newarray and anewarray
138
@Override JavaDoc public void visitTypeInsn(int opcode, String JavaDoc desc) {
139         logger.entering(
140                 "com.sun.enterprise.tools.verifier.apiscan.classfile.ASMMethod", "visitTypeInsn", new Object JavaDoc[]{ // NOI18N
141
AbstractVisitor.OPCODES[opcode], desc});
142         switch (opcode) {
143             case Opcodes.INSTANCEOF:
144             case Opcodes.CHECKCAST:
145             case Opcodes.ANEWARRAY:
146                 addClass(desc);
147                 break;
148             case Opcodes.NEW:
149                 // skip as class gets added during constructor call.
150
break;
151             case Opcodes.NEWARRAY:
152                 // primitive type array, so skip
153
break;
154             default:
155                 logger.logp(Level.WARNING, "com.sun.enterprise.tools.verifier.apiscan.classfile.ASMMethod", "visitTypeInsn", // NOI18N
156
getClass().getName() + ".warning1", AbstractVisitor.OPCODES[opcode]); // NOI18N
157
break;
158         }
159     }
160
161     @Override JavaDoc public void visitMultiANewArrayInsn(String JavaDoc desc, int dims) {
162         logger.entering(
163                 "com.sun.enterprise.tools.verifier.apiscan.classfile.ASMMethod", "visitMultiANewArrayInsn", // NOI18N
164
new Object JavaDoc[]{desc});
165         addClass(desc);
166     }
167
168     @Override JavaDoc public String JavaDoc toString() {
169         StringBuilder JavaDoc sb = new StringBuilder JavaDoc(
170                 decodeAccessFlag(access) +
171                 name +
172                 " " + // NOI18N
173
descriptor+
174                 "{\n"); // NOI18N
175
for(MethodRef mr : referencedMethods){
176             sb.append(mr).append("\n"); // NOI18N
177
}
178         sb.append("}"); // NOI18N
179
return sb.toString();
180     }
181
182     public int getAccess() {
183         return access;
184     }
185
186     public String JavaDoc getSignature() {
187         return signature;
188     }
189
190     /**
191      * {@inheritDoc}
192      */

193     public String JavaDoc[] getExceptions() {
194         return exceptions;
195     }
196
197     private void addClass(String JavaDoc nameOrTypeDescriptor) {
198         //sometimes we get names like Ljava.lang.Integer; or [I. So we need
199
// to decode the names.
200
if (nameOrTypeDescriptor.indexOf(';') != -1 ||
201                 nameOrTypeDescriptor.indexOf('[') != -1) {
202             referencedClasses.addAll(
203                     typeDescriptorToClassNames(nameOrTypeDescriptor));
204         } else {
205             referencedClasses.add(nameOrTypeDescriptor);
206         }
207     }
208
209     private void addMethod(String JavaDoc owner, String JavaDoc name, String JavaDoc desc) {
210         addClass(owner);
211         // We don't need the following code as this is not required.
212
// because if everything is null, then no class gets loaded.
213
// for(String embeddedClassName : typeDescriptorToClassNames(desc)) {
214
// referencedClasses.add(embeddedClassName);
215
// }
216
referencedMethods.add(new MethodRef(owner, name, desc));
217     }
218
219     public static String JavaDoc decodeAccessFlag(int access) {
220         StringBuilder JavaDoc result = new StringBuilder JavaDoc("");
221         if ((access & Opcodes.ACC_PRIVATE) == Opcodes.ACC_PRIVATE) {
222             result.append("private "); // NOI18N
223
} else if ((access & Opcodes.ACC_PROTECTED) == Opcodes.ACC_PROTECTED) {
224             result.append("protected "); // NOI18N
225
} else if ((access & Opcodes.ACC_PUBLIC) == Opcodes.ACC_PUBLIC) {
226             result.append("public "); // NOI18N
227
}
228         if ((access & Opcodes.ACC_ABSTRACT) == Opcodes.ACC_ABSTRACT) {
229             result.append("abstract "); // NOI18N
230
} else if ((access & Opcodes.ACC_FINAL) == Opcodes.ACC_FINAL) {
231             result.append("final "); // NOI18N
232
} else if ((access & Opcodes.ACC_STATIC) == Opcodes.ACC_STATIC) {
233             result.append("static "); // NOI18N
234
}
235         if ((access & Opcodes.ACC_NATIVE) == Opcodes.ACC_NATIVE) {
236             result.append("native "); // NOI18N
237
}
238         return result.toString();
239     }
240
241     private static List<String JavaDoc> typeDescriptorToClassNames(String JavaDoc signature) {
242         logger.entering(
243                 "com.sun.enterprise.tools.verifier.apiscan.classfile.ASMMethod", "typeDescriptorToClassNames", // NOI18N
244
new Object JavaDoc[]{signature});
245         List<String JavaDoc> result = new ArrayList<String JavaDoc>();
246         int i = 0;
247         while ((i = signature.indexOf('L', i)) != -1) {
248             int j = signature.indexOf(';', i);
249             if (j > i) {
250                 // get name, minus leading 'L' and trailing ';'
251
String JavaDoc className = signature.substring(i + 1, j);
252                 if (!Util.isPrimitive(className)) result.add(className);
253                 i = j + 1;
254             } else
255                 break;
256         }
257         if (logger.isLoggable(Level.FINE)) {
258             StringBuffer JavaDoc sb = new StringBuffer JavaDoc("Class Names are {"); // NOI18N
259
int size = result.size();
260             for (int k = 0; k < size; k++) {
261                 sb.append((String JavaDoc) result.get(k));
262                 if (k != size - 1) sb.append(", "); // NOI18N
263
}
264             sb.append("}"); // NOI18N
265
logger.finer(sb.toString());
266         }
267         return result;
268     }
269
270 }
271
Popular Tags