1. /*
  2. * Copyright 2001-2002,2004 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 org.apache.tools.ant.taskdefs.optional.sitraka.bytecode;
  18. import java.io.DataInputStream;
  19. import java.io.IOException;
  20. import java.io.InputStream;
  21. import org.apache.tools.ant.taskdefs.optional.depend.constantpool.ClassCPInfo;
  22. import org.apache.tools.ant.taskdefs.optional.depend.constantpool.ConstantPool;
  23. import org.apache.tools.ant.taskdefs.optional.depend.constantpool.Utf8CPInfo;
  24. import org.apache.tools.ant.taskdefs.optional.sitraka.bytecode.attributes.AttributeInfo;
  25. /**
  26. * Object representing a class.
  27. *
  28. * Information are kept to the strict minimum for JProbe reports so
  29. * that not too many objects are created for a class, otherwise the
  30. * JVM can quickly run out of memory when analyzing a great deal of
  31. * classes and keeping them in memory for global analysis.
  32. *
  33. */
  34. public final class ClassFile {
  35. private MethodInfo[] methods;
  36. private String sourceFile;
  37. private String fullname;
  38. private int access_flags;
  39. public ClassFile(InputStream is) throws IOException {
  40. DataInputStream dis = new DataInputStream(is);
  41. ConstantPool constantPool = new ConstantPool();
  42. /* int magic = */ dis.readInt(); // 0xCAFEBABE
  43. /* int minor = */ dis.readShort();
  44. /* int major = */ dis.readShort();
  45. constantPool.read(dis);
  46. constantPool.resolve();
  47. // class information
  48. access_flags = dis.readShort();
  49. int this_class = dis.readShort();
  50. fullname = ((ClassCPInfo) constantPool.getEntry(this_class)).getClassName().replace('/', '.');
  51. /* int super_class = */ dis.readShort();
  52. // skip interfaces...
  53. int count = dis.readShort();
  54. dis.skipBytes(count * 2); // short
  55. // skip fields...
  56. int numFields = dis.readShort();
  57. for (int i = 0; i < numFields; i++) {
  58. // 3 short: access flags, name index, descriptor index
  59. dis.skip(2 * 3);
  60. // attribute list...
  61. int attributes_count = dis.readUnsignedShort();
  62. for (int j = 0; j < attributes_count; j++) {
  63. dis.skipBytes(2); // skip attr_id (short)
  64. int len = dis.readInt();
  65. dis.skipBytes(len);
  66. }
  67. }
  68. // read methods
  69. int method_count = dis.readShort();
  70. methods = new MethodInfo[method_count];
  71. for (int i = 0; i < method_count; i++) {
  72. methods[i] = new MethodInfo();
  73. methods[i].read(constantPool, dis);
  74. }
  75. // get interesting attributes.
  76. int attributes_count = dis.readUnsignedShort();
  77. for (int j = 0; j < attributes_count; j++) {
  78. int attr_id = dis.readShort();
  79. int len = dis.readInt();
  80. String attr_name = Utils.getUTF8Value(constantPool, attr_id);
  81. if (AttributeInfo.SOURCE_FILE.equals(attr_name)) {
  82. int name_index = dis.readShort();
  83. sourceFile = ((Utf8CPInfo) constantPool.getEntry(name_index)).getValue();
  84. } else {
  85. dis.skipBytes(len);
  86. }
  87. }
  88. }
  89. public int getAccess() {
  90. return access_flags;
  91. }
  92. public String getSourceFile() {
  93. return sourceFile;
  94. }
  95. public MethodInfo[] getMethods() {
  96. return methods;
  97. }
  98. public String getFullName() {
  99. return fullname;
  100. }
  101. public String getName() {
  102. String name = getFullName();
  103. int pos = name.lastIndexOf('.');
  104. if (pos == -1) {
  105. return "";
  106. }
  107. return name.substring(pos + 1);
  108. }
  109. public String getPackage() {
  110. String name = getFullName();
  111. int pos = name.lastIndexOf('.');
  112. if (pos == -1) {
  113. return "";
  114. }
  115. return name.substring(0, pos);
  116. }
  117. }