1 2 29 package com.puppycrawl.tools.checkstyle.checks.usage.transmogrify; 30 31 32 33 import java.lang.reflect.Constructor ; 34 import java.lang.reflect.Field ; 35 import java.lang.reflect.Method ; 36 import java.util.ArrayList ; 37 import java.util.Collection ; 38 import java.util.HashSet ; 39 import java.util.Iterator ; 40 import java.util.List ; 41 import java.util.Set ; 42 import java.util.SortedSet ; 43 import java.util.TreeSet ; 44 45 47 public class ExternalClass extends ExternalDefinition implements IClass { 48 private Class _javaClass; 49 50 private List _subclasses; 51 private List _implementors; 52 53 private Set _methods; 54 55 public ExternalClass(Class javaClass) { 56 _javaClass = javaClass; 57 _subclasses = new ArrayList (); 58 _implementors = new ArrayList (); 59 } 60 61 public Class getJavaClass() { 62 return _javaClass; 63 } 64 65 public String getName() { 66 return getLocalName(); 67 } 68 69 private String getLocalName() { 70 String fullName = _javaClass.getName(); 71 return fullName.substring(fullName.lastIndexOf(".") + 1); 72 } 73 74 public IClass getSuperclass() { 75 IClass result = null; 76 Class javaSuperclass = _javaClass.getSuperclass(); 77 78 if (javaSuperclass != null) { 79 result = new ExternalClass(javaSuperclass); 80 } 81 else { 82 if (_javaClass.isInterface()) { 83 result = new ExternalClass(Object .class); 87 } 88 } 89 90 return result; 91 } 92 93 public IClass[] getInterfaces() { 94 Class [] javaInterfaces = _javaClass.getInterfaces(); 95 96 IClass[] result = new IClass[javaInterfaces.length]; 97 98 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 name) { 107 IClass result = null; 108 109 String qualifiedName = getQualifiedName() + "$" + name; 110 111 Class [] classes = getJavaClass().getClasses(); 112 for (int i = 0; i < classes.length; i++) { 113 String 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 public IVariable getVariableDefinition(String name) { 126 IVariable result = null; 127 Field javaField = null; 128 129 try { 130 javaField = _javaClass.getDeclaredField(name); 131 } 132 catch (NoSuchFieldException ignoreMe) {} 133 134 if (javaField == null) { 135 Class [] 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 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 name, 157 ISignature signature) { 158 IMethod result = null; 159 160 if (name.equals(getName())) { 161 result = getConstructorDefinition(signature); 162 } 163 else { 164 Method [] 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 name, ISignature signature) { 203 IMethod result = null; 204 205 SortedSet compatibleMethods 206 = new TreeSet (new MethodSpecificityComparator()); 207 208 Iterator 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 getMethods() { 226 if (_methods == null) { 227 _methods = new HashSet (); 228 229 Method [] 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 [] 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 if (type.equals(this)) { 298 result = true; 299 } 300 else if (getSuperclass() != null && getSuperclass().isCompatibleWith(type)) { 302 result = true; 303 } 304 else if (_javaClass.getInterfaces().length > 0) { 306 Class [] 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 getImplementors() { 324 return _implementors; 325 } 326 327 public void addSubclass(ClassDef subclass) { 328 _subclasses.add(subclass); 329 } 330 331 public List getSubclasses() { 332 return _subclasses; 333 } 334 335 public String getQualifiedName() { 336 return _javaClass.getName(); 337 } 338 339 public boolean isPrimitive() { 340 return getJavaClass().isPrimitive(); 341 } 342 343 public IClass[] getInnerClasses() { 344 Class [] 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 toString() { 355 return getClass() + "[" + getQualifiedName() + "]"; 356 } 357 358 public boolean equals(Object 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 |