View Javadoc

1   /*
2    * Copyright 2001-2005 The Apache Software Foundation.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package net.sf.mavenizer.analyser.asm;
18  
19  import net.sf.mavenizer.analyser.bytecode.ParsingHandler;
20  
21  import org.apache.commons.logging.Log;
22  import org.apache.commons.logging.LogFactory;
23  import org.objectweb.asm.AnnotationVisitor;
24  import org.objectweb.asm.FieldVisitor;
25  import org.objectweb.asm.Label;
26  import org.objectweb.asm.MethodVisitor;
27  import org.objectweb.asm.Type;
28  import org.objectweb.asm.signature.SignatureReader;
29  
30  
31  /***
32   * @author <a href="mailto:cedric-vidal@users.sourceforge.net">C&eacute;dric Vidal</a>
33   *
34   */
35  public class DefaultDependencyVisitor extends AbstractDependencyVisitor {
36  
37  	private static Log log = LogFactory.getLog(DefaultDependencyVisitor.class);
38  
39  	private ParsingHandler parsingListener;
40  
41  	// ClassVisitor
42  
43  	public void visit(final int version, final int access,
44  			final String classFullyQualifiedName, final String signature,
45  			final String superClassFullyQualifiedName, final String[] interfaces) {
46  
47  		getParsingListener().source(classFullyQualifiedName);
48  
49  		if (signature == null) {
50  			addClassName(superClassFullyQualifiedName);
51  			addClassNames(interfaces);
52  		} else {
53  			addSignature(signature);
54  		}
55  	}
56  
57  	public AnnotationVisitor visitAnnotation(final String desc,
58  			final boolean visible) {
59  		addDesc(desc);
60  		return this;
61  	}
62  
63  	public FieldVisitor visitField(final int access, final String name,
64  			final String desc, final String signature, final Object value) {
65  		if (signature == null) {
66  			addDesc(desc);
67  		} else {
68  			addTypeSignature(signature);
69  		}
70  		if (value instanceof Type) {
71  			addType((Type) value);
72  		}
73  		return this;
74  	}
75  
76  	public MethodVisitor visitMethod(final int access, final String name,
77  			final String desc, final String signature, final String[] exceptions) {
78  		if (signature == null) {
79  			addMethodDesc(desc);
80  		} else {
81  			addSignature(signature);
82  		}
83  		addClassNames(exceptions);
84  		return this;
85  	}
86  
87  	public void visitInnerClass(final String name, final String outerName,
88  			final String innerName, final int access) {
89  		// addName( outerName);
90  		// addName( innerName);
91  	}
92  
93  	public void visitOuterClass(final String owner, final String name,
94  			final String desc) {
95  		// addName(owner);
96  		// addMethodDesc(desc);
97  	}
98  
99  	// MethodVisitor
100 
101 	public AnnotationVisitor visitParameterAnnotation(final int parameter,
102 			final String desc, final boolean visible) {
103 		addDesc(desc);
104 		return this;
105 	}
106 
107 	public void visitTypeInsn(final int opcode, final String desc) {
108 		if (desc.charAt(0) == '[') {
109 			addDesc(desc);
110 		} else {
111 			addClassName(desc);
112 		}
113 	}
114 
115 	public void visitFieldInsn(final int opcode, final String owner,
116 			final String name, final String desc) {
117 		addClassName(owner);
118 		addDesc(desc);
119 	}
120 
121 	public void visitMethodInsn(final int opcode, final String owner,
122 			final String name, final String desc) {
123 		addClassName(owner);
124 		addMethodDesc(desc);
125 	}
126 
127 	public void visitLdcInsn(final Object cst) {
128 		if (cst instanceof Type) {
129 			addType((Type) cst);
130 		}
131 	}
132 
133 	public void visitMultiANewArrayInsn(final String desc, final int dims) {
134 		addDesc(desc);
135 	}
136 
137 	public void visitLocalVariable(final String name, final String desc,
138 			final String signature, final Label start, final Label end,
139 			final int index) {
140 		addTypeSignature(signature);
141 	}
142 
143 	public void visitTryCatchBlock(final Label start, final Label end,
144 			final Label handler, final String type) {
145 		addClassName(type);
146 	}
147 
148 	// AnnotationVisitor
149 
150 	public void visit(final String name, final Object value) {
151 		if (value instanceof Type) {
152 			addType((Type) value);
153 		}
154 	}
155 
156 	public void visitEnum(final String name, final String desc,
157 			final String value) {
158 		addDesc(desc);
159 	}
160 
161 	public AnnotationVisitor visitAnnotation(final String name,
162 			final String desc) {
163 		addDesc(desc);
164 		return this;
165 	}
166 
167 	// SignatureVisitor
168 
169 	public void visitTypeVariable(final String name) {
170 		// TODO verify
171 	}
172 
173 	public void visitClassType(final String name) {
174 		addClassName(name);
175 	}
176 
177 	public void visitInnerClassType(final String name) {
178 		addClassName(name);
179 	}
180 
181 	// ---------------------------------------------
182 
183 	private void addClassName(final String name) {
184 		if (name == null) {
185 			return;
186 		}
187 		getParsingListener().target(name);
188 	}
189 
190 	private void addClassNames(final String[] names) {
191 		for (int i = 0; names != null && i < names.length; i++) {
192 			addClassName(names[i]);
193 		}
194 	}
195 
196 	private void addDesc(final String desc) {
197 		addType(Type.getType(desc));
198 	}
199 
200 	private void addMethodDesc(final String desc) {
201 		addType(Type.getReturnType(desc));
202 		Type[] types = Type.getArgumentTypes(desc);
203 		for (int i = 0; i < types.length; i++) {
204 			addType(types[i]);
205 		}
206 	}
207 
208 	private void addType(final Type t) {
209 		switch (t.getSort()) {
210 		case Type.ARRAY:
211 			addType(t.getElementType());
212 			break;
213 		case Type.OBJECT:
214 			addClassName(t.getClassName().replace('.', '/'));
215 			break;
216 		default:
217 			// do nothing
218 			break;
219 		}
220 	}
221 
222 	private void addSignature(final String signature) {
223 		if (signature != null) {
224 			new SignatureReader(signature).accept(this);
225 		}
226 	}
227 
228 	private void addTypeSignature(final String signature) {
229 		if (signature != null) {
230 			new SignatureReader(signature).acceptType(this);
231 		}
232 	}
233 
234 	public ParsingHandler getParsingListener() {
235 		return parsingListener;
236 	}
237 
238 	public void setParsingListener(ParsingHandler parsingListener) {
239 		this.parsingListener = parsingListener;
240 	}
241 
242 }