diff --git a/.classpath b/.classpath index 2bda701..c36a269 100644 --- a/.classpath +++ b/.classpath @@ -1,8 +1,10 @@ + + diff --git a/docs/ASM_UML.png b/docs/ASM_UML.png new file mode 100644 index 0000000..e142d10 Binary files /dev/null and b/docs/ASM_UML.png differ diff --git a/docs/ASM_UML.uxf b/docs/ASM_UML.uxf new file mode 100644 index 0000000..1ebcb83 --- /dev/null +++ b/docs/ASM_UML.uxf @@ -0,0 +1,227 @@ + + + 10 + + UMLClass + + 900 + 280 + 650 + 140 + + ClassMethodVisitor +-- +-out: OutputStream +-firstMethod: boolean +-- ++visitMethod(int access, String name, String desc, String signature, String[] exceptions): MethodVisitor +~addAccessLevel(int access): void +~addReturnType(String desc): void +~addArguments(String desc): void +-- + + + + + UMLClass + + 600 + 80 + 440 + 190 + + Relations +-- +~includedELements = new ArrayList<String>(): List<String> +~childParrent = new HashMap<String, String>(): Map<String, String> +~interfaces = new ArrayList<String[]>(): List<String[]> +-- ++addElement(String element): void ++addChildParrentRelation(String child, String parrent): void ++addInterfaceRelation(String clazz, String interfase): void ++getChildParentIncludedRelations(): Map<String, String> ++getIncludedInterfaceRelations(): List<String[]> +-- + + + + + UMLClass + + 900 + 430 + 650 + 150 + + ClassDeclarationVisitor +-- +-out: OutputStream +-relations: Relations +-- ++visit(int version, int access, String name, String signature, String superName, String[] interfaces): void +-addInterfaceName(String thisName, String[] interfaces): void +-addSuperName(String thisName, String superName): void ++getCleanName(String s): String +-- + + + + + UMLClass + + 900 + 590 + 580 + 90 + + ClassFieldVisitor +-- +-out: OutputStream +-- ++visitField(int access, String name, String desc, String signature, Object value): FieldVisitor ++getAccessLevel(int access): String +-- + + + + + UMLClass + + 0 + 410 + 630 + 110 + + Main +-- ++ CLASSES : String[] +-- ++main(String[] args) : void +-writeChildParrentRelations(Map<String, String> childParrentRelations, OutputStream out) : void +-writeInterfaceRelations(List<String[]> interfaces, OutputStream out) : void +-- + + + + + Relation + + 620 + 320 + 300 + 150 + + lt=<- + 280.0;10.0;200.0;10.0;200.0;130.0;10.0;130.0 + + + Relation + + 620 + 470 + 300 + 30 + + lt=<- + 280.0;10.0;10.0;10.0 + + + Relation + + 620 + 490 + 300 + 160 + + lt=<- + 280.0;140.0;200.0;140.0;200.0;10.0;10.0;10.0 + + + Relation + + 450 + 190 + 170 + 240 + + lt=<- + 150.0;10.0;10.0;10.0;10.0;220.0 + + + Relation + + 690 + 260 + 230 + 140 + + lt=<- + 10.0;10.0;10.0;120.0;210.0;120.0 + + + Relation + + 690 + 370 + 230 + 200 + + lt=- + 10.0;10.0;10.0;180.0;210.0;180.0 + + + Relation + + 690 + 540 + 230 + 130 + + lt=- + 10.0;10.0;10.0;110.0;210.0;110.0 + + + UMLClass + + 1770 + 450 + 100 + 40 + + ClassVisitor + + + + Relation + + 1540 + 330 + 250 + 140 + + lt=<<- + 230.0;120.0;140.0;120.0;140.0;10.0;10.0;10.0 + + + Relation + + 1540 + 460 + 250 + 30 + + lt=<<- + 230.0;10.0;10.0;10.0 + + + Relation + + 1470 + 480 + 320 + 160 + + lt=<<- + 300.0;10.0;210.0;10.0;210.0;140.0;10.0;140.0 + + diff --git a/docs/ASM_UML_Generated.png b/docs/ASM_UML_Generated.png new file mode 100644 index 0000000..8a71402 Binary files /dev/null and b/docs/ASM_UML_Generated.png differ diff --git a/docs/UML.uxf b/docs/UML.uxf deleted file mode 100644 index 356d2be..0000000 --- a/docs/UML.uxf +++ /dev/null @@ -1,287 +0,0 @@ - - - 10 - - UMLClass - - 490 - 150 - 210 - 50 - - Main --- -+ static void main(String[] args) - - - - UMLClass - - 150 - 530 - 220 - 50 - - Class --- -AbstractJavaStructre superClass - - - - UMLClass - - 230 - 400 - 270 - 80 - - /AbstractJavaStructure/ --- -List<AbstractJavaElement> subElements -List<Interface> implements - - - - - - - - UMLClass - - 380 - 530 - 100 - 30 - - Interface --- - - - - - UMLClass - - 690 - 470 - 70 - 30 - - Field --- - - - - - UMLClass - - 650 - 530 - 240 - 50 - - Method --- -List<AbstractJavaThing> arguments - - - - UMLClass - - 1090 - 380 - 110 - 50 - - <<interface>> -IModifer --- - - - - - UMLClass - - 980 - 470 - 100 - 30 - - FinalModifier - - - - UMLClass - - 1090 - 470 - 100 - 30 - - StaticModifier - - - - UMLClass - - 1200 - 470 - 140 - 30 - - SynchronizedModifier - - - - UMLClass - - 690 - 390 - 160 - 50 - - /AbstractJavaElement/ --- -AbstractJavaThing type - - - - - - Relation - - 420 - 470 - 30 - 80 - - lt=<<- - 10.0;10.0;10.0;60.0 - - - Relation - - 270 - 470 - 30 - 80 - - lt=<<- - 10.0;10.0;10.0;60.0 - - - Relation - - 720 - 430 - 30 - 60 - - lt=<<- - 10.0;10.0;10.0;40.0 - - - Relation - - 790 - 430 - 30 - 120 - - lt=<<- - 10.0;10.0;10.0;100.0 - - - UMLClass - - 510 - 280 - 160 - 90 - - /AbstractJavaThing/ --- -String name -List<IModifer> modifiers - - - - - - - Relation - - 660 - 320 - 120 - 90 - - lt=<<- - 10.0;10.0;100.0;10.0;100.0;70.0 - - - Relation - - 350 - 320 - 180 - 100 - - lt=<<- - 160.0;10.0;10.0;10.0;10.0;80.0 - - - UMLClass - - 980 - 520 - 100 - 30 - - PrivateModifier - - - - UMLClass - - 1090 - 520 - 100 - 30 - - PublicModifier - - - - UMLClass - - 1200 - 520 - 140 - 30 - - ProtectedModifier - - - - UMLClass - - 980 - 560 - 170 - 30 - - ProtectedPrivateModifier - - - - UMLClass - - 1160 - 560 - 170 - 30 - - AbstractModifier - - - diff --git a/docs/UML_1_3_Generated.png b/docs/UML_1_3_Generated.png new file mode 100644 index 0000000..518cefc Binary files /dev/null and b/docs/UML_1_3_Generated.png differ diff --git a/docs/UML_1__3.png b/docs/UML_1__3.png new file mode 100644 index 0000000..832fcdd Binary files /dev/null and b/docs/UML_1__3.png differ diff --git a/docs/UML_1__3.uxf b/docs/UML_1__3.uxf new file mode 100644 index 0000000..e16e17b --- /dev/null +++ b/docs/UML_1__3.uxf @@ -0,0 +1,157 @@ + + + 10 + + UMLClass + + 400 + 370 + 200 + 70 + + <<interface>> +IWatcher +-- +handleEvent(String fileName) + + + + + UMLClass + + 290 + 510 + 200 + 50 + + HtmlWatcher +-- +handleEvent(String fileName) + + + + + UMLClass + + 510 + 510 + 200 + 50 + + TxtWatcher +-- +handleEvent(String fileName) + + + + + UMLClass + + 310 + 60 + 370 + 240 + + AppLauncher +-- +-watcher: WatchService +-dir: Path +-stop: boolean +-processes: List<Process> +-- +~AppLauncher(Path dir): ctor ++run(): void +#clearEverything(): void ++stopGracefully(): void ++isRunning(): boolean ++getApplicationsCount(): int ++handleDirectoryEvent(String eventName, Path file): void ++main(String[] args): void +-- + + + + + Relation + + 490 + 290 + 30 + 100 + + lt=<- + 10.0;80.0;10.0;10.0 + + + Relation + + 380 + 430 + 80 + 100 + + lt=<<. + 60.0;10.0;10.0;80.0 + + + Relation + + 540 + 430 + 80 + 100 + + lt=<<. + 10.0;10.0;60.0;80.0 + + + UMLClass + + 740 + 510 + 200 + 50 + + TextPrinterWatcher +-- +handleEvent(String fileName) + + + + + UMLClass + + 60 + 510 + 200 + 50 + + JarWatcher +-- +handleEvent(String fileName) + + + + + Relation + + 140 + 410 + 280 + 120 + + lt=<<. + 260.0;10.0;10.0;100.0 + + + Relation + + 590 + 400 + 260 + 130 + + lt=<<. + 10.0;10.0;240.0;110.0 + + diff --git a/src/edu/rosehulman/cjjb/Main.java b/src/edu/rosehulman/cjjb/Main.java index 798436f..32f4ad4 100644 --- a/src/edu/rosehulman/cjjb/Main.java +++ b/src/edu/rosehulman/cjjb/Main.java @@ -3,17 +3,6 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; -import java.util.List; -import java.util.Map; - -import org.objectweb.asm.ClassReader; -import org.objectweb.asm.ClassVisitor; -import org.objectweb.asm.Opcodes; - -import edu.rosehulman.cjjb.asm.ClassDeclarationVisitor; -import edu.rosehulman.cjjb.asm.ClassFieldVisitor; -import edu.rosehulman.cjjb.asm.ClassMethodVisitor; -import edu.rosehulman.cjjb.asm.Relations; public class Main { @@ -24,6 +13,12 @@ public class Main { "edu.rosehulman.cjjb.asm.ClassMethodVisitor", "edu.rosehulman.cjjb.asm.Relations", "org.objectweb.asm.ClassVisitor" + /*"problem.AppLauncher", + "problem.HtmlWatcher", + "problem.JarWatcher", + "problem.TextPrinterWatcher", + "problem.TxtWatcher", + "problem.IWatcher"*/ }; public static final String boilerPlate = "digraph G { fontname = \"Bitstream Vera Sans\" fontsize = 8 node [ fontname = \"Bitstream Vera Sans\" fontsize = 8 shape = \"record\" ] edge [ fontname = \"Bitstream Vera Sans\" fontsize = 8 ]"; @@ -31,46 +26,8 @@ public class Main { public static void main(String[] args) throws IOException { OutputStream out = new FileOutputStream("output.txt"); - Relations relations = new Relations(); - - out.write(boilerPlate.getBytes()); - for (String className : CLASSES) { - - ClassReader reader = new ClassReader(className); - ClassVisitor decVisitor = new ClassDeclarationVisitor(Opcodes.ASM5, out, relations); - ClassVisitor fieldVisitor = new ClassFieldVisitor(Opcodes.ASM5, decVisitor, out); - ClassVisitor methodVisitor = new ClassMethodVisitor(Opcodes.ASM5, fieldVisitor, out); - // TODO: add more DECORATORS here in later milestones to accomplish - // specific tasks - reader.accept(methodVisitor, ClassReader.EXPAND_FRAMES); - - out.write("}\"\n]".getBytes()); - - } - - Map childParrentRelations = relations.getChildParentIncludedRelations(); - List interfaces = relations.getIncludedInterfaceRelations(); - writeChildParrentRelations(childParrentRelations,out); - writeInterfaceRelations(interfaces, out); - out.write("}".getBytes()); - } - - private static void writeChildParrentRelations(Map childParrentRelations, OutputStream out) throws IOException { - for(String child: childParrentRelations.keySet()) { - String toWrite = child + " -> " + childParrentRelations.get(child) + " [arrowhead=\"onormal\", style=\"filled\"]"; - - out.write(toWrite.getBytes()); - } - } - - private static void writeInterfaceRelations(List interfaces, OutputStream out) throws IOException { - //WeatherData -> Subject [arrowhead="onormal", style="dashed"]; - - for(String[] array: interfaces) { - String toWrite = array[0] + " -> " + array[1] + " [arrowhead=\"onormal\", style=\"dashed\"]"; - - out.write(toWrite.getBytes()); - } + UMLClassVisitor visitor = new UMLClassVisitor(CLASSES, out); + visitor.buildUML(); } diff --git a/src/edu/rosehulman/cjjb/UMLClassVisitor.java b/src/edu/rosehulman/cjjb/UMLClassVisitor.java new file mode 100644 index 0000000..f21a779 --- /dev/null +++ b/src/edu/rosehulman/cjjb/UMLClassVisitor.java @@ -0,0 +1,71 @@ +package edu.rosehulman.cjjb; + +import java.io.IOException; +import java.io.OutputStream; +import java.util.List; +import java.util.Map; + +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.Opcodes; + +import edu.rosehulman.cjjb.asm.ClassDeclarationVisitor; +import edu.rosehulman.cjjb.asm.ClassFieldVisitor; +import edu.rosehulman.cjjb.asm.ClassMethodVisitor; +import edu.rosehulman.cjjb.asm.Relations; + +public class UMLClassVisitor { + + public String[] classes; + public OutputStream out; + public static final String boilerPlate = "digraph G { fontname = \"Bitstream Vera Sans\" fontsize = 8 node [ fontname = \"Bitstream Vera Sans\" fontsize = 8 shape = \"record\" ] edge [ fontname = \"Bitstream Vera Sans\" fontsize = 8 ]"; + + public UMLClassVisitor(String[] classes, OutputStream out) { + this.classes = classes; + this.out = out; + } + + public void buildUML() throws IOException { + Relations relations = new Relations(); + + out.write(boilerPlate.getBytes()); + for (String className : this.classes) { + + ClassReader reader = new ClassReader(className); + ClassVisitor decVisitor = new ClassDeclarationVisitor(Opcodes.ASM5, out, relations); + ClassVisitor fieldVisitor = new ClassFieldVisitor(Opcodes.ASM5, decVisitor, out); + ClassVisitor methodVisitor = new ClassMethodVisitor(Opcodes.ASM5, fieldVisitor, out); + // TODO: add more DECORATORS here in later milestones to accomplish + // specific tasks + reader.accept(methodVisitor, ClassReader.EXPAND_FRAMES); + + out.write("}\"\n]".getBytes()); + + } + + Map childParrentRelations = relations.getChildParentIncludedRelations(); + List interfaces = relations.getIncludedInterfaceRelations(); + writeChildParrentRelations(childParrentRelations, out); + writeInterfaceRelations(interfaces, out); + out.write("}".getBytes()); + } + + private void writeChildParrentRelations(Map childParrentRelations, OutputStream out) throws IOException { + for(String child: childParrentRelations.keySet()) { + String toWrite = child + " -> " + childParrentRelations.get(child) + " [arrowhead=\"onormal\", style=\"filled\"]"; + + out.write(toWrite.getBytes()); + } + } + + private void writeInterfaceRelations(List interfaces, OutputStream out) throws IOException { + //WeatherData -> Subject [arrowhead="onormal", style="dashed"]; + + for(String[] array: interfaces) { + String toWrite = array[0] + " -> " + array[1] + " [arrowhead=\"onormal\", style=\"dashed\"]"; + + out.write(toWrite.getBytes()); + } + } + +} diff --git a/test/SyntaxTest.java b/test/SyntaxTest.java new file mode 100644 index 0000000..0e1c536 --- /dev/null +++ b/test/SyntaxTest.java @@ -0,0 +1,36 @@ +import static org.junit.Assert.*; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +import org.junit.Test; + +import edu.rosehulman.cjjb.UMLClassVisitor; + +public class SyntaxTest { + + @Test + public void testSyntax() throws IOException { + String[] classes = new String[] {"sampleClasses.Class1", "sampleClasses.Class2", "sampleClasses.Inter1"}; + ByteArrayOutputStream out = new ByteArrayOutputStream(); + UMLClassVisitor visitor = new UMLClassVisitor(classes, out); + visitor.buildUML(); + String result = new String(out.toByteArray()); + assertTrue(result.contains("Class1")); + assertTrue(result.contains("Class2")); + assertTrue(result.contains("Inter1")); + assertTrue(result.contains("Class1 -> Inter1")); + assertEquals(countString("\\{", result), countString("\\}", result)); + assertEquals(countString("\\[", result), countString("\\]", result)); + } + + public int countString(String delimeter, String result) { + int count = 0; + while (result.contains(delimeter)) { + result = result.replaceFirst(delimeter, ""); + count++; + } + return count; + } + +} diff --git a/test/sampleClasses/Class1.java b/test/sampleClasses/Class1.java new file mode 100644 index 0000000..bfbfd68 --- /dev/null +++ b/test/sampleClasses/Class1.java @@ -0,0 +1,17 @@ +package sampleClasses; + +public class Class1 implements Inter1{ + + public int publicField; + private int privateField; + + @Override + public void publicVoidMethod(){ + + } + + private int privateReturnIntMethod() { + return 0; + } + +} diff --git a/test/sampleClasses/Class2.java b/test/sampleClasses/Class2.java new file mode 100644 index 0000000..e0ed97c --- /dev/null +++ b/test/sampleClasses/Class2.java @@ -0,0 +1,12 @@ +package sampleClasses; + +public class Class2 extends Class1 { + + protected int protectedInt; + int defaultInt; + + protected void protectedVoidMethod() { + + } + +} diff --git a/test/sampleClasses/Inter1.java b/test/sampleClasses/Inter1.java new file mode 100644 index 0000000..3aabb76 --- /dev/null +++ b/test/sampleClasses/Inter1.java @@ -0,0 +1,5 @@ +package sampleClasses; + +public interface Inter1 { + public void publicVoidMethod(); +}