KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > puppycrawl > tools > checkstyle > checks > usage > transmogrify > ExternalClass


1
2 // Transmogrify License
3
//
4
// Copyright (c) 2001, ThoughtWorks, Inc.
5
// All rights reserved.
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
// - Redistributions of source code must retain the above copyright notice,
10
// this list of conditions and the following disclaimer.
11
// - 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
// Neither the name of the ThoughtWorks, Inc. nor the names of its
15
// contributors may be used to endorse or promote products derived from this
16
// software without specific prior written permission.
17
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19
// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
21
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28

29 package com.puppycrawl.tools.checkstyle.checks.usage.transmogrify;
30
31
32
33 import java.lang.reflect.Constructor JavaDoc;
34 import java.lang.reflect.Field JavaDoc;
35 import java.lang.reflect.Method JavaDoc;
36 import java.util.ArrayList JavaDoc;
37 import java.util.Collection JavaDoc;
38 import java.util.HashSet JavaDoc;
39 import java.util.Iterator JavaDoc;
40 import java.util.List JavaDoc;
41 import java.util.Set JavaDoc;
42 import java.util.SortedSet JavaDoc;
43 import java.util.TreeSet JavaDoc;
44
45 //import com.puppycrawl.tools.checkstyle.checks.lint.parser.DotUtils;
46

