package jp.igapyon.jcfa;\r
\r
+import java.io.File;\r
import java.io.IOException;\r
\r
import jp.igapyon.jcfa.util.JcfaUtil;\r
+import jp.igapyon.jcfa.util.JcfaWriteUtil;\r
+import jp.igapyon.jcfa.vo.JcfaClass;\r
+import jp.igapyon.jcfa.vo.JcfaField;\r
+import jp.igapyon.jcfa.vo.JcfaMethod;\r
+import jp.igapyon.jcfa.vo.JcfaUnit;\r
\r
import org.apache.bcel.Constants;\r
-/**\r
- * Apache Jakarta BCELを用いたクラスファイル(バイトコード)解析サンプル\r
- */\r
import org.apache.bcel.classfile.ClassFormatException;\r
import org.apache.bcel.classfile.ClassParser;\r
import org.apache.bcel.classfile.Code;\r
+import org.apache.bcel.classfile.ConstantValue;\r
import org.apache.bcel.classfile.Field;\r
import org.apache.bcel.classfile.JavaClass;\r
import org.apache.bcel.classfile.Method;\r
\r
public class JavaClassFileAnalyzer {\r
- private static final String CLASS_MODULE = "./bin/test/TestJavaClass001.class";\r
+ protected JcfaUnit jcfaUnit = new JcfaUnit();\r
\r
public static final void main(final String[] args) {\r
- new JavaClassFileAnalyzer().process();\r
+ new JavaClassFileAnalyzer().parseDir(new File("./bin/test"));\r
}\r
\r
- private final void process() {\r
+ private void parseDir(final File dir) {\r
+ final File[] files = dir.listFiles();\r
+ if (files == null) {\r
+ return;\r
+ }\r
+ for (File file : files) {\r
+ if (file.isDirectory()) {\r
+ parseDir(file);\r
+ }\r
+ if (file.isFile()) {\r
+ if (file.getName().endsWith(".class")) {\r
+ new JavaClassFileAnalyzer().process(file, new File(\r
+ "./testJavaClass/output"));\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ private final void process(final File inputFile, final File outputDir) {\r
try {\r
- final JavaClass jc = new ClassParser(CLASS_MODULE).parse();\r
- System.out.println("Classname : " + jc.getClassName());\r
- System.out.println("Parent class: " + jc.getSuperclassName());\r
+ final JavaClass jc = new ClassParser(inputFile.getCanonicalPath())\r
+ .parse();\r
+ final JcfaClass jcfaClass = new JcfaClass();\r
+ jcfaUnit.getClassList().add(jcfaClass);\r
+\r
+ jcfaClass.setName(jc.getClassName());\r
+ jcfaClass.setExtendsName(jc.getSuperclassName());\r
+\r
+ jcfaClass.getComment().getCommentList()\r
+ .add("TODO import func. is missing.");\r
+\r
+ final String[] split = jc.getClassName().split("\\.");\r
+ File actualyTargetDir = outputDir;\r
+ if (split.length > 1) {\r
+ for (int index = 0; index < split.length - 1; index++) {\r
+ actualyTargetDir = new File(outputDir, split[index]);\r
+ actualyTargetDir.mkdirs();\r
+ }\r
+ }\r
+\r
+ analyzeFields(jc, jcfaClass);\r
+ analyzeMethods(jc, jcfaClass);\r
+\r
+ jcfaUnit.setTargetFile(new File(actualyTargetDir,\r
+ split[split.length - 1] + ".jcfa"));\r
\r
- analyzeFields(jc);\r
- analyzeMethods(jc);\r
+ JcfaWriteUtil.writeToFile(jcfaUnit);\r
} catch (ClassFormatException e) {\r
e.printStackTrace();\r
} catch (IOException e) {\r
}\r
}\r
\r
- private void analyzeFields(final JavaClass jc) {\r
+ private void analyzeFields(final JavaClass jc, final JcfaClass jcfaClass) {\r
final org.apache.bcel.classfile.Field[] fields = jc.getFields();\r
for (int indexField = 0; indexField < fields.length; indexField++) {\r
final Field field = fields[indexField];\r
- analyzeField(jc, field);\r
+ analyzeField(jc, field, jcfaClass);\r
}\r
}\r
\r
- private void analyzeField(final JavaClass jc, final Field field) {\r
- System.out.println(" Field:" + field.getName());\r
+ private void analyzeField(final JavaClass jc, final Field field,\r
+ final JcfaClass jcfaClass) {\r
+ final JcfaField jcfaField = new JcfaField();\r
+ jcfaField.setName(field.getName());\r
+ jcfaClass.getFieldList().add(jcfaField);\r
+\r
+ // TODO type should be more collect.\r
+ jcfaField.setType(field.getType().toString());\r
+\r
String access = "";\r
access += field.isPublic() ? "public " : "";\r
+ access += field.isProtected() ? "protected " : "";\r
+ access += field.isPrivate() ? "private " : "";\r
access += field.isAbstract() ? "abstract " : "";\r
access += field.isStatic() ? "static " : "";\r
+ access += field.isVolatile() ? "volatile " : "";\r
access += field.isFinal() ? "final " : "";\r
- System.out.println(" " + access);\r
- System.out.println(" " + field.getSignature());\r
+ jcfaField.setAccess(access);\r
+\r
+ String constValue = null;\r
+ final ConstantValue cv = field.getConstantValue();\r
+ if (cv != null) {\r
+ jcfaField.setConstantValue(jc.getConstantPool().getConstantString(\r
+ cv.getConstantValueIndex(), Constants.CONSTANT_String));\r
+\r
+ jcfaField\r
+ .getComment()\r
+ .getCommentList()\r
+ .add("FIXME other type support is missing. Now only String.");\r
+\r
+ jcfaField.setConstantValueType(Constants.CONSTANT_String);\r
+ }\r
+\r
+ System.out.println(" " + access + field.getType().toString() + " "\r
+ + field.getName()\r
+ + (constValue == null ? "" : " = \"" + constValue + "\""));\r
}\r
\r
- private void analyzeMethods(final JavaClass jc) throws IOException {\r
+ private void analyzeMethods(final JavaClass jc, final JcfaClass jcfaClass)\r
+ throws IOException {\r
final org.apache.bcel.classfile.Method[] methods = jc.getMethods();\r
for (int indexMethod = 0; indexMethod < methods.length; indexMethod++) {\r
final Method method = methods[indexMethod];\r
- analyzeMethod(jc, method);\r
+ analyzeMethod(jc, method, jcfaClass);\r
\r
}\r
}\r
\r
- private void analyzeMethod(final JavaClass jc, final Method method)\r
- throws IOException {\r
- System.out.println(" Method:" + method.getName());\r
+ private void analyzeMethod(final JavaClass jc, final Method method,\r
+ final JcfaClass jcfaClass) throws IOException {\r
+ final JcfaMethod jcfaMethod = new JcfaMethod();\r
+ jcfaClass.getMethodList().add(jcfaMethod);\r
+\r
+ jcfaMethod.setName(method.getName());\r
+\r
final Code code = method.getCode();\r
if (code == null) {\r
return;\r
final short opcode = JcfaUtil.byte2UnsignedByte(codes[pc]);\r
short operands = Constants.NO_OF_OPERANDS[opcode];\r
if (operands < 0) {\r
- System.out.println(" TODO negative value:"\r
+ System.err.println(" TODO negative value:"\r
+ Constants.OPCODE_NAMES[opcode] + ": " + operands);\r
// break;\r
}\r