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
-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
- protected JcfaUnit jcfaUnit = new JcfaUnit();\r
-\r
public static final void main(final String[] args) {\r
new JavaClassFileAnalyzer().parseDir(new File("./bin/test"));\r
+ new JavaClassFileAnalyzer().parseDir(new File(\r
+ "./bin/jp/igapyon/jcfa/vo"));\r
}\r
\r
private void parseDir(final File dir) {\r
}\r
\r
private final void process(final File inputFile, final File outputDir) {\r
- try {\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
- JcfaWriteUtil.writeToFile(jcfaUnit);\r
- } catch (ClassFormatException e) {\r
- e.printStackTrace();\r
- } catch (IOException e) {\r
- e.printStackTrace();\r
- }\r
- }\r
-\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, jcfaClass);\r
- }\r
- }\r
-\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
- 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
- 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, 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, jcfaClass);\r
-\r
- }\r
+ final JcfaUnit jcfaUnit = new JcfaParser().parseUnit(inputFile,\r
+ outputDir);\r
}\r
\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
- }\r
-\r
- final byte[] codes = code.getCode();\r
- for (int pc = 0; pc < codes.length; pc++) {\r
- final short opcode = JcfaUtil.byte2UnsignedByte(codes[pc]);\r
- short operands = Constants.NO_OF_OPERANDS[opcode];\r
- if (operands < 0) {\r
- System.err.println(" TODO negative value:"\r
- + Constants.OPCODE_NAMES[opcode] + ": " + operands);\r
- // break;\r
- }\r
-\r
- switch (opcode) {\r
- case Constants.RETURN: {\r
- System.out.println(" " + pc + ": "\r
- + Constants.OPCODE_NAMES[opcode]);\r
- break;\r
- }\r
- case Constants.GETSTATIC: {\r
- System.out.println(" "\r
- + pc\r
- + ": "\r
- + Constants.OPCODE_NAMES[opcode]\r
- + ": "\r
- + JcfaUtil.getConstantFieldrefString(jc, codes[pc + 1],\r
- codes[pc + 2]));\r
- break;\r
- }\r
- case Constants.LDC: {\r
- System.out.println(" " + pc + ": "\r
- + Constants.OPCODE_NAMES[opcode] + ": "\r
- + JcfaUtil.getConstantString(jc, codes[pc + 1]));\r
- }\r
- break;\r
- case Constants.INVOKEVIRTUAL:\r
- case Constants.INVOKESPECIAL: {\r
- final int operand = JcfaUtil.byte2UnsignedShort(codes[pc + 1],\r
- codes[pc + 2]);\r
- System.out.println(" " + pc + ": "\r
- + Constants.OPCODE_NAMES[opcode] + ": "\r
- + JcfaUtil.getConstantMethodRefString(jc, operand));\r
- }\r
- break;\r
- case Constants.LOOKUPSWITCH:\r
- int result = JcfaUtil.byte2Int(codes[pc + 1], codes[pc + 2],\r
- codes[pc + 3], codes[pc + 4]);\r
- System.out.println(" TODO skipping bytes: " + (result));\r
-\r
- int lookupOp = pc + 5;\r
-\r
- short diff = JcfaUtil.byte2UnsignedByte(codes[lookupOp++]);\r
- System.out.println(" TODO skipping bytes: " + (diff));\r
-\r
- int loopCount = JcfaUtil\r
- .byte2Int(codes[lookupOp++], codes[lookupOp++],\r
- codes[lookupOp++], codes[lookupOp++]);\r
- for (int index = 0; index < loopCount; index++) {\r
- System.out.println(" "\r
- + JcfaUtil.byte2Int(codes[lookupOp++],\r
- codes[lookupOp++], codes[lookupOp++],\r
- codes[lookupOp++])\r
- + ":"\r
- + (JcfaUtil.byte2Int(codes[lookupOp++],\r
- codes[lookupOp++], codes[lookupOp++],\r
- codes[lookupOp++]) + pc));\r
- }\r
-\r
- short diff2 = JcfaUtil.byte2UnsignedByte(codes[lookupOp++]);\r
- System.out.println(" TODO skipping bytes: " + (diff2));\r
-\r
- operands += (lookupOp - pc);\r
-\r
- break;\r
- default: {\r
- System.out.println(" " + pc + ": "\r
- + Constants.OPCODE_NAMES[opcode] + " (" + operands\r
- + ")");\r
- }\r
- break;\r
- }\r
- pc += operands;\r
- }\r
- }\r
}
\ No newline at end of file