47 public class ExternalClass extends ExternalDefinition implements IClass {
48   private Class JavaDoc _javaClass;
49
50   private List JavaDoc _subclasses;
51   private List JavaDoc _implementors;
52
53   private Set JavaDoc _methods;
54
55   public ExternalClass(Class JavaDoc javaClass) {
56     _javaClass = javaClass;
57     _subclasses = new ArrayList JavaDoc();
58     _implementors = new ArrayList JavaDoc();
59   }
60
61   public Class JavaDoc getJavaClass() {
62     return _javaClass;
63   }
64
65   public String JavaDoc getName() {
66     return getLocalName();
67   }
68
69   private String JavaDoc getLocalName() {
70     String JavaDoc fullName = _javaClass.getName();
71     return fullName.substring(fullName.lastIndexOf(".") + 1);
72   }
73
74   public IClass getSuperclass() {
75     IClass result = null;
76     Class JavaDoc javaSuperclass = _javaClass.getSuperclass();
77
78     if (javaSuperclass != null) {
79       result = new ExternalClass(javaSuperclass);
80     }
81     else {
82       if (_javaClass.isInterface()) {
83         // according to Java, java.lang.Object is not the superclass of
84
// interfaces, which makes sense. However, we need Object to be
85
// the superclass of everything to make type compatibility work.
86
result = new ExternalClass(Object JavaDoc.class);
87       }
88     }
89
90     return result;
91   }
92
93   public IClass[] getInterfaces() {
94     Class JavaDoc[] javaInterfaces = _javaClass.getInterfaces();
95
96     IClass[] result = new IClass[javaInterfaces.length];
97
98     // should we cache this?
99
for (int i = 0; i < javaInterfaces.length; i++) {
100       result[i] = new ExternalClass(javaInterfaces[i]);
101     }
102
103     return result;
104   }
105
106   public IClass getClassDefinition(String JavaDoc name) {
107     IClass result = null;
108
109     String JavaDoc qualifiedName = getQualifiedName() + "$" + name;
110
111     Class JavaDoc[] classes = getJavaClass().getClasses();
112     for (int i = 0; i < classes.length; i++) {
113       String JavaDoc candidateQualifiedName = classes[i].getName();
114
115       if (qualifiedName.equals(candidateQualifiedName)) {
116         result = new ExternalClass(classes[i]);
117         break;
118       }
119     }
120
121     return result;
122   }
123
124   // REDTAG -- this should be a template method!
125
public IVariable getVariableDefinition(String JavaDoc name) {
126     IVariable result = null;
127     Field JavaDoc javaField = null;
128
129     try {
130       javaField = _javaClass.getDeclaredField(name);
131     }
132     catch (NoSuchFieldException JavaDoc ignoreMe) {}
133
134     if (javaField == null) {
135       Class JavaDoc[] interfaces = _javaClass.getInterfaces();
136       for (int i = 0; i < interfaces.length && javaField == null; i++) {
137         try {
138           javaField = interfaces[i].getDeclaredField(name);
139         }
140         catch (NoSuchFieldException JavaDoc ignoreMe) {}
141       }
142     }
143
144     if (javaField != null) {
145       result = new ExternalVariable(javaField);
146     }
147     else {
148       if (getSuperclass() != null) {
149         result = getSuperclass().getVariableDefinition(name);
150       }
151     }
152
153     return result;
154   }
155
156   public IMethod getMethodDefinition(String JavaDoc name,
157                                      ISignature signature) {
158     IMethod result = null;
159
160     if (name.equals(getName())) {
161       result = getConstructorDefinition(signature);
162     }
163     else {
164       Method JavaDoc[] methods = _javaClass.getDeclaredMethods();
165
166       for (int i = 0; i < methods.length; i++) {
167         if (name.equals(methods[i].getName())) {
168           IMethod method = new ExternalMethod(methods[i]);
169           if (method.hasSameSignature(signature)) {
170             result = method;
171             break;
172           }
173         }
174       }
175
176       if (result == null) {
177         result = getMostCompatibleMethod(name, signature);
178       }
179
180       if (result == null) {
181         if (getSuperclass() != null) {
182           result = getSuperclass().getMethodDefinition(name, signature);
183         }
184       }
185
186       if (result == null) {
187         IClass[] interfaces = getInterfaces();
188         for (int i = 0; i < interfaces.length; i++) {
189           result = interfaces[i].getMethodDefinition(name, signature);
190
191           if (result != null) {
192             break;
193           }
194
195         }
196       }
197     }
198
199     return result;
200   }
201
202   public IMethod getMostCompatibleMethod(String JavaDoc name, ISignature signature) {
203     IMethod result = null;
204
205     SortedSet JavaDoc compatibleMethods
206       = new TreeSet JavaDoc(new MethodSpecificityComparator());
207
208     Iterator JavaDoc it = getMethods().iterator();
209     while (it.hasNext()) {
210       IMethod method = (IMethod)it.next();
211       if ( name.equals( method.getName() ) ) {
212         if ( method.hasCompatibleSignature( signature ) ) {
213           compatibleMethods.add(method);
214         }
215       }
216     }
217
218     if (!compatibleMethods.isEmpty()) {
219       result = (IMethod)compatibleMethods.first();
220     }
221
222     return result;
223   }
224
225   private Collection JavaDoc getMethods() {
226     if (_methods == null) {
227       _methods = new HashSet JavaDoc();
228
229       Method JavaDoc[] methods = _javaClass.getDeclaredMethods();
230       for (int i = 0; i < methods.length; i++) {
231         _methods.add(new ExternalMethod(methods[i]));
232       }
233
234     }
235
236     return _methods;
237   }
238
239   public IMethod getConstructorDefinition(ISignature signature) {
240     IMethod result = null;
241
242     if (_javaClass.isInterface()) {
243       result = getInterfaceConstructor(signature);
244     }
245     else {
246       result = getClassConstructor(signature);
247     }
248
249     return result;
250   }
251
252   private IMethod getInterfaceConstructor(ISignature signature) {
253     IMethod result = null;
254
255     if (signature.getParameters().length == 0) {
256       result = new InterfaceConstructor(_javaClass);
257     }
258
259     return result;
260   }
261
262   private IMethod getClassConstructor(ISignature signature) {
263     IMethod result = null;
264
265     Constructor JavaDoc[] constructors = _javaClass.getConstructors();
266
267     for (int i = 0; i < constructors.length; i++) {
268       IMethod constructor = new ExternalConstructor(constructors[i]);
269       if (constructor.hasSameSignature(signature)) {
270         result = constructor;
271         break;
272       }
273     }
274
275     if (result == null) {
276       for (int i = 0; i < constructors.length; i++) {
277         IMethod constructor = new ExternalConstructor(constructors[i]);
278         if (constructor.hasCompatibleSignature(signature)) {
279           result = constructor;
280           break;
281         }
282       }
283     }
284
285     return result;
286   }
287
288   public boolean isCompatibleWith(IClass type) {
289     boolean result = false;
290
291     if (isPrimitive() && type.isPrimitive()) {
292       result = PrimitiveClasses.typesAreCompatible((ExternalClass)type,
293                                                      this);
294     }
295     else {
296       // check myself
297
if (type.equals(this)) {
298         result = true;
299       }
300       // check my superclass
301
else if (getSuperclass() != null && getSuperclass().isCompatibleWith(type)) {
302         result = true;
303       }
304       // check my interfaces
305
else if (_javaClass.getInterfaces().length > 0) {
306         Class JavaDoc[] interfaces = _javaClass.getInterfaces();
307         for (int i = 0; i < interfaces.length; i++) {
308           if (new ExternalClass(interfaces[i]).isCompatibleWith(type)) {
309             result = true;
310             break;
311           }
312         }
313       }
314     }
315
316     return result;
317   }
318
319   public void addImplementor(ClassDef implementor) {
320     _implementors.add(implementor);
321   }
322
323   public List JavaDoc getImplementors() {
324     return _implementors;
325   }
326
327   public void addSubclass(ClassDef subclass) {
328     _subclasses.add(subclass);
329   }
330
331   public List JavaDoc getSubclasses() {
332     return _subclasses;
333   }
334
335   public String JavaDoc getQualifiedName() {
336     return _javaClass.getName();
337   }
338
339   public boolean isPrimitive() {
340     return getJavaClass().isPrimitive();
341   }
342
343   public IClass[] getInnerClasses() {
344     Class JavaDoc[] innerJavaClasses = getJavaClass().getDeclaredClasses();
345     IClass[] result = new IClass[innerJavaClasses.length];
346
347     for (int i = 0; i < result.length; i++) {
348       result[i] = new ExternalClass(innerJavaClasses[i]);
349     }
350
351     return result;
352   }
353
354   public String JavaDoc toString() {
355      return getClass() + "[" + getQualifiedName() + "]";
356    }
357
358   public boolean equals(Object JavaDoc o) {
359     boolean result = false;
360
361     if (o instanceof ExternalClass) {
362       ExternalClass compared = (ExternalClass)o;
363       result = (getJavaClass().equals(compared.getJavaClass()));
364     }
365
366     return result;
367   }
368
369   public int hashCode() {
370     return getJavaClass().hashCode();
371   }
372
373 }
374
Popular Tags