001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: * -------------------------------------------------------------------------
017: * * Copyright (c) 2000-2005 INRIA, France Telecom
018: * All rights reserved.
019: *
020: * Redistribution and use in source and binary forms, with or without
021: * modification, are permitted provided that the following conditions
022: * are met:
023: * 1. Redistributions of source code must retain the above copyright
024: * notice, this list of conditions and the following disclaimer.
025: * 2. Redistributions in binary form must reproduce the above copyright
026: * notice, this list of conditions and the following disclaimer in the
027: * documentation and/or other materials provided with the distribution.
028: * 3. Neither the name of the copyright holders nor the names of its
029: * contributors may be used to endorse or promote products derived from
030: * this software without specific prior written permission.
031: *
032: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
033: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
034: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
035: * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
036: * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
037: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
038: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
039: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
040: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
041: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
042: * THE POSSIBILITY OF SUCH DAMAGE.
043:
044: *
045: */package org.apache.openejb;
046:
047: import org.objectweb.asm.AnnotationVisitor;
048: import org.objectweb.asm.ClassVisitor;
049: import org.objectweb.asm.FieldVisitor;
050: import org.objectweb.asm.MethodVisitor;
051: import org.objectweb.asm.Attribute;
052: import org.objectweb.asm.Type;
053: import org.objectweb.asm.Label;
054: import org.objectweb.asm.signature.SignatureVisitor;
055: import org.objectweb.asm.signature.SignatureReader;
056:
057: import java.util.Set;
058: import java.util.HashSet;
059: import java.util.Map;
060: import java.util.HashMap;
061:
062: /**
063: * @version $Rev: 602704 $ $Date: 2007-12-09 09:58:22 -0800 $
064: */
065: public class DependencyVisitor implements AnnotationVisitor,
066: SignatureVisitor, ClassVisitor, FieldVisitor, MethodVisitor {
067: Set<String> packages = new HashSet<String>();
068:
069: Map<String, Map<String, Integer>> groups = new HashMap<String, Map<String, Integer>>();
070:
071: Map<String, Integer> current;
072:
073: public Map<String, Map<String, Integer>> getGlobals() {
074: return groups;
075: }
076:
077: public Set<String> getPackages() {
078: return packages;
079: }
080:
081: // ClassVisitor
082:
083: public void visit(final int version, final int access,
084: final String name, final String signature,
085: final String super Name, final String[] interfaces) {
086: String p = getGroupKey(name);
087: current = groups.get(p);
088: if (current == null) {
089: current = new HashMap<String, Integer>();
090: groups.put(p, current);
091: }
092:
093: if (signature == null) {
094: addName(super Name);
095: addNames(interfaces);
096: } else {
097: addSignature(signature);
098: }
099: }
100:
101: public AnnotationVisitor visitAnnotation(final String desc,
102: final boolean visible) {
103: addDesc(desc);
104: return this ;
105: }
106:
107: public void visitAttribute(final Attribute attr) {
108: }
109:
110: public FieldVisitor visitField(final int access, final String name,
111: final String desc, final String signature,
112: final Object value) {
113: if (signature == null) {
114: addDesc(desc);
115: } else {
116: addTypeSignature(signature);
117: }
118: if (value instanceof Type) {
119: addType((Type) value);
120: }
121: return this ;
122: }
123:
124: public MethodVisitor visitMethod(final int access,
125: final String name, final String desc,
126: final String signature, final String[] exceptions) {
127: if (signature == null) {
128: addMethodDesc(desc);
129: } else {
130: addSignature(signature);
131: }
132: addNames(exceptions);
133: return this ;
134: }
135:
136: public void visitSource(final String source, final String debug) {
137: }
138:
139: public void visitInnerClass(final String name,
140: final String outerName, final String innerName,
141: final int access) {
142: // addName( outerName);
143: // addName( innerName);
144: }
145:
146: public void visitOuterClass(final String owner, final String name,
147: final String desc) {
148: // addName(owner);
149: // addMethodDesc(desc);
150: }
151:
152: // MethodVisitor
153:
154: public AnnotationVisitor visitParameterAnnotation(
155: final int parameter, final String desc,
156: final boolean visible) {
157: addDesc(desc);
158: return this ;
159: }
160:
161: public void visitTypeInsn(final int opcode, final String desc) {
162: if (desc.charAt(0) == '[') {
163: addDesc(desc);
164: } else {
165: addName(desc);
166: }
167: }
168:
169: public void visitFieldInsn(final int opcode, final String owner,
170: final String name, final String desc) {
171: addName(owner);
172: addDesc(desc);
173: }
174:
175: public void visitMethodInsn(final int opcode, final String owner,
176: final String name, final String desc) {
177: addName(owner);
178: addMethodDesc(desc);
179: }
180:
181: public void visitLdcInsn(final Object cst) {
182: if (cst instanceof Type) {
183: addType((Type) cst);
184: }
185: }
186:
187: public void visitMultiANewArrayInsn(final String desc,
188: final int dims) {
189: addDesc(desc);
190: }
191:
192: public void visitLocalVariable(final String name,
193: final String desc, final String signature,
194: final Label start, final Label end, final int index) {
195: addTypeSignature(signature);
196: }
197:
198: public AnnotationVisitor visitAnnotationDefault() {
199: return this ;
200: }
201:
202: public void visitCode() {
203: }
204:
205: public void visitFrame(final int type, final int nLocal,
206: final Object[] local, final int nStack, final Object[] stack) {
207: }
208:
209: public void visitInsn(final int opcode) {
210: }
211:
212: public void visitIntInsn(final int opcode, final int operand) {
213: }
214:
215: public void visitVarInsn(final int opcode, final int var) {
216: }
217:
218: public void visitJumpInsn(final int opcode, final Label label) {
219: }
220:
221: public void visitLabel(final Label label) {
222: }
223:
224: public void visitIincInsn(final int var, final int increment) {
225: }
226:
227: public void visitTableSwitchInsn(final int min, final int max,
228: final Label dflt, final Label[] labels) {
229: }
230:
231: public void visitLookupSwitchInsn(final Label dflt,
232: final int[] keys, final Label[] labels) {
233: }
234:
235: public void visitTryCatchBlock(final Label start, final Label end,
236: final Label handler, final String type) {
237: addName(type);
238: }
239:
240: public void visitLineNumber(final int line, final Label start) {
241: }
242:
243: public void visitMaxs(final int maxStack, final int maxLocals) {
244: }
245:
246: // AnnotationVisitor
247:
248: public void visit(final String name, final Object value) {
249: if (value instanceof Type) {
250: addType((Type) value);
251: }
252: }
253:
254: public void visitEnum(final String name, final String desc,
255: final String value) {
256: addDesc(desc);
257: }
258:
259: public AnnotationVisitor visitAnnotation(final String name,
260: final String desc) {
261: addDesc(desc);
262: return this ;
263: }
264:
265: public AnnotationVisitor visitArray(final String name) {
266: return this ;
267: }
268:
269: // SignatureVisitor
270:
271: public void visitFormalTypeParameter(final String name) {
272: }
273:
274: public SignatureVisitor visitClassBound() {
275: return this ;
276: }
277:
278: public SignatureVisitor visitInterfaceBound() {
279: return this ;
280: }
281:
282: public SignatureVisitor visitSuperclass() {
283: return this ;
284: }
285:
286: public SignatureVisitor visitInterface() {
287: return this ;
288: }
289:
290: public SignatureVisitor visitParameterType() {
291: return this ;
292: }
293:
294: public SignatureVisitor visitReturnType() {
295: return this ;
296: }
297:
298: public SignatureVisitor visitExceptionType() {
299: return this ;
300: }
301:
302: public void visitBaseType(final char descriptor) {
303: }
304:
305: public void visitTypeVariable(final String name) {
306: // TODO verify
307: }
308:
309: public SignatureVisitor visitArrayType() {
310: return this ;
311: }
312:
313: public void visitClassType(final String name) {
314: addName(name);
315: }
316:
317: public void visitInnerClassType(final String name) {
318: addName(name);
319: }
320:
321: public void visitTypeArgument() {
322: }
323:
324: public SignatureVisitor visitTypeArgument(final char wildcard) {
325: return this ;
326: }
327:
328: // common
329:
330: public void visitEnd() {
331: }
332:
333: // ---------------------------------------------
334:
335: private String getGroupKey(String name) {
336: int n = name.lastIndexOf('/');
337: if (n > -1) {
338: name = name.substring(0, n);
339: }
340: name = name.replace('/', '.');
341: packages.add(name);
342: return name;
343: }
344:
345: private void addName(final String name) {
346: if (name == null) {
347: return;
348: }
349: String p = getGroupKey(name);
350: if (current.containsKey(p)) {
351: current.put(p, current.get(p) + 1);
352: } else {
353: current.put(p, 1);
354: }
355: }
356:
357: private void addNames(final String[] names) {
358: for (int i = 0; names != null && i < names.length; i++) {
359: addName(names[i]);
360: }
361: }
362:
363: private void addDesc(final String desc) {
364: addType(Type.getType(desc));
365: }
366:
367: private void addMethodDesc(final String desc) {
368: addType(Type.getReturnType(desc));
369: Type[] types = Type.getArgumentTypes(desc);
370: for (int i = 0; i < types.length; i++) {
371: addType(types[i]);
372: }
373: }
374:
375: private void addType(final Type t) {
376: switch (t.getSort()) {
377: case Type.ARRAY:
378: addType(t.getElementType());
379: break;
380: case Type.OBJECT:
381: addName(t.getClassName().replace('.', '/'));
382: break;
383: }
384: }
385:
386: private void addSignature(final String signature) {
387: if (signature != null) {
388: new SignatureReader(signature).accept(this );
389: }
390: }
391:
392: private void addTypeSignature(final String signature) {
393: if (signature != null) {
394: new SignatureReader(signature).acceptType(this);
395: }
396: }
397: }
|