OSDN Git Service

save
[jcfa/jcfa.git] / jcfa / src / jp / igapyon / jcfa / JavaClassFileAnalyzer.java
index 2d98765..2740724 100644 (file)
@@ -1,35 +1,78 @@
 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
@@ -37,37 +80,69 @@ public class JavaClassFileAnalyzer {
                }\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
@@ -78,7 +153,7 @@ public class JavaClassFileAnalyzer {
                        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