Clover coverage report - Dependency Finder
Coverage timestamp: Mon Nov 29 2010 15:00:50 PST
file stats: LOC: 522   Methods: 48
NCLOC: 372   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
Classfile.java 66.7% 79.9% 89.6% 78.2%
coverage coverage
 1    /*
 2    * Copyright (c) 2001-2009, Jean Tessier
 3    * All rights reserved.
 4    *
 5    * Redistribution and use in source and binary forms, with or without
 6    * modification, are permitted provided that the following conditions
 7    * are met:
 8    *
 9    * * Redistributions of source code must retain the above copyright
 10    * notice, this list of conditions and the following disclaimer.
 11    *
 12    * * Redistributions in binary form must reproduce the above copyright
 13    * notice, this list of conditions and the following disclaimer in the
 14    * documentation and/or other materials provided with the distribution.
 15    *
 16    * * Neither the name of Jean Tessier nor the names of his contributors
 17    * may be used to endorse or promote products derived from this software
 18    * without specific prior written permission.
 19    *
 20    * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 21    * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 22    * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 23    * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
 24    * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 25    * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 26    * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 27    * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 28    * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 29    * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 30    * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 31    */
 32   
 33    package com.jeantessier.classreader.impl;
 34   
 35    import com.jeantessier.classreader.ClassfileLoader;
 36    import com.jeantessier.classreader.Visitor;
 37    import org.apache.log4j.Logger;
 38   
 39    import java.io.DataInput;
 40    import java.io.IOException;
 41    import java.util.Collection;
 42    import java.util.Iterator;
 43    import java.util.LinkedList;
 44   
 45    public class Classfile implements com.jeantessier.classreader.Classfile {
 46    private static final int ACC_PUBLIC = 0x0001;
 47    private static final int ACC_FINAL = 0x0010;
 48    private static final int ACC_SUPER = 0x0020;
 49    private static final int ACC_INTERFACE = 0x0200;
 50    private static final int ACC_ABSTRACT = 0x0400;
 51    private static final int ACC_SYNTHETIC = 0x1000;
 52    private static final int ACC_ANNOTATION = 0x2000;
 53    private static final int ACC_ENUM = 0x4000;
 54   
 55    private ClassfileLoader loader;
 56   
 57    private int magicNumber;
 58    private int minorVersion;
 59    private int majorVersion;
 60    private ConstantPool constantPool;
 61    private int accessFlag;
 62    private int classIndex;
 63    private int superclassIndex;
 64    private Collection<Class_info> interfaces = new LinkedList<Class_info>();
 65    private Collection<Field_info> fields = new LinkedList<Field_info>();
 66    private Collection<Method_info> methods = new LinkedList<Method_info>();
 67    private Collection<Attribute_info> attributes = new LinkedList<Attribute_info>();
 68   
 69    /**
 70    * Parses the input stream and extracts the class description.
 71    * You should only call this constructor from a ClassfileLoader.
 72    */
 73  1304 public Classfile(ClassfileLoader loader, DataInput in) throws IOException {
 74  1304 this(loader, in, new AttributeFactory());
 75    }
 76   
 77  1304 public Classfile(ClassfileLoader loader, DataInput in, AttributeFactory attributeFactory) throws IOException {
 78  1304 this.loader = loader;
 79   
 80  1304 magicNumber = in.readInt();
 81  1304 Logger.getLogger(getClass()).debug("magic number = 0x" + Integer.toHexString(magicNumber).toUpperCase());
 82   
 83  1304 if (magicNumber != 0xCAFEBABE) {
 84  0 throw new IOException("Bad magic number");
 85    }
 86   
 87    // Reading the file format's version number
 88  1304 minorVersion = in.readUnsignedShort();
 89  1304 Logger.getLogger(getClass()).debug("minor version = " + minorVersion);
 90  1304 majorVersion = in.readUnsignedShort();
 91  1304 Logger.getLogger(getClass()).debug("major version = " + majorVersion);
 92   
 93    // Reading the constant pool
 94  1304 Logger.getLogger(getClass()).debug("Reading the constant pool ...");
 95  1304 constantPool = new ConstantPool(this, in);
 96  1304 Logger.getLogger(getClass()).debug(constantPool);
 97   
 98    // Skipping the access flag
 99  1304 accessFlag = in.readUnsignedShort();
 100  1304 Logger.getLogger(getClass()).debug("accessFlag = " + accessFlag);
 101   
 102    // Retrieving this class's name
 103  1304 classIndex = in.readUnsignedShort();
 104  1304 Logger.getLogger(getClass()).debug("thisClass = " + classIndex + " (" + getClassName() + ")");
 105   
 106    // Retrieving this class's superclass
 107  1304 superclassIndex = in.readUnsignedShort();
 108  1304 Logger.getLogger(getClass()).debug("superclass = " + superclassIndex + " (" + getSuperclassName() + ")");
 109   
 110    // Retrieving the inferfaces
 111  1304 int interfaceCount = in.readUnsignedShort();
 112  1304 Logger.getLogger(getClass()).debug("Reading " + interfaceCount + " interface(s)");
 113  1304 for (int i=0; i<interfaceCount; i++) {
 114  77 Class_info interfaceInfo = (Class_info) constantPool.get(in.readUnsignedShort());
 115  77 Logger.getLogger(getClass()).debug(" " + interfaceInfo.getName());
 116  77 interfaces.add(interfaceInfo);
 117    }
 118   
 119    // Retrieving the fields
 120  1304 int fieldCount = in.readUnsignedShort();
 121  1304 Logger.getLogger(getClass()).debug("Reading " + fieldCount + " field(s)");
 122  1304 for (int i=0; i<fieldCount; i++) {
 123  1974 Logger.getLogger(getClass()).debug("Field " + i + ":");
 124  1974 fields.add(new Field_info(this, in));
 125    }
 126   
 127    // Retrieving the methods
 128  1304 int methodCount = in.readUnsignedShort();
 129  1304 Logger.getLogger(getClass()).debug("Reading " + methodCount + " method(s)");
 130  1304 for (int i=0; i<methodCount; i++) {
 131  3045 Logger.getLogger(getClass()).debug("Method " + i + ":");
 132  3045 methods.add(new Method_info(this, in));
 133    }
 134   
 135    // Retrieving the attributes
 136  1304 int attributeCount = in.readUnsignedShort();
 137  1304 Logger.getLogger(getClass()).debug("Reading " + attributeCount + " class attribute(s)");
 138  1304 for (int i=0; i<attributeCount; i++) {
 139  1034 Logger.getLogger(getClass()).debug("Attribute " + i + ":");
 140  1034 attributes.add(attributeFactory.create(constantPool, this, in));
 141    }
 142    }
 143   
 144    /**
 145    * For testing only
 146    */
 147  16 Classfile(ClassfileLoader loader, ConstantPool constantPool, int accessFlag, int classIndex, int superclassIndex, Iterable<Class_info> interfaces, Iterable<Field_info> fields, Iterable<Method_info> methods, Iterable<Attribute_info> attributes) {
 148  16 this.loader = loader;
 149  16 this.constantPool = constantPool;
 150  16 this.accessFlag = accessFlag;
 151  16 this.classIndex = classIndex;
 152  16 this.superclassIndex = superclassIndex;
 153   
 154  16 for (Class_info interfaceInfo : interfaces) {
 155  0 this.interfaces.add(interfaceInfo);
 156    }
 157   
 158  16 for (Field_info field : fields) {
 159  1 this.fields.add(field);
 160    }
 161   
 162  16 for (Method_info method : methods) {
 163  1 this.methods.add(method);
 164    }
 165   
 166  16 for (Attribute_info attribute : attributes) {
 167  2 this.attributes.add(attribute);
 168    }
 169    }
 170   
 171  914 public ClassfileLoader getLoader() {
 172  914 return loader;
 173    }
 174   
 175  16 public int getMagicNumber() {
 176  16 return magicNumber;
 177    }
 178   
 179  16 public int getMinorVersion() {
 180  16 return minorVersion;
 181    }
 182   
 183  16 public int getMajorVersion() {
 184  16 return majorVersion;
 185    }
 186   
 187  228624 public ConstantPool getConstantPool() {
 188  228624 return constantPool;
 189    }
 190   
 191  12227 public int getAccessFlag() {
 192  12227 return accessFlag;
 193    }
 194   
 195  28766 public int getClassIndex() {
 196  28766 return classIndex;
 197    }
 198   
 199  28766 public Class_info getRawClass() {
 200  28766 return (Class_info) getConstantPool().get(getClassIndex());
 201    }
 202   
 203  12384 public String getClassName() {
 204  12384 return getRawClass().getName();
 205    }
 206   
 207  172 public String getPackageName() {
 208  172 return getRawClass().getPackageName();
 209    }
 210   
 211  16194 public String getSimpleName() {
 212  16194 return getRawClass().getSimpleName();
 213    }
 214   
 215  10288 public int getSuperclassIndex() {
 216  10288 return superclassIndex;
 217    }
 218   
 219  4408 public Class_info getRawSuperclass() {
 220  4408 return (Class_info) getConstantPool().get(getSuperclassIndex());
 221    }
 222   
 223  4024 public String getSuperclassName() {
 224  4024 String result = "";
 225   
 226  4024 if (getSuperclassIndex() != 0) {
 227  4024 result = getRawSuperclass().getName();
 228    }
 229   
 230  4024 return result;
 231    }
 232   
 233  0 public Class_info getInterface(String name) {
 234  0 for (Class_info interfaceInfo : interfaces) {
 235  0 if (interfaceInfo.getName().equals(name)) {
 236  0 return interfaceInfo;
 237    }
 238    }
 239   
 240  0 return null;
 241    }
 242   
 243  3621 public Collection<Class_info> getAllInterfaces() {
 244  3621 return interfaces;
 245    }
 246   
 247  1464 public Collection<Field_info> getAllFields() {
 248  1464 return fields;
 249    }
 250   
 251  3884 public Field_info getField(String name) {
 252  3884 for (Field_info field : fields) {
 253  41216 if (field.getName().equals(name)) {
 254  2754 return field;
 255    }
 256    }
 257   
 258  1130 return null;
 259    }
 260   
 261  351 public com.jeantessier.classreader.Field_info locateField(String name) {
 262  351 com.jeantessier.classreader.Field_info localField = getField(name);
 263  351 if (localField != null) {
 264  1 return localField;
 265    }
 266   
 267  350 com.jeantessier.classreader.Classfile superclass = getLoader().getClassfile(getSuperclassName());
 268  350 if (superclass != null) {
 269  5 com.jeantessier.classreader.Field_info inheritedField = superclass.locateField(name);
 270  5 if (inheritedField != null && (inheritedField.isPublic() || inheritedField.isProtected() || (inheritedField.isPackage() && inheritedField.getClassfile().getPackageName().equals(superclass.getPackageName())))) {
 271  3 return inheritedField;
 272    }
 273    }
 274   
 275   
 276  347 for (com.jeantessier.classreader.Class_info interfaceInfo : getAllInterfaces()) {
 277  0 com.jeantessier.classreader.Classfile interfaceClassfile = getLoader().getClassfile(interfaceInfo.getName());
 278  0 if (interfaceClassfile != null) {
 279  0 com.jeantessier.classreader.Field_info interfaceField = interfaceClassfile.locateField(name);
 280  0 if (interfaceField != null && (interfaceField.isPublic() || interfaceField.isProtected())) {
 281  0 return interfaceField;
 282    }
 283    }
 284    }
 285   
 286  347 return null;
 287    }
 288   
 289  1271 public Collection<Method_info> getAllMethods() {
 290  1271 return methods;
 291    }
 292   
 293  3100 public Method_info getMethod(String signature) {
 294  3100 for (Method_info method : methods) {
 295  20326 if (method.getSignature().equals(signature)) {
 296  2612 return method;
 297    }
 298    }
 299   
 300  488 return null;
 301    }
 302   
 303  131 public com.jeantessier.classreader.Method_info locateMethod(String signature) {
 304  131 com.jeantessier.classreader.Method_info localMethod = getMethod(signature);
 305  131 if (localMethod != null) {
 306  1 return localMethod;
 307    }
 308   
 309  130 com.jeantessier.classreader.Classfile superclass = getLoader().getClassfile(getSuperclassName());
 310  130 if (superclass != null) {
 311  5 com.jeantessier.classreader.Method_info inheritedMethod = superclass.locateMethod(signature);
 312  5 if (inheritedMethod != null && (inheritedMethod.isPublic() || inheritedMethod.isProtected() || (inheritedMethod.isPackage() && inheritedMethod.getClassfile().getPackageName().equals(superclass.getPackageName())))) {
 313  3 return inheritedMethod;
 314    }
 315    }
 316   
 317  127 for (com.jeantessier.classreader.Class_info inferfaceInfo : getAllInterfaces()) {
 318  0 com.jeantessier.classreader.Classfile interfaceClassfile = getLoader().getClassfile(inferfaceInfo.getName());
 319  0 if (interfaceClassfile != null) {
 320  0 com.jeantessier.classreader.Method_info interfaceMethod = interfaceClassfile.locateMethod(signature);
 321  0 if (interfaceMethod != null && (interfaceMethod.isPublic() || interfaceMethod.isProtected())) {
 322  0 return interfaceMethod;
 323    }
 324    }
 325    }
 326   
 327  127 return null;
 328    }
 329   
 330  3114 public Collection<Attribute_info> getAttributes() {
 331  3114 return attributes;
 332    }
 333   
 334  2885 public boolean isPublic() {
 335  2885 return (getAccessFlag() & ACC_PUBLIC) != 0;
 336    }
 337   
 338  12 public boolean isPackage() {
 339  12 return (getAccessFlag() & ACC_PUBLIC) == 0;
 340    }
 341   
 342  2872 public boolean isFinal() {
 343  2872 return (getAccessFlag() & ACC_FINAL) != 0;
 344    }
 345   
 346  378 public boolean isSuper() {
 347  378 return (getAccessFlag() & ACC_SUPER) != 0;
 348    }
 349   
 350  3481 public boolean isInterface() {
 351  3481 return (getAccessFlag() & ACC_INTERFACE) != 0;
 352    }
 353   
 354  1817 public boolean isAbstract() {
 355  1817 return (getAccessFlag() & ACC_ABSTRACT) != 0;
 356    }
 357   
 358  18 public boolean isAnnotation() {
 359  18 return (getAccessFlag() & ACC_ANNOTATION) != 0;
 360    }
 361   
 362  20 public boolean isEnum() {
 363  20 return (getAccessFlag() & ACC_ENUM) != 0;
 364    }
 365   
 366  728 public boolean isSynthetic() {
 367  728 return isSyntheticFromAccessFlag() || isSyntheticFromAttribute();
 368    }
 369   
 370  728 private boolean isSyntheticFromAccessFlag() {
 371  728 return (getAccessFlag() & ACC_SYNTHETIC) != 0;
 372    }
 373   
 374  728 private boolean isSyntheticFromAttribute() {
 375  728 boolean result = false;
 376   
 377  728 Iterator i = getAttributes().iterator();
 378  728 while (!result && i.hasNext()) {
 379  1278 result = i.next() instanceof Synthetic_attribute;
 380    }
 381   
 382  728 return result;
 383    }
 384   
 385  1949 public boolean isDeprecated() {
 386  1949 boolean result = false;
 387   
 388  1949 Iterator i = getAttributes().iterator();
 389  1949 while (!result && i.hasNext()) {
 390  571 result = i.next() instanceof Deprecated_attribute;
 391    }
 392   
 393  1949 return result;
 394    }
 395   
 396  2 public boolean isGeneric() {
 397  2 boolean result = false;
 398   
 399  2 Iterator i = getAttributes().iterator();
 400  2 while (!result && i.hasNext()) {
 401  3 result = i.next() instanceof Signature_attribute;
 402    }
 403   
 404  2 return result;
 405    }
 406   
 407  2437 public String getDeclaration() {
 408  2437 StringBuffer result = new StringBuffer();
 409   
 410  2437 if (isPublic()) result.append("public ");
 411  6 if (isFinal()) result.append("final ");
 412   
 413  2437 if (isInterface()) {
 414  1049 result.append("interface ").append(getClassName());
 415   
 416  1049 if (getAllInterfaces().size() != 0) {
 417  96 result.append(" extends ");
 418  96 Iterator i = getAllInterfaces().iterator();
 419  96 while (i.hasNext()) {
 420  96 result.append(i.next());
 421  96 if (i.hasNext()) {
 422  0 result.append(", ");
 423    }
 424    }
 425    }
 426    } else {
 427  0 if (isAbstract()) result.append("abstract ");
 428  1388 result.append("class ").append(getClassName());
 429   
 430  1388 if (getSuperclassIndex() != 0) {
 431  1388 result.append(" extends ").append(getSuperclassName());
 432    }
 433   
 434  1388 if (getAllInterfaces().size() != 0) {
 435  96 result.append(" implements ");
 436  96 Iterator i = getAllInterfaces().iterator();
 437  96 while (i.hasNext()) {
 438  96 result.append(i.next());
 439  96 if (i.hasNext()) {
 440  0 result.append(", ");
 441    }
 442    }
 443    }
 444    }
 445   
 446  2437 return result.toString();
 447    }
 448   
 449  423 public void accept(Visitor visitor) {
 450  423 visitor.visitClassfile(this);
 451    }
 452   
 453  29 public String toString() {
 454  29 return getClassName();
 455    }
 456   
 457  3 public boolean isInnerClass() {
 458  3 return getMatchingInnerClass() != null;
 459    }
 460   
 461  0 public boolean isMemberClass() {
 462  0 boolean result = false;
 463   
 464  0 InnerClass innerClass = getMatchingInnerClass();
 465  0 if (innerClass != null) {
 466  0 result = innerClass.isMemberClass();
 467    }
 468   
 469  0 return result;
 470    }
 471   
 472  0 public boolean isLocalClass() {
 473  0 boolean result = false;
 474   
 475  0 InnerClass innerClass = getMatchingInnerClass();
 476  0 EnclosingMethod_attribute enclosingMethod = getEnclosingMethod();
 477  0 if (innerClass != null && enclosingMethod != null) {
 478  0 result = !innerClass.isAnonymousClass();
 479    }
 480   
 481  0 return result;
 482    }
 483   
 484  0 public boolean isAnonymousClass() {
 485  0 boolean result = false;
 486   
 487  0 InnerClass innerClass = getMatchingInnerClass();
 488  0 if (innerClass != null) {
 489  0 result = innerClass.isAnonymousClass();
 490    }
 491   
 492  0 return result;
 493    }
 494   
 495  3 private InnerClass getMatchingInnerClass() {
 496  3 InnerClass result = null;
 497   
 498  3 for (Attribute_info attribute : getAttributes()) {
 499  2 if (attribute instanceof InnerClasses_attribute) {
 500  2 for (InnerClass innerClass : ((InnerClasses_attribute) attribute).getInnerClasses()) {
 501  2 if (innerClass.getInnerClassInfo().equals(getClassName())) {
 502  1 result = innerClass;
 503    }
 504    }
 505    }
 506    }
 507   
 508  3 return result;
 509    }
 510   
 511  0 private EnclosingMethod_attribute getEnclosingMethod() {
 512  0 EnclosingMethod_attribute result = null;
 513   
 514  0 for (Attribute_info attribute : getAttributes()) {
 515  0 if (attribute instanceof EnclosingMethod_attribute) {
 516  0 result = (EnclosingMethod_attribute) attribute;
 517    }
 518    }
 519   
 520  0 return result;
 521    }
 522    }