├── .gitignore ├── Makefile ├── README.md ├── _config.yml ├── class-diagram-gen ├── bin │ └── .gitignore ├── src │ ├── RunUMLParser.java │ └── com │ │ └── uml │ │ └── parser │ │ ├── enums │ │ ├── Modifiers.java │ │ └── RelationType.java │ │ ├── main │ │ ├── Counselor.java │ │ ├── GenerateUML.java │ │ ├── ParseJava.java │ │ └── UMLHelper.java │ │ └── model │ │ ├── Relationship.java │ │ ├── UMLClass.java │ │ ├── UMLMethod.java │ │ └── UMLVariable.java └── test-solutions │ ├── test1.png │ ├── test2.png │ ├── test3.png │ ├── test4.png │ └── test5.png ├── images ├── class.png ├── icon.png ├── sequence.png └── webapp.png ├── sequence-diagram-gen ├── bin │ └── .gitignore ├── sequence-diagram.png ├── src │ └── SequenceDiagramGenerator.java └── test-case │ └── SequenceGen.aj └── uml-parser-webapp ├── .idea ├── jsLibraryMappings.xml ├── libraries │ └── uml_parser_webapp_node_modules.xml ├── misc.xml ├── modules.xml ├── uml-parser-webapp.iml └── workspace.xml ├── app.js ├── bin ├── PlantUMLGrammar.txt ├── class-diagram-1493595773602.png ├── class-diagram-1493595785438.png ├── class-diagram-1493595800038.png ├── class-diagram-1493595812807.png ├── class-diagram-1493595827831.png └── www ├── images ├── branches.png ├── cars.png ├── customers.png ├── homepage.png └── transaction.png ├── package.json ├── public ├── javascripts │ └── upload.js └── stylesheets │ └── style.css ├── routes └── home.js ├── uploads ├── test1.zip ├── test2.zip ├── test3.zip ├── test4.zip ├── test5.zip └── upload_fb1ca40ccaa7d99a34cd9b2f9dd4fdbf └── views ├── error.ejs ├── homepage.ejs └── index.ejs /.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | 3 | # Mobile Tools for Java (J2ME) 4 | .mtj.tmp/ 5 | 6 | # Package Files # 7 | *.jar 8 | *.war 9 | *.ear 10 | 11 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 12 | hs_err_pid* 13 | /bin/ 14 | 15 | .settings/ 16 | .classpath 17 | .project 18 | .DS_Store 19 | 20 | # For Jekyll site 21 | _site/ 22 | 23 | # Logs 24 | logs 25 | *.log 26 | npm-debug.log* 27 | 28 | # Runtime data 29 | pids 30 | *.pid 31 | *.seed 32 | 33 | # Directory for instrumented libs generated by jscoverage/JSCover 34 | lib-cov 35 | 36 | # Coverage directory used by tools like istanbul 37 | coverage 38 | 39 | # nyc test coverage 40 | .nyc_output 41 | 42 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 43 | .grunt 44 | 45 | # node-waf configuration 46 | .lock-wscript 47 | 48 | # Compiled binary addons (http://nodejs.org/api/addons.html) 49 | build/Release 50 | 51 | # Dependency directories 52 | node_modules 53 | jspm_packages 54 | 55 | # Optional npm cache directory 56 | .npm 57 | 58 | # Optional REPL history 59 | .node_repl_history 60 | 61 | # ideal workspace.xml 62 | .idea/workspace.xml 63 | .idea/runConfigurations/bin_www.xml 64 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | ## 2 | # Makefile for UML Parser. 3 | # Generates UML Class diagram PNG file with name given and for folder path specified. 4 | # 5 | # NOTE: Make sure Java is installed and able to run "javac" on your machine 6 | ## 7 | 8 | CDG_BASE_DIR = class-diagram-gen/src/ 9 | CDG_BIN_DIR = class-diagram-gen/bin/ 10 | CDG_LIB_DIR = class-diagram-gen/lib/* 11 | 12 | CDG_MAIN = $(CDG_BASE_DIR)com/uml/parser/main/*.java 13 | CDG_ENUMS = $(CDG_BASE_DIR)com/uml/parser/enums/*.java 14 | CDG_MODEL = $(CDG_BASE_DIR)com/uml/parser/model/*.java 15 | 16 | # Main class which runs the program 17 | CDG_RUN = RunUMLParser 18 | # Complete folder path for the Java files for which UML class diagram is required 19 | CLASS_TEST_FOLDER_PATH = /Users/rishi/Downloads/cmpe202-master/umlparser/test2.zip 20 | # UML Class diagram output PNG file name 21 | CLASS_OUTPUT_FILE_NAME = umloutput 22 | 23 | 24 | all: clean 25 | 26 | clean: 27 | find . -name "*.class" -exec rm -rf {} \; 28 | 29 | generate-class-diagram: 30 | ###### Compiling classes required for UML Class diagram generator ###### 31 | javac -d $(CDG_BIN_DIR) -cp .:$(CDG_LIB_DIR) $(CDG_ENUMS) 32 | javac -d $(CDG_BIN_DIR) -cp .:$(CDG_BIN_DIR):$(CDG_LIB_DIR) $(CDG_MODEL) 33 | javac -d $(CDG_BIN_DIR) -cp .:$(CDG_BIN_DIR):$(CDG_LIB_DIR) $(CDG_MAIN) 34 | javac -d $(CDG_BIN_DIR) -cp .:$(CDG_BIN_DIR):$(CDG_LIB_DIR) $(CDG_BASE_DIR)*.java 35 | ##### Running UML Class diagram generator ###### 36 | java -cp .:$(CDG_BIN_DIR):$(CDG_LIB_DIR) $(CDG_RUN) $(CLASS_TEST_FOLDER_PATH) $(CLASS_TEST_FOLDER_PATH) 37 | 38 | execute-class-diagram-jar: 39 | java -jar class-diagram-gen/executable-jar/UMLClassDiagramGen.jar $(CLASS_TEST_FOLDER_PATH) $(CLASS_TEST_FOLDER_PATH) 40 | 41 | 42 | 43 | # ###################################################################################### 44 | # SDG_BASE_DIR = sequence-diagram-gen/src/ 45 | # SDG_BIN_DIR = sequence-diagram-gen/bin/ 46 | # SDG_LIB_DIR = sequence-diagram-gen/lib/* 47 | # 48 | # SDG_MAIN = $(SDG_BASE_DIR)*.java 49 | # SDG_AJ = $(SDG_BASE_DIR)*.aj 50 | # 51 | # # Main class which runs the program 52 | # SDG_RUN = SequenceDiagramGenerator 53 | # # Complete folder path for the Java files for which UML sequence diagram is required 54 | # SEQ_TEST_FOLDER_PATH = /Users/rishi/Downloads/cmpe202-master/umlparser/sequence.zip 55 | # # UML Sequence diagram output PNG file name 56 | # SEQ_OUTPUT_FILE_NAME = sequence-diagram 57 | # 58 | # generate-sequence-diagram: 59 | # ###### Compiling classes required for UML Sequence diagram generator ###### 60 | # javac -d $(SDG_BIN_DIR) -cp .:$(SDG_LIB_DIR) $(SDG_MAIN) 61 | # ##### Running UML Sequence diagram generator ###### 62 | # java -cp .:$(SDG_BIN_DIR):$(SDG_LIB_DIR) $(SDG_RUN) $(SEQ_TEST_FOLDER_PATH) $(SEQ_OUTPUT_FILE_NAME) 63 | # 64 | # execute-sequence-diagram-jar: 65 | # java -jar UMLClassDiagramGen.jar $(SEQ_TEST_FOLDER_PATH) $(SEQ_OUTPUT_FILE_NAME) 66 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Java tools to generate UML Class and Sequence diagrams 2 | 3 | **About** 4 | 5 | There are three applications here: 6 | 1. **UML Class diagram generator** 7 | 2. **Web application for UML Class diagram generator** 8 | 3. **UML Sequence diagram generator** 9 | 10 | **Tools and libraries used** 11 | 12 | 1. **[Javaparser](http://javaparser.org/index.html)**: Easy to understand and use, it gives Abstract Syntax Tree (AST) from java code. Parsed java class can be easily processed to generate the UML diagram 13 | 14 | 2. **[PlantUML](http://plantuml.com/)**: UML diagrams can be generated using simple and intuitive language used by PlantUML. 15 | 16 | 3. **[GraphViz](http://plantuml.com/graphviz-dot)**: Works with PlantUML to generate diagrams 17 | 3. **[AspectJ](https://eclipse.org/aspectj/doc/next/progguide/starting.html)**: Using AspectJ to parse the Java code and then create relevant grammar for PlantUML to generate the UML Sequence Diagram. 18 | 19 | **How it works** 20 | 21 | 1. **UML Class diagram generator**: The java files provided either directly or through the ZIP files are parsed using Javaparser for all the variables, methods, constructors, and interfaces. During parsing process, the code also creates the relationships between the classes. All the relationships and classes are stored in objects. Finally, grammar is created using these objects and given to PlantUML to generate the class diagram. 22 | 23 | 2. **Web application for UML Class diagram generator**: This internally uses the executable JAR generated using the #1. Simple layout created for uploading the ZIP using Bootstrap and Node.js uses Child Process module to start process to execute the JAR file. The JAR file is kept in one of folders of web application. ZIP files are extracted to 'test' folder temporarily and once class diagram is generated it's cleaned. The final diagram is shown on web page. 24 | 25 | 3. **UML Sequence diagram generator**: Uses AspectJ to understand when a method call is started and when it is ended. Pointcut is added to parse the input Java files. Code works fine for both folder path or ZIP file with java files. The output AspectJ parsing is used to create a grammar for the PlantUML, using this Sequence diagram is generated. 26 | 27 | 28 | **How to run** 29 | 30 | The steps below are after you have downloaded the project and kept the structure as it is. All the libraries are already included in the project. NOTE: You might need to change some paths based on configurations. 31 | 32 | *Pre-requisite* 33 | 34 | Java is installed and able to compile java files using terminal. 35 | 36 | 1. **UML Class diagram generator**: Edit the Makefile and update CLASS_TEST_FOLDER_PATH. Either point to folder with Java files or to path to ZIP file (Example: /Users/rishi/Downloads/cmpe202-master/umlparser/test2.zip). Use command "make generate-class-diagram" or "make execute-class-diagram-jar". If using Eclipse IDE, then it's staightforward. 37 | 38 | 2. **Web application for UML Class diagram generator**: To host this application of your own cloud, make sure that cloud environment has Java installed and GraphVIZ installed along with Node.js environment. Or else just to go https://uml-diagram-generator.herokuapp.com/ to run and use existing application to generate class diagrams. 39 | 40 | 3. **UML Sequence diagram generator**: To run this, you also need install Eclipse IDE AspectJ support and AspectJ compiler (AJC). Once that's done edit the run configurations of "SequenceDiagramGenerator.java" file in Eclipse IDE and point to correct folder with Java files or ZIP file with java files. Run the class as AspectJ/Java Application. 41 | 42 | 43 | **Development** 44 | 45 | This project tasks are managed by Kanban board created using [Waffle](https://waffle.io/) 46 | 47 | **Possible improvement** 48 | 49 | Option for user to select what all things should be included in the final UML Class diagram and flexibility of Sequence diagram generator to generate for any project, not specific one for which is developed. 50 | 51 | **Links** 52 | 53 | UML Class diagram generator web application: https://uml-diagram-generator.herokuapp.com/ 54 | UML Class diagram generator demo video: https://www.youtube.com/watch?v=kghB42D1UaQ 55 | UML Sequence diagram generator demo video: https://www.youtube.com/watch?v=NLxIUonmM24 56 | 57 | **Screenshots** 58 | 59 | Web app 60 | 61 | Web app 62 | 63 | Web app 64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-cayman -------------------------------------------------------------------------------- /class-diagram-gen/bin/.gitignore: -------------------------------------------------------------------------------- 1 | /com/ 2 | -------------------------------------------------------------------------------- /class-diagram-gen/src/RunUMLParser.java: -------------------------------------------------------------------------------- 1 | import java.io.BufferedOutputStream; 2 | import java.io.File; 3 | import java.io.FileInputStream; 4 | import java.io.FileOutputStream; 5 | import java.io.IOException; 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | import java.util.zip.ZipEntry; 9 | import java.util.zip.ZipInputStream; 10 | 11 | import com.uml.parser.main.GenerateUML; 12 | import com.uml.parser.main.ParseJava; 13 | 14 | /** 15 | * Main class to start the process. Validates the inputs and start t 16 | * 17 | * @author rishi 18 | * 19 | */ 20 | public class RunUMLParser { 21 | static {}; 22 | 23 | private static final int BUFFER_SIZE = 4096; 24 | 25 | public static void main(String[] args) { 26 | 27 | if (args.length < 2) { 28 | System.out.println("Invalid arguments, need two arguments!"); 29 | System.out.println("1. Complete folder path to Java files. 2. UML Class diagram output PNG file name"); 30 | System.out.println("Output file will be of .png format so no need to enter extenstion"); 31 | return; 32 | } 33 | 34 | RunUMLParser obj = new RunUMLParser(); 35 | obj.startProcess(args[0], args[1]); 36 | obj.clearTestFolder(); 37 | } 38 | 39 | /** 40 | * Starts the process of UML class diagram generation 41 | * @param inputPath 42 | * @param outputFileName 43 | */ 44 | private void startProcess(String inputPath, String outputFileName){ 45 | if (inputPath.indexOf(".zip") != -1) { 46 | try { 47 | unzipAndProcess(inputPath, outputFileName); 48 | 49 | } catch (IOException e) { 50 | System.out.println("Failed to unzip the folder. \nNote: Keep the Java files in root folder of zip:\n"+ e.getMessage()); 51 | } 52 | } else { 53 | File folder = new File(inputPath); 54 | if (folder == null || !folder.isDirectory()) { 55 | System.out.println("Folder path provided is not valid, please check -> " + inputPath); 56 | return; 57 | } 58 | processFiles(getFileListFromFolder(folder), outputFileName); 59 | } 60 | } 61 | 62 | /** 63 | * Returns list of files from the folder 64 | * @param folder 65 | * @return 66 | */ 67 | private List getFileListFromFolder(File folder) { 68 | List files = new ArrayList<>(); 69 | File[] filesInFolder = folder.listFiles(); 70 | for (int i = 0; filesInFolder != null && i < filesInFolder.length; i++) { 71 | File file = filesInFolder[i]; 72 | if (isValidFile(file)) { 73 | files.add(file); 74 | } 75 | } 76 | return files; 77 | } 78 | 79 | /** 80 | * Returns if the file is valid Java file or not 81 | * @param file 82 | * @return 83 | */ 84 | private boolean isValidFile(File file) { 85 | if (file.isFile()) { 86 | if (file.getName().endsWith("java") && !file.getName().equalsIgnoreCase("RunUMLParser.java")) { 87 | return true; 88 | } 89 | } 90 | return false; 91 | } 92 | 93 | /** 94 | * Actual process on list of collected java file starts 95 | * @param files 96 | * @param outputFileName 97 | */ 98 | private void processFiles(List files, String outputFileName) { 99 | if (files.size() == 0) { 100 | System.out.println( 101 | "Folder path has no .java files, program works only for Java files. Check and re-run the program\n" 102 | + "If you are using Zip file make sure the Java files are in home directory of Zip file"); 103 | return; 104 | } 105 | ParseJava obj = new ParseJava(); 106 | obj.parseFiles(files); 107 | GenerateUML generateUML = new GenerateUML(); 108 | generateUML.createGrammar(outputFileName); 109 | } 110 | 111 | 112 | /** 113 | * Extracts a zip file specified by the zipFilePath to a directory specified by 114 | * destDirectory (will be created if does not exists) 115 | * @param zipFilePath 116 | * @param destDirectory 117 | * @throws IOException 118 | */ 119 | public void unzipAndProcess(String zipFilePath, String outputFileName) throws IOException { 120 | String destDirectory = "test"; 121 | File destDir = new File(destDirectory); 122 | if (!destDir.exists()) { 123 | destDir.mkdir(); 124 | } 125 | 126 | ZipInputStream zipIn = new ZipInputStream(new FileInputStream(zipFilePath)); 127 | ZipEntry entry = zipIn.getNextEntry(); 128 | // iterates over entries in the zip file 129 | while (entry != null) { 130 | String filePath = destDirectory + File.separator + entry.getName(); 131 | if (!entry.isDirectory()) { 132 | // if the entry is a file, extracts it 133 | extractFile(zipIn, filePath); 134 | }else { 135 | // if the entry is a directory, make the directory 136 | File dir = new File(filePath); 137 | dir.mkdir(); 138 | } 139 | zipIn.closeEntry(); 140 | entry = zipIn.getNextEntry(); 141 | } 142 | zipIn.close(); 143 | 144 | File file = new File(destDir.getAbsolutePath()); 145 | processFiles(getFileListFromFolder(file), outputFileName); 146 | } 147 | /** 148 | * Extracts a zip entry (file entry) 149 | * @param zipIn 150 | * @param filePath 151 | * @throws IOException 152 | */ 153 | private void extractFile(ZipInputStream zipIn, String filePath) throws IOException { 154 | BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(filePath)); 155 | byte[] bytesIn = new byte[BUFFER_SIZE]; 156 | int read = 0; 157 | while ((read = zipIn.read(bytesIn)) != -1) { 158 | bos.write(bytesIn, 0, read); 159 | } 160 | bos.close(); 161 | } 162 | 163 | /** 164 | * Clears the test folder created for keeping the extracted files 165 | */ 166 | private void clearTestFolder(){ 167 | String destDirectory = "test"; 168 | File destDir = new File(destDirectory); 169 | if (destDir.exists()) { 170 | for(File file : destDir.listFiles()){ 171 | file.delete(); 172 | } 173 | } 174 | } 175 | } 176 | -------------------------------------------------------------------------------- /class-diagram-gen/src/com/uml/parser/enums/Modifiers.java: -------------------------------------------------------------------------------- 1 | package com.uml.parser.enums; 2 | 3 | /** 4 | * Defines all the possible modifiers and their symbols to be used 5 | * in the grammar 6 | * @author rishi 7 | * 8 | */ 9 | public enum Modifiers { 10 | 11 | PRIVATE(2, "-"), 12 | PRIVATE_STATIC(10, "- {static}"), 13 | PRIVATE_FINAL_STATIC(26, ""), 14 | 15 | PROTECTED(4, "#"), 16 | PROTECTED_STATIC(12, "{static}"), 17 | PROTECTED_ABSTRACT(1028, "# {abstract}"), 18 | PROTECTED_FINAL_STATIC(28, ""), 19 | 20 | PUBLIC(1, "+"), 21 | PUBLIC_STATIC(9, "+ {static}"), 22 | PUBLIC_ABSTRACT(1025, "+ {abstract}"), 23 | PUBLIC_FINAL_STATIC(25, ""), 24 | 25 | PACKAGE(0, "~"), 26 | PACKAGE_STATIC(8, "~ {static}"), 27 | PACKAGE_ABSTRACT(1024, "~ {abstract}"), 28 | PACKAGE_FINAL_STATIC(24, ""); 29 | 30 | 31 | public int modifier; 32 | public String symbol; 33 | 34 | /** 35 | * Initializes the modifiers with number and symobol for it 36 | * @param modifier 37 | * @param symbol 38 | */ 39 | private Modifiers(int modifier, String symbol) { 40 | this.modifier = modifier; 41 | this.symbol = symbol; 42 | } 43 | 44 | /** 45 | * Returns value for modifier 46 | * @param modifier 47 | * @return 48 | */ 49 | public static String valueOf(int modifier){ 50 | for(Modifiers mod : Modifiers.values()){ 51 | if(mod.modifier == modifier){ 52 | return mod.symbol; 53 | } 54 | } 55 | return ""; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /class-diagram-gen/src/com/uml/parser/enums/RelationType.java: -------------------------------------------------------------------------------- 1 | package com.uml.parser.enums; 2 | 3 | /** 4 | * Has all the possible relation types 5 | * @author rishi 6 | * 7 | */ 8 | public enum RelationType { 9 | // When a class is dependent on another class for its existence or implementation. 10 | // Example: When a class has object of another passed in a method as parameter. 11 | DEPENDENCY("..>"), 12 | 13 | // Shows static relationship among two classes with multiplicity, can be uni/bi directional. 14 | // Example: Car and Customer. Customer has array of objects of Car or Car has object of Customer as owner. 15 | ASSOCIATION("--"), 16 | 17 | // Shows 'has-a' relation, form of association relationship, whole is made of its parts. 18 | // Example: School and Student. School is made of Students. 19 | AGGREGATION("--o"), 20 | 21 | // Shows 'is-a' relation, form of association where one class owns the other. And other class cannot exist if owner is destroyed. 22 | // Example: Car and Engine where Car owns Engine. Engine cannot exist if Car is destroyed. 23 | COMPOSITION("--*"), 24 | 25 | // Represents inheritance concept in java. When a class is extended by other using extends. 26 | GENERALIZATION("--|>"), 27 | 28 | // Represents relation between class and interface. When class implements interfaces. 29 | REALIZATION("..|>"); // When implements is used 30 | 31 | private String symbol; 32 | 33 | /** 34 | * Constructor assigning symbol for relation type 35 | * @param symbol 36 | */ 37 | private RelationType(String symbol) { 38 | this.symbol = symbol; 39 | } 40 | 41 | /** 42 | * Returns symbol to be used in grammar for relation type 43 | * @return 44 | */ 45 | public String getSymbol(){ 46 | return this.symbol; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /class-diagram-gen/src/com/uml/parser/main/Counselor.java: -------------------------------------------------------------------------------- 1 | package com.uml.parser.main; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import com.uml.parser.enums.Modifiers; 7 | import com.uml.parser.enums.RelationType; 8 | import com.uml.parser.model.Relationship; 9 | import com.uml.parser.model.UMLClass; 10 | import com.uml.parser.model.UMLMethod; 11 | import com.uml.parser.model.UMLVariable; 12 | 13 | import japa.parser.ast.body.ClassOrInterfaceDeclaration; 14 | import japa.parser.ast.body.Parameter; 15 | import japa.parser.ast.body.TypeDeclaration; 16 | import japa.parser.ast.expr.VariableDeclarationExpr; 17 | import japa.parser.ast.type.ClassOrInterfaceType; 18 | import japa.parser.ast.type.Type; 19 | 20 | /** 21 | * Deals with creating relationships between {@link UMLClass} by using the 22 | * relations defined in {@link RelationType} 23 | * Maintains data for all the {@link UMLClass} and their {@link Relationship} 24 | * @author rishi 25 | * 26 | */ 27 | public class Counselor { 28 | 29 | private static Counselor counselor; 30 | private List relationships; 31 | private List umlClasses; 32 | 33 | /** 34 | * Returns the instance for singleton class 35 | * @return 36 | */ 37 | public static Counselor getInstance(){ 38 | if(counselor == null){ 39 | counselor = new Counselor(); 40 | } 41 | return counselor; 42 | } 43 | 44 | /** 45 | * Private constructor to implement singleton class 46 | */ 47 | private Counselor() { 48 | relationships = new ArrayList<>(); 49 | umlClasses = new ArrayList<>(); 50 | } 51 | 52 | /** 53 | * Check relationship between extended classes or implemented interfaces for given 54 | * {@link UMLClass} 55 | * 56 | * @param umlClass 57 | * @param type 58 | */ 59 | public void checkForRelatives(UMLClass umlClass, TypeDeclaration type){ 60 | ClassOrInterfaceDeclaration classOrInterfaceDeclaration = (ClassOrInterfaceDeclaration) type; 61 | if(classOrInterfaceDeclaration.getExtends() != null){ 62 | List extendList = classOrInterfaceDeclaration.getExtends(); 63 | for(ClassOrInterfaceType ext : extendList){ 64 | umlClass.addParent(ext.getName()); 65 | createRelationship(umlClass, ext, RelationType.GENERALIZATION); 66 | } 67 | } 68 | 69 | if(classOrInterfaceDeclaration.getImplements() != null){ 70 | List implementList = classOrInterfaceDeclaration.getImplements(); 71 | for(ClassOrInterfaceType imp : implementList){ 72 | umlClass.addParent(imp.getName()); 73 | createRelationship(umlClass, imp, RelationType.REALIZATION); 74 | } 75 | } 76 | } 77 | 78 | /** 79 | * Checks for dependency relationship, if object of other class is used in method parameters. 80 | * @param umlClass 81 | * @param method 82 | */ 83 | public void checkForRelatives(UMLClass umlClass, UMLMethod method){ 84 | if(method.getParameters() != null){ 85 | List parameters = method.getParameters(); 86 | for(Parameter parameter : parameters){ 87 | if(UMLHelper.isUMLClassType(parameter.getType())){ 88 | createRelationship(umlClass, parameter.getType(), RelationType.DEPENDENCY); 89 | } 90 | } 91 | } 92 | } 93 | 94 | /** 95 | * Checks relationships for instance variables declared for class. 96 | * @param umlClass 97 | * @param field 98 | */ 99 | public void checkForRelatives(UMLClass umlClass, UMLVariable field){ 100 | if(field.isUMLClassType()){ 101 | createRelationship(umlClass, field.getType(), RelationType.ASSOCIATION); 102 | } 103 | } 104 | 105 | /** 106 | * Checks for relatives in the method body 107 | * @param umlClass 108 | * @param variableDeclarationExpr 109 | */ 110 | public void checkForRelatives(UMLClass umlClass, VariableDeclarationExpr variableDeclarationExpr){ 111 | Type variableType = variableDeclarationExpr.getType(); 112 | if(UMLHelper.isUMLClassType(variableType)){ 113 | createRelationship(umlClass, variableType, RelationType.DEPENDENCY); 114 | } 115 | } 116 | 117 | /** 118 | * If there is a relationship they are created here. 119 | * @param umlClass 120 | * @param relative 121 | * @param relationType 122 | */ 123 | public void createRelationship(UMLClass umlClass, Type relative, RelationType relationType){ 124 | Relationship relationship = new Relationship(); 125 | relationship.setType(relationType); 126 | if(UMLHelper.isUMLClassArray(relative)){ 127 | relationship.setParent(counselor.getUMLClass(UMLHelper.getArrayClassName(relative))); 128 | if(relationType == RelationType.ASSOCIATION){ 129 | relationship.setParentCardinality("1"); 130 | relationship.setChildCardinality("0..*"); 131 | } 132 | }else { 133 | relationship.setParent(counselor.getUMLClass(relative.toString())); 134 | } 135 | relationship.setChild(umlClass); 136 | addRelation(relationship); 137 | 138 | // // As there is a relationship it means child is also a Class or Interface, so adding it to the list 139 | // // of UMLClasses. 140 | // UMLClass childUMLClass = counselor.getUMLClass(relationship.getChild()); 141 | // counselor.addUMLClass(childUMLClass); 142 | } 143 | 144 | 145 | /** 146 | * Returns all the relationship 147 | * @return the relationships 148 | */ 149 | public List getRelationships() { 150 | return relationships; 151 | } 152 | 153 | /** 154 | * Setter for setting relationships 155 | * @param relationships the relationships to set 156 | */ 157 | public void setRelationships(List relationships) { 158 | this.relationships = relationships; 159 | } 160 | 161 | /** 162 | * Adds {@link Relationship} by checking if its already present or not 163 | * @param newRelation 164 | */ 165 | private void addRelation(Relationship newRelation){ 166 | if(relationships.size() > 0){ 167 | for(Relationship oldRelation : relationships){ 168 | if(oldRelation.getParent().getName().equalsIgnoreCase(newRelation.getParent().getName()) && 169 | oldRelation.getChild().getName().equalsIgnoreCase(newRelation.getChild().getName()) 170 | && oldRelation.getType() == newRelation.getType()){ 171 | return; 172 | }else if(oldRelation.getParent().getName().equalsIgnoreCase(newRelation.getChild().getName()) && 173 | oldRelation.getChild().getName().equalsIgnoreCase(newRelation.getParent().getName()) 174 | && oldRelation.getType() == newRelation.getType()){ 175 | return; 176 | } 177 | } 178 | } 179 | relationships.add(newRelation); 180 | } 181 | 182 | /** 183 | * Adds {@link UMLClass} 184 | * @param newUMLClass 185 | */ 186 | public void addUMLClass(UMLClass newUMLClass){ 187 | if(!hasUMLClass(newUMLClass)){ 188 | umlClasses.add(newUMLClass); 189 | } 190 | } 191 | 192 | /** 193 | * Returns all the {@link UMLClass} 194 | * @return 195 | */ 196 | public List getUMLClasses(){ 197 | return umlClasses; 198 | } 199 | 200 | /** 201 | * Returns {@link UMLClass} for given name 202 | * @param name 203 | * @return 204 | */ 205 | public UMLClass getUMLClass(String name){ 206 | for(UMLClass umlClass : umlClasses){ 207 | if(umlClass.getName().equalsIgnoreCase(name)){ 208 | return umlClass; 209 | } 210 | } 211 | UMLClass newUMLClass = new UMLClass(); 212 | newUMLClass.setName(name); 213 | umlClasses.add(newUMLClass); 214 | return newUMLClass; 215 | } 216 | 217 | /** 218 | * Checks if {@link UMLClass} is already present with {@link Counselor} 219 | * @param newUMLClass 220 | * @return 221 | */ 222 | public boolean hasUMLClass(UMLClass newUMLClass){ 223 | for(UMLClass umlClass : umlClasses){ 224 | if(umlClass.getName().equalsIgnoreCase(newUMLClass.getName())){ 225 | return true; 226 | } 227 | } 228 | return false; 229 | } 230 | 231 | /** 232 | * If the variable has getter and setter we update it to public 233 | * @param umlClass 234 | * @param variableName 235 | */ 236 | public void updateVariableToPublic(UMLClass umlClass, String variableName){ 237 | for(UMLVariable variable : umlClass.getUMLVariables()){ 238 | if(variable.getName().equalsIgnoreCase(variableName)){ 239 | variable.setModifier(Modifiers.PUBLIC.modifier); 240 | } 241 | } 242 | } 243 | 244 | /** 245 | * Removes the getter and setter methods, as we are making the variable public 246 | * @param umlClass 247 | * @param getterMethod 248 | * @param setterMethod 249 | */ 250 | public void removeSetterGetterMethod(UMLClass umlClass, UMLMethod getterMethod, UMLMethod setterMethod){ 251 | List umlMethods = new ArrayList<>(); 252 | for(UMLMethod umlMethod : umlClass.getUMLMethods()){ 253 | if(!umlMethod.getName().equalsIgnoreCase(getterMethod.getName()) && 254 | !umlMethod.getName().equalsIgnoreCase(setterMethod.getName())){ 255 | umlMethods.add(umlMethod); 256 | } 257 | } 258 | } 259 | 260 | /** 261 | * TODO Confirm if this required or not 262 | * Removes the methods which are repeated in the Child classes, as they are already defined in parent classes 263 | */ 264 | public void removeUnneccessaryMethods(){ 265 | for(Relationship relationship : relationships){ 266 | if(relationship.getType() == RelationType.GENERALIZATION || relationship.getType() == RelationType.REALIZATION){ 267 | UMLClass parent = relationship.getParent(); 268 | UMLClass child = relationship.getChild(); 269 | List newChildMethods = child.getUMLMethods(); 270 | 271 | for(UMLMethod parentMethod : parent.getUMLMethods()){ 272 | if(newChildMethods.contains(parentMethod)){ 273 | newChildMethods.remove(parentMethod); 274 | } 275 | } 276 | child.setUMLMethods(newChildMethods); 277 | } 278 | } 279 | } 280 | } 281 | -------------------------------------------------------------------------------- /class-diagram-gen/src/com/uml/parser/main/GenerateUML.java: -------------------------------------------------------------------------------- 1 | package com.uml.parser.main; 2 | 3 | import java.io.BufferedWriter; 4 | import java.io.FileNotFoundException; 5 | import java.io.FileOutputStream; 6 | import java.io.FileWriter; 7 | import java.io.IOException; 8 | import java.io.OutputStream; 9 | import java.util.List; 10 | 11 | import com.uml.parser.enums.Modifiers; 12 | import com.uml.parser.enums.RelationType; 13 | import com.uml.parser.model.Relationship; 14 | import com.uml.parser.model.UMLClass; 15 | import com.uml.parser.model.UMLMethod; 16 | import com.uml.parser.model.UMLVariable; 17 | 18 | import net.sourceforge.plantuml.SourceStringReader; 19 | 20 | /** 21 | * Generates the UML based on the {@link UMLClass} and {@link Relationship} 22 | * provided by {@link Counselor} 23 | * @author rishi 24 | * 25 | */ 26 | public class GenerateUML { 27 | 28 | private Counselor counselor; 29 | 30 | /** 31 | * Constructor fetches instance of {@link Counselor} 32 | */ 33 | public GenerateUML() { 34 | counselor = Counselor.getInstance(); 35 | } 36 | 37 | /** 38 | * Generation of UML for class diagram is done by writing the grammar 39 | * @param outputFileName 40 | */ 41 | public void createGrammar(String outputFileName){ 42 | if(outputFileName.indexOf('.') != -1){ 43 | outputFileName = outputFileName.split("\\.")[0]; 44 | } 45 | StringBuilder umlSource = new StringBuilder(); 46 | umlSource.append("@startuml \nskinparam classAttributeIconSize 0\n"); 47 | for(UMLClass umlClass : counselor.getUMLClasses()){ 48 | if(umlClass.isInterface()){ 49 | umlSource.append("interface " + umlClass.getName() + " << interface >> {\n"); 50 | }else { 51 | umlSource.append("class " + umlClass.getName() + " {\n"); 52 | } 53 | 54 | boolean hasSetter = false; 55 | boolean hasGetter = false; 56 | String setVariable = ""; 57 | String getVariable = ""; 58 | UMLMethod setterMethod = null; 59 | UMLMethod getterMethod = null; 60 | List methods = umlClass.getUMLMethods(); 61 | for(UMLMethod method : methods){ 62 | if(!isMethodPublic(method)){ 63 | continue; 64 | } 65 | if(method.isConstructor()){ 66 | umlSource.append(method.getParameterizedUMLString()); 67 | }else if(method.getName().contains("set") && method.getName().split("set").length > 1){ 68 | hasSetter = true; 69 | setVariable = method.getName().split("set")[1]; 70 | setterMethod = method; 71 | }else if(method.getName().contains("get") && method.getName().split("get").length > 1){ 72 | hasGetter = true; 73 | getVariable = method.getName().split("get")[1]; 74 | getterMethod = method; 75 | }else if(isMethodPublic(method)){ 76 | umlSource.append(method.getParameterizedUMLString()); 77 | } 78 | } 79 | if(hasGetter && hasSetter && setVariable.equalsIgnoreCase(getVariable) && setterMethod != null){ 80 | if(umlClass.hasVariable(getVariable)){ 81 | counselor.updateVariableToPublic(umlClass, getVariable); 82 | counselor.removeSetterGetterMethod(umlClass, getterMethod, setterMethod); 83 | }else { 84 | umlSource.append(getterMethod.getParameterizedUMLString()); 85 | umlSource.append(setterMethod.getParameterizedUMLString()); 86 | } 87 | } 88 | 89 | List variables = umlClass.getUMLVariables(); 90 | for(UMLVariable variable : variables){ 91 | if(variable.getModifier() != Modifiers.PROTECTED.modifier && variable.getModifier() != Modifiers.PACKAGE.modifier && 92 | !variable.isUMLClassType()){ 93 | umlSource.append(variable.getUMLString()); 94 | } 95 | } 96 | 97 | umlSource.append("}\n\n"); 98 | } 99 | 100 | for(Relationship relationship : counselor.getRelationships()){ 101 | if(relationship.getType() == RelationType.DEPENDENCY && UMLHelper.isInterfaceDependency(relationship)){ 102 | umlSource.append(relationship.getUMLString()); 103 | }else if(relationship.getType() != RelationType.DEPENDENCY){ 104 | umlSource.append(relationship.getUMLString()); 105 | } 106 | } 107 | 108 | umlSource.append("hide circle \n@enduml"); 109 | dumpGrammarToFile(umlSource.toString()); 110 | generateUML(outputFileName, umlSource.toString()); 111 | } 112 | 113 | /** 114 | * Actually generates the PNG with provided output file name 115 | * @param outputFileName 116 | * @param umlSource 117 | */ 118 | private void generateUML(String outputFileName, String umlSource){ 119 | try{ 120 | OutputStream png = new FileOutputStream(outputFileName + ".png"); 121 | SourceStringReader reader = new SourceStringReader(umlSource); 122 | reader.generateImage(png); 123 | System.out.println("Output UML Class diagram with name '"+outputFileName +".png' is generated in base directory"); 124 | } 125 | catch (FileNotFoundException exception) { 126 | System.err.println("Failed to create output file " + exception.getMessage()); 127 | } 128 | catch (IOException exception){ 129 | System.err.println("Failed to write to output file " + exception.getMessage()); 130 | } 131 | } 132 | 133 | /** 134 | * Returns true if the method is public, checks for all combinations 135 | * @param method 136 | * @return 137 | */ 138 | private boolean isMethodPublic(UMLMethod method){ 139 | if(method.getModifier() == Modifiers.PUBLIC.modifier || method.getModifier() == Modifiers.PUBLIC_STATIC.modifier || 140 | method.getModifier() == Modifiers.PUBLIC_ABSTRACT.modifier){ 141 | return true; 142 | } 143 | return false; 144 | } 145 | 146 | /** 147 | * Dumps the grammar generated for UML Class diagram to txt file. 148 | * @param grammar 149 | */ 150 | private void dumpGrammarToFile(String grammar){ 151 | try { 152 | BufferedWriter writer = new BufferedWriter(new FileWriter("PlantUMLGrammar.txt")); 153 | writer.write(grammar); 154 | writer.close(); 155 | System.out.println("PlantUML grammar is dumped in 'PlantUMLGrammar.txt' file in base directory"); 156 | } catch (IOException e) { 157 | System.err.println("Failed to dump grammar to text file: "+ e.getMessage()); 158 | } 159 | 160 | } 161 | } 162 | -------------------------------------------------------------------------------- /class-diagram-gen/src/com/uml/parser/main/ParseJava.java: -------------------------------------------------------------------------------- 1 | package com.uml.parser.main; 2 | import java.io.File; 3 | import java.io.FileNotFoundException; 4 | import java.io.IOException; 5 | import java.util.List; 6 | 7 | import com.uml.parser.enums.Modifiers; 8 | import com.uml.parser.model.UMLClass; 9 | import com.uml.parser.model.UMLMethod; 10 | import com.uml.parser.model.UMLVariable; 11 | 12 | import japa.parser.JavaParser; 13 | import japa.parser.ParseException; 14 | import japa.parser.ast.CompilationUnit; 15 | import japa.parser.ast.body.BodyDeclaration; 16 | import japa.parser.ast.body.ClassOrInterfaceDeclaration; 17 | import japa.parser.ast.body.ConstructorDeclaration; 18 | import japa.parser.ast.body.FieldDeclaration; 19 | import japa.parser.ast.body.MethodDeclaration; 20 | import japa.parser.ast.body.TypeDeclaration; 21 | import japa.parser.ast.body.VariableDeclarator; 22 | import japa.parser.ast.expr.VariableDeclarationExpr; 23 | import japa.parser.ast.stmt.BlockStmt; 24 | import japa.parser.ast.stmt.ExpressionStmt; 25 | import japa.parser.ast.stmt.Statement; 26 | 27 | /** 28 | * Parses Java classes to create {@link UMLClass} for each input class. 29 | * Deals with variables, constructors and methods. 30 | * Also, calls {@link Counselor} for creating relationships if any 31 | * @author rishi 32 | * 33 | */ 34 | public class ParseJava { 35 | private Counselor counselor; 36 | 37 | /** 38 | * Constructor for class 39 | */ 40 | public ParseJava() { 41 | counselor = Counselor.getInstance(); 42 | } 43 | 44 | /** 45 | * Parsing begins here for each input file 46 | * @param files 47 | */ 48 | public void parseFiles(List files){ 49 | try{ 50 | for(File file : files){ 51 | System.out.println("Parsing " + file.getAbsolutePath() + " file..."); 52 | CompilationUnit compliationUnit = JavaParser.parse(file); 53 | createUMLClass(compliationUnit); 54 | } 55 | //counselor.removeUnneccessaryMethods(); 56 | }catch(FileNotFoundException ex){ 57 | System.err.println("Error: File not found. Trace: "+ ex.getMessage()); 58 | }catch(IOException ex){ 59 | System.err.println("Error: IO Exception. Trace: "+ ex.getMessage()); 60 | }catch(ParseException ex){ 61 | System.err.println("Error: Parse exception. Trace: "+ ex.getMessage()); 62 | } 63 | } 64 | 65 | /** 66 | * Creates {@link UMLClass} for input Java Class. 67 | * @param compliationUnit 68 | */ 69 | private void createUMLClass(CompilationUnit compliationUnit){ 70 | List types = compliationUnit.getTypes(); 71 | for(TypeDeclaration type : types){ 72 | List bodyDeclarations = type.getMembers(); 73 | boolean isInterface = ((ClassOrInterfaceDeclaration) type).isInterface(); 74 | 75 | UMLClass umlClass = counselor.getUMLClass(type.getName()); 76 | umlClass.setInterface(isInterface); 77 | 78 | counselor.checkForRelatives(umlClass, type); 79 | 80 | for(BodyDeclaration body : bodyDeclarations){ 81 | if(body instanceof FieldDeclaration){ 82 | createUMLVariables(umlClass, (FieldDeclaration) body); 83 | }else if(body instanceof MethodDeclaration){ 84 | createUMLMethods(umlClass, (MethodDeclaration) body, false); 85 | }else if(body instanceof ConstructorDeclaration){ 86 | createUMLMethods(umlClass, (ConstructorDeclaration) body, true); 87 | } 88 | } 89 | counselor.addUMLClass(umlClass); 90 | } 91 | } 92 | 93 | /** 94 | * All instance variables are parsed here 95 | * @param umlClass 96 | * @param field 97 | */ 98 | private void createUMLVariables(UMLClass umlClass, FieldDeclaration field){ 99 | List variables = field.getVariables(); 100 | for(VariableDeclarator variable : variables){ 101 | UMLVariable umlVariable = new UMLVariable(); 102 | umlVariable.setModifier(field.getModifiers()); 103 | umlVariable.setName(variable.getId().getName()); 104 | umlVariable.setInitialValue(variable.getInit() == null ? "" : " = " + variable.getInit().toString()); 105 | umlVariable.setUMLClassType(UMLHelper.isUMLClassType(field.getType())); 106 | umlVariable.setType(field.getType()); 107 | umlClass.getUMLVariables().add(umlVariable); 108 | counselor.checkForRelatives(umlClass, umlVariable); 109 | } 110 | } 111 | 112 | /** 113 | * All the methods including constructors are parsed here 114 | * @param umlClass 115 | * @param body 116 | * @param isConstructor 117 | */ 118 | private void createUMLMethods(UMLClass umlClass, BodyDeclaration body, boolean isConstructor){ 119 | UMLMethod umlMethod = new UMLMethod(); 120 | if(isConstructor){ 121 | ConstructorDeclaration constructor = (ConstructorDeclaration) body; 122 | umlMethod.setConstructor(true); 123 | umlMethod.setModifier(constructor.getModifiers()); 124 | umlMethod.setName(constructor.getName()); 125 | umlMethod.setParameters(constructor.getParameters()); 126 | 127 | parseMethodBody(umlClass, constructor.getBlock()); 128 | }else { 129 | MethodDeclaration method = (MethodDeclaration) body; 130 | umlMethod.setConstructor(false); 131 | umlMethod.setModifier(umlClass.isInterface() ? Modifiers.PUBLIC_ABSTRACT.modifier : method.getModifiers()); 132 | umlMethod.setName(method.getName()); 133 | umlMethod.setParameters(method.getParameters()); 134 | umlMethod.setType(method.getType()); 135 | 136 | parseMethodBody(umlClass, method.getBody()); 137 | } 138 | umlClass.getUMLMethods().add(umlMethod); 139 | counselor.checkForRelatives(umlClass, umlMethod); 140 | } 141 | 142 | /** 143 | * Method body parsing 144 | * @param umlClass 145 | * @param methodBody 146 | */ 147 | private void parseMethodBody(UMLClass umlClass, BlockStmt methodBody){ 148 | if(methodBody == null || methodBody.getStmts() == null){ 149 | return; 150 | } 151 | List methodStmts = methodBody.getStmts(); 152 | for(Statement statement : methodStmts){ 153 | if(statement instanceof ExpressionStmt && ((ExpressionStmt) statement).getExpression() instanceof VariableDeclarationExpr){ 154 | VariableDeclarationExpr expression = (VariableDeclarationExpr) (((ExpressionStmt) statement).getExpression()); 155 | counselor.checkForRelatives(umlClass, expression); 156 | } 157 | } 158 | } 159 | } -------------------------------------------------------------------------------- /class-diagram-gen/src/com/uml/parser/main/UMLHelper.java: -------------------------------------------------------------------------------- 1 | package com.uml.parser.main; 2 | 3 | 4 | import java.util.List; 5 | 6 | import com.uml.parser.model.Relationship; 7 | import com.uml.parser.model.UMLClass; 8 | 9 | import japa.parser.ast.type.ClassOrInterfaceType; 10 | import japa.parser.ast.type.PrimitiveType; 11 | import japa.parser.ast.type.ReferenceType; 12 | import japa.parser.ast.type.Type; 13 | 14 | /** 15 | * Helper provides methods for important checks and operations 16 | * @author rishi 17 | * 18 | */ 19 | public class UMLHelper { 20 | 21 | /** 22 | * Checks if the {@link Type} is of {@link UMLClass} type or not. 23 | * Ignores java objects and collections as we are just concentrating on the 24 | * input java classes. 25 | * @param type 26 | * @return 27 | */ 28 | public static boolean isUMLClassType(Type type){ 29 | if(type instanceof PrimitiveType){ 30 | return false; 31 | }else if(type instanceof ReferenceType){ 32 | if(((ReferenceType) type).getType() instanceof PrimitiveType){ 33 | return false; 34 | }else if(((ReferenceType) type).getType() instanceof ClassOrInterfaceType){ 35 | ReferenceType refernceType = (ReferenceType) type; 36 | ClassOrInterfaceType actualType = (ClassOrInterfaceType) refernceType.getType(); 37 | return isValidUMLClass(actualType.getName()) || isValidUMLClass(getArrayClassName(refernceType)); 38 | } 39 | } 40 | return true; 41 | } 42 | 43 | /** 44 | * Checks if {@link Type} is {@link UMLClass} and array or collection at the same time. 45 | * @param type 46 | * @return 47 | */ 48 | public static boolean isUMLClassArray(Type type){ 49 | if(type.toString().contains("[") || type.toString().contains("<")){ 50 | return true; 51 | } 52 | return false; 53 | } 54 | 55 | /** 56 | * Extracts just the name for arrays or collections of {@link UMLClass} 57 | * @param type 58 | * @return 59 | */ 60 | public static String getArrayClassName(Type type){ 61 | if(type.toString().contains("[")){ 62 | return getElementName(type.toString()); 63 | }else if(type.toString().contains("<")){ 64 | ReferenceType collectionType = (ReferenceType) type; 65 | ClassOrInterfaceType classOrInterfaceType = (ClassOrInterfaceType) collectionType.getType(); 66 | if(classOrInterfaceType.getTypeArgs() != null){ 67 | List args = classOrInterfaceType.getTypeArgs(); 68 | for(Type arg : args){ 69 | if(isUMLClassType(arg)){ 70 | return arg.toString(); 71 | } 72 | } 73 | } 74 | } 75 | return ""; 76 | } 77 | 78 | /** 79 | * Ignores [] and <> to fetch just the name 80 | * @param typeStr 81 | * @return 82 | */ 83 | public static String getElementName(String typeStr){ 84 | if(typeStr.contains("[")){ 85 | typeStr = typeStr.split("\\[")[0]; 86 | }else if(typeStr.contains("<")){ 87 | typeStr = typeStr.split("<")[0]; 88 | } 89 | return typeStr; 90 | } 91 | 92 | /** 93 | * We just need dependency for interfaces, this checks if one of the relatives is interface or not 94 | * @param relationship 95 | * @return 96 | */ 97 | public static boolean isInterfaceDependency(Relationship relationship){ 98 | UMLClass child = relationship.getChild(); 99 | UMLClass parent = relationship.getParent(); 100 | if((child.isInterface() && !parent.isInterface()) || (!child.isInterface()) && parent.isInterface()){ 101 | return true; 102 | } 103 | return false; 104 | } 105 | 106 | /** 107 | * Returns true if the class name is not one of the Java core classes 108 | * @param typeStr 109 | * @return 110 | */ 111 | private static boolean isValidUMLClass(String typeStr){ 112 | if(typeStr.equalsIgnoreCase("") || typeStr.equalsIgnoreCase("Double") || typeStr.equalsIgnoreCase("Float") || 113 | typeStr.equalsIgnoreCase("Long") || typeStr.equalsIgnoreCase("Integer") || 114 | typeStr.equalsIgnoreCase("Short") || typeStr.equalsIgnoreCase("Character") || 115 | typeStr.equalsIgnoreCase("Byte") || typeStr.equalsIgnoreCase("Boolean") || 116 | typeStr.equalsIgnoreCase("String") || typeStr.equalsIgnoreCase("ArrayList") || 117 | typeStr.equalsIgnoreCase("Collection") || typeStr.equalsIgnoreCase("HashSet")){ 118 | return false; 119 | } 120 | return true; 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /class-diagram-gen/src/com/uml/parser/model/Relationship.java: -------------------------------------------------------------------------------- 1 | package com.uml.parser.model; 2 | import com.uml.parser.enums.RelationType; 3 | 4 | /** 5 | * Model for relationships between all the classes. 6 | * @author rishi 7 | * 8 | */ 9 | public class Relationship { 10 | 11 | private UMLClass parent; 12 | private UMLClass child; 13 | private RelationType type; 14 | private String parentCardinality; 15 | private String childCardinality; 16 | 17 | /** 18 | * Contructor for the relationship 19 | */ 20 | public Relationship() { 21 | parentCardinality = null; 22 | childCardinality = null; 23 | } 24 | 25 | /** 26 | * @return the parent 27 | */ 28 | public UMLClass getParent() { 29 | return parent; 30 | } 31 | /** 32 | * @param parent the parent to set 33 | */ 34 | public void setParent(UMLClass parent) { 35 | this.parent = parent; 36 | } 37 | /** 38 | * @return the child 39 | */ 40 | public UMLClass getChild() { 41 | return child; 42 | } 43 | /** 44 | * @param child the child to set 45 | */ 46 | public void setChild(UMLClass child) { 47 | this.child = child; 48 | } 49 | /** 50 | * @return the type 51 | */ 52 | public RelationType getType() { 53 | return type; 54 | } 55 | /** 56 | * @param type the type to set 57 | */ 58 | public void setType(RelationType type) { 59 | this.type = type; 60 | } 61 | /** 62 | * @return the parentCardinality 63 | */ 64 | public String getParentCardinality() { 65 | return parentCardinality; 66 | } 67 | /** 68 | * @param parentCardinality the parentCardinality to set 69 | */ 70 | public void setParentCardinality(String parentCardinality) { 71 | this.parentCardinality = parentCardinality; 72 | } 73 | /** 74 | * @return the childCardinality 75 | */ 76 | public String getChildCardinality() { 77 | return childCardinality; 78 | } 79 | /** 80 | * @param childCardinality the childCardinality to set 81 | */ 82 | public void setChildCardinality(String childCardinality) { 83 | this.childCardinality = childCardinality; 84 | } 85 | 86 | /** 87 | * Returns the grammar for UML class diagram 88 | * @return 89 | */ 90 | public String getUMLString(){ 91 | if(parentCardinality != null && childCardinality != null){ 92 | return (child.getName() + "\"" + parentCardinality + "\"" + type.getSymbol() + "\"" + childCardinality + "\"" + parent.getName() + "\n\n"); 93 | } 94 | return (child.getName() + type.getSymbol() + parent.getName() + "\n\n"); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /class-diagram-gen/src/com/uml/parser/model/UMLClass.java: -------------------------------------------------------------------------------- 1 | package com.uml.parser.model; 2 | import java.util.ArrayList; 3 | import java.util.List; 4 | 5 | /** 6 | * Model representing each class provided. 7 | * @author rishi 8 | * 9 | */ 10 | public class UMLClass { 11 | 12 | private List umlVariables; 13 | private List umlMethods; 14 | private boolean isInterface; 15 | private String name; 16 | private List parents; 17 | 18 | /** 19 | * Constructor for initializing the variables 20 | */ 21 | public UMLClass() { 22 | name = ""; 23 | isInterface = false; 24 | umlVariables = new ArrayList<>(); 25 | umlMethods = new ArrayList<>(); 26 | parents = new ArrayList<>(); 27 | } 28 | 29 | /** 30 | * @return the fieldDeclarations 31 | */ 32 | public List getUMLVariables() { 33 | return umlVariables; 34 | } 35 | /** 36 | * @param umlVariables the fieldDeclarations to set 37 | */ 38 | public void setUMLVariables(List umlVariables) { 39 | this.umlVariables = umlVariables; 40 | } 41 | /** 42 | * @return the methodDeclarations 43 | */ 44 | public List getUMLMethods() { 45 | return umlMethods; 46 | } 47 | /** 48 | * @param umlMethods the methodDeclarations to set 49 | */ 50 | public void setUMLMethods(List umlMethods) { 51 | this.umlMethods = umlMethods; 52 | } 53 | 54 | /** 55 | * @return the isInterface 56 | */ 57 | public boolean isInterface() { 58 | return isInterface; 59 | } 60 | /** 61 | * @param isInterface the isInterface to set 62 | */ 63 | public void setInterface(boolean isInterface) { 64 | this.isInterface = isInterface; 65 | } 66 | 67 | /** 68 | * @return the name 69 | */ 70 | public String getName() { 71 | return name; 72 | } 73 | 74 | /** 75 | * @param name the name to set 76 | */ 77 | public void setName(String name) { 78 | this.name = name; 79 | } 80 | 81 | /** 82 | * @return the parents 83 | */ 84 | public List getParents() { 85 | return parents; 86 | } 87 | 88 | /** 89 | * @param parents the parents to set 90 | */ 91 | public void setParents(List parents) { 92 | this.parents = parents; 93 | } 94 | 95 | /** 96 | * Adds individual parent one by one 97 | * @param parent 98 | */ 99 | public void addParent(String parent){ 100 | this.parents.add(parent); 101 | } 102 | 103 | /** 104 | * Returns true if the Class already has variable 105 | * @param variable 106 | * @return 107 | */ 108 | public boolean hasVariable(String variable){ 109 | for(UMLVariable var : umlVariables){ 110 | if(var.getName().equalsIgnoreCase(variable)){ 111 | return true; 112 | } 113 | } 114 | return false; 115 | } 116 | 117 | } 118 | -------------------------------------------------------------------------------- /class-diagram-gen/src/com/uml/parser/model/UMLMethod.java: -------------------------------------------------------------------------------- 1 | package com.uml.parser.model; 2 | import java.util.ArrayList; 3 | import java.util.List; 4 | 5 | import com.uml.parser.enums.Modifiers; 6 | 7 | import japa.parser.ast.type.Type; 8 | 9 | import japa.parser.ast.body.Parameter; 10 | 11 | /** 12 | * Model representing methods in the classes 13 | * @author rishi 14 | * 15 | */ 16 | public class UMLMethod { 17 | 18 | private String name; 19 | private List parameters; 20 | private int modifier; 21 | private boolean isConstructor; 22 | private Type type; 23 | 24 | public UMLMethod() { 25 | parameters = new ArrayList<>(); 26 | } 27 | 28 | /** 29 | * @return the name 30 | */ 31 | public String getName() { 32 | return name; 33 | } 34 | /** 35 | * @param name the name to set 36 | */ 37 | public void setName(String name) { 38 | this.name = name; 39 | } 40 | /** 41 | * @return the parameters 42 | */ 43 | public List getParameters() { 44 | return parameters; 45 | } 46 | /** 47 | * @param parameters the parameters to set 48 | */ 49 | public void setParameters(List parameters) { 50 | this.parameters = parameters; 51 | } 52 | /** 53 | * @return the modifier 54 | */ 55 | public int getModifier() { 56 | return modifier; 57 | } 58 | /** 59 | * @param modifier the modifier to set 60 | */ 61 | public void setModifier(int modifier) { 62 | this.modifier = modifier; 63 | } 64 | /** 65 | * @return the isConstructor 66 | */ 67 | public boolean isConstructor() { 68 | return isConstructor; 69 | } 70 | /** 71 | * @param isConstructor the isConstructor to set 72 | */ 73 | public void setConstructor(boolean isConstructor) { 74 | this.isConstructor = isConstructor; 75 | } 76 | 77 | 78 | /** 79 | * @return the type 80 | */ 81 | public Type getType() { 82 | return type; 83 | } 84 | 85 | /** 86 | * @param type the type to set 87 | */ 88 | public void setType(Type type) { 89 | this.type = type; 90 | } 91 | 92 | public String getParameterizedUMLString(){ 93 | StringBuffer umlStr = new StringBuffer(); 94 | if(parameters != null){ 95 | umlStr.append(Modifiers.valueOf(modifier)); 96 | umlStr.append(name + "("); 97 | for(int i=0; i < parameters.size(); i++){ 98 | umlStr.append(parameters.get(i).getId().getName() + ": " + parameters.get(i).getType()); 99 | } 100 | // TODO Make sure more than one parameters could be added 101 | umlStr.append(")"); 102 | }else { 103 | umlStr.append(Modifiers.valueOf(modifier) + name + "()"); 104 | } 105 | 106 | return (type != null) ? umlStr.append(": " + type + "\n").toString() : umlStr.append(" \n").toString(); 107 | } 108 | 109 | /* (non-Javadoc) 110 | * @see java.lang.Object#hashCode() 111 | */ 112 | @Override 113 | public int hashCode() { 114 | // TODO Auto-generated method stub 115 | return super.hashCode(); 116 | } 117 | 118 | /* (non-Javadoc) 119 | * @see java.lang.Object#equals(java.lang.Object) 120 | */ 121 | @Override 122 | public boolean equals(Object obj) { 123 | if(!(obj instanceof UMLMethod)){ 124 | return false; 125 | } 126 | if(obj == this){ 127 | return true; 128 | } 129 | return this.getName().equalsIgnoreCase(((UMLMethod)obj).getName()); 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /class-diagram-gen/src/com/uml/parser/model/UMLVariable.java: -------------------------------------------------------------------------------- 1 | package com.uml.parser.model; 2 | import com.uml.parser.enums.Modifiers; 3 | 4 | import japa.parser.ast.type.Type; 5 | 6 | /** 7 | * Model representing variables in classes 8 | * @author rishi 9 | * 10 | */ 11 | public class UMLVariable { 12 | 13 | private int modifier; 14 | private String name; 15 | private String initialValue; 16 | private boolean isUMLClassType; 17 | private Type type; 18 | 19 | /** 20 | * @return the modifier 21 | */ 22 | public int getModifier() { 23 | return modifier; 24 | } 25 | /** 26 | * @param modifier the modifier to set 27 | */ 28 | public void setModifier(int modifier) { 29 | this.modifier = modifier; 30 | } 31 | /** 32 | * @return the name 33 | */ 34 | public String getName() { 35 | return name; 36 | } 37 | /** 38 | * @param name the name to set 39 | */ 40 | public void setName(String name) { 41 | this.name = name; 42 | } 43 | /** 44 | * @return the initialValue 45 | */ 46 | public String getInitialValue() { 47 | return initialValue; 48 | } 49 | /** 50 | * @param initialValue the initialValue to set 51 | */ 52 | public void setInitialValue(String initialValue) { 53 | this.initialValue = initialValue; 54 | } 55 | /** 56 | * @return the isUMLClassType 57 | */ 58 | public boolean isUMLClassType() { 59 | return isUMLClassType; 60 | } 61 | /** 62 | * @param isUMLClassType the isUMLClassType to set 63 | */ 64 | public void setUMLClassType(boolean isUMLClassType) { 65 | this.isUMLClassType = isUMLClassType; 66 | } 67 | /** 68 | * @return the type 69 | */ 70 | public Type getType() { 71 | return type; 72 | } 73 | /** 74 | * @param type the type to set 75 | */ 76 | public void setType(Type type) { 77 | this.type = type; 78 | } 79 | 80 | /** 81 | * Returns grammar for UML Class diagram 82 | * @return 83 | */ 84 | public String getUMLString(){ 85 | return Modifiers.valueOf(modifier) + name + ": " + type + initialValue + "\n"; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /class-diagram-gen/test-solutions/test1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rishirajrandive/uml-parser/3464d55bf4d1b2070fc9dd03b90e37d0af06bc0c/class-diagram-gen/test-solutions/test1.png -------------------------------------------------------------------------------- /class-diagram-gen/test-solutions/test2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rishirajrandive/uml-parser/3464d55bf4d1b2070fc9dd03b90e37d0af06bc0c/class-diagram-gen/test-solutions/test2.png -------------------------------------------------------------------------------- /class-diagram-gen/test-solutions/test3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rishirajrandive/uml-parser/3464d55bf4d1b2070fc9dd03b90e37d0af06bc0c/class-diagram-gen/test-solutions/test3.png -------------------------------------------------------------------------------- /class-diagram-gen/test-solutions/test4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rishirajrandive/uml-parser/3464d55bf4d1b2070fc9dd03b90e37d0af06bc0c/class-diagram-gen/test-solutions/test4.png -------------------------------------------------------------------------------- /class-diagram-gen/test-solutions/test5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rishirajrandive/uml-parser/3464d55bf4d1b2070fc9dd03b90e37d0af06bc0c/class-diagram-gen/test-solutions/test5.png -------------------------------------------------------------------------------- /images/class.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rishirajrandive/uml-parser/3464d55bf4d1b2070fc9dd03b90e37d0af06bc0c/images/class.png -------------------------------------------------------------------------------- /images/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rishirajrandive/uml-parser/3464d55bf4d1b2070fc9dd03b90e37d0af06bc0c/images/icon.png -------------------------------------------------------------------------------- /images/sequence.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rishirajrandive/uml-parser/3464d55bf4d1b2070fc9dd03b90e37d0af06bc0c/images/sequence.png -------------------------------------------------------------------------------- /images/webapp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rishirajrandive/uml-parser/3464d55bf4d1b2070fc9dd03b90e37d0af06bc0c/images/webapp.png -------------------------------------------------------------------------------- /sequence-diagram-gen/bin/.gitignore: -------------------------------------------------------------------------------- 1 | /sequence.zip 2 | /Makefile 3 | /sample.png 4 | -------------------------------------------------------------------------------- /sequence-diagram-gen/sequence-diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rishirajrandive/uml-parser/3464d55bf4d1b2070fc9dd03b90e37d0af06bc0c/sequence-diagram-gen/sequence-diagram.png -------------------------------------------------------------------------------- /sequence-diagram-gen/src/SequenceDiagramGenerator.java: -------------------------------------------------------------------------------- 1 | import java.io.BufferedOutputStream; 2 | import java.io.BufferedReader; 3 | import java.io.File; 4 | import java.io.FileInputStream; 5 | import java.io.FileOutputStream; 6 | import java.io.IOException; 7 | import java.io.InputStream; 8 | import java.io.InputStreamReader; 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | import java.util.zip.ZipEntry; 12 | import java.util.zip.ZipInputStream; 13 | 14 | public class SequenceDiagramGenerator { 15 | 16 | private static final int BUFFER_SIZE = 4096; 17 | 18 | public static void main(String[] args) { 19 | 20 | if (args.length < 1) { 21 | System.out.println("Invalid arguments, need two arguments!"); 22 | System.out.println("1. Complete folder path to Java files."); 23 | System.out.println("Output file will be of .png format so no need to enter extenstion"); 24 | return; 25 | } 26 | SequenceDiagramGenerator obj = new SequenceDiagramGenerator(); 27 | obj.startProcess(args[0]); 28 | obj.clearTestFolder(); 29 | } 30 | 31 | /** 32 | * Starts the process of UML class diagram generation 33 | * 34 | * @param inputPath 35 | * @param outputFileName 36 | */ 37 | private void startProcess(String inputPath) { 38 | if (inputPath.indexOf(".zip") != -1) { 39 | try { 40 | unzipAndProcess(inputPath); 41 | 42 | } catch (IOException e) { 43 | System.out.println("Failed to unzip the folder. \nNote: Keep the Java files in root folder of zip:\n" 44 | + e.getMessage()); 45 | } 46 | } else { 47 | File folder = new File(inputPath); 48 | if (folder == null || !folder.isDirectory()) { 49 | System.out.println("Folder path provided is not valid, please check -> " + inputPath); 50 | return; 51 | } 52 | processFiles(getFileListFromFolder(folder)); 53 | } 54 | } 55 | 56 | /** 57 | * Returns list of files from the folder 58 | * 59 | * @param folder 60 | * @return 61 | */ 62 | private List getFileListFromFolder(File folder) { 63 | List files = new ArrayList<>(); 64 | File[] filesInFolder = folder.listFiles(); 65 | for (int i = 0; filesInFolder != null && i < filesInFolder.length; i++) { 66 | File file = filesInFolder[i]; 67 | if (isValidFile(file)) { 68 | files.add(file); 69 | } 70 | } 71 | return files; 72 | } 73 | 74 | /** 75 | * Returns if the file is valid Java file or not 76 | * 77 | * @param file 78 | * @return 79 | */ 80 | private boolean isValidFile(File file) { 81 | if (file.isFile()) { 82 | if (file.getName().endsWith("java") && !file.getName().equalsIgnoreCase("RunUMLParser.java")) { 83 | return true; 84 | } 85 | } 86 | return false; 87 | } 88 | 89 | /** 90 | * Actual process on list of collected java file starts 91 | * 92 | * @param files 93 | * @param outputFileName 94 | */ 95 | private void processFiles(List files) { 96 | if (files.size() == 0) { 97 | System.out.println( 98 | "Folder path has no .java files, program works only for Java files. Check and re-run the program\n" 99 | + "If you are using Zip file make sure the Java files are in home directory of Zip file"); 100 | return; 101 | } 102 | 103 | try { 104 | Process processCompile = Runtime.getRuntime().exec( 105 | "/Users/rishi/aspectj1.8/bin/ajc -1.8 -cp .:lib/aspectjrt.jar:lib/plantuml.jar test-case/*.java test-case/*.aj"); 106 | printOutput(" Error:", processCompile.getErrorStream()); 107 | Process processRun = Runtime.getRuntime() 108 | .exec("java -cp .:lib/aspectjrt.jar:lib/plantuml.jar:test-case/ Main"); 109 | printOutput(" Output:", processRun.getInputStream()); 110 | printOutput(" Error:", processRun.getErrorStream()); 111 | } catch (IOException e) { 112 | System.out.println("Error generating UML Sequence diagram: " + e.getMessage()); 113 | } 114 | } 115 | 116 | /** 117 | * Extracts a zip file specified by the zipFilePath to a directory specified 118 | * by destDirectory (will be created if does not exists) 119 | * 120 | * @param zipFilePath 121 | * @param destDirectory 122 | * @throws IOException 123 | */ 124 | public void unzipAndProcess(String zipFilePath) throws IOException { 125 | String destDirectory = "test-case"; 126 | File destDir = new File(destDirectory); 127 | if (!destDir.exists()) { 128 | destDir.mkdir(); 129 | } 130 | 131 | ZipInputStream zipIn = new ZipInputStream(new FileInputStream(zipFilePath)); 132 | ZipEntry entry = zipIn.getNextEntry(); 133 | // iterates over entries in the zip file 134 | while (entry != null) { 135 | String filePath = destDirectory + File.separator + entry.getName(); 136 | if (!entry.isDirectory()) { 137 | // if the entry is a file, extracts it 138 | extractFile(zipIn, filePath); 139 | } else { 140 | // if the entry is a directory, make the directory 141 | File dir = new File(filePath); 142 | dir.mkdir(); 143 | } 144 | zipIn.closeEntry(); 145 | entry = zipIn.getNextEntry(); 146 | } 147 | zipIn.close(); 148 | 149 | File file = new File(destDir.getAbsolutePath()); 150 | processFiles(getFileListFromFolder(file)); 151 | } 152 | 153 | /** 154 | * Extracts a zip entry (file entry) 155 | * 156 | * @param zipIn 157 | * @param filePath 158 | * @throws IOException 159 | */ 160 | private void extractFile(ZipInputStream zipIn, String filePath) throws IOException { 161 | BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(filePath)); 162 | byte[] bytesIn = new byte[BUFFER_SIZE]; 163 | int read = 0; 164 | while ((read = zipIn.read(bytesIn)) != -1) { 165 | bos.write(bytesIn, 0, read); 166 | } 167 | bos.close(); 168 | } 169 | 170 | /** 171 | * Clears test folders once done 172 | */ 173 | private void clearTestFolder() { 174 | String destDirectory = "test-case"; 175 | File destDir = new File(destDirectory); 176 | if (destDir.exists()) { 177 | for (File file : destDir.listFiles()) { 178 | if (!file.getName().equals("SequenceGen.aj")) 179 | file.delete(); 180 | } 181 | } 182 | } 183 | 184 | /** 185 | * Print the output while generating the sequencesOs 186 | * 187 | * @param name 188 | * @param ins 189 | * @throws IOException 190 | */ 191 | private void printOutput(String name, InputStream ins) throws IOException { 192 | String line = null; 193 | BufferedReader in = new BufferedReader(new InputStreamReader(ins)); 194 | while ((line = in.readLine()) != null) { 195 | System.out.println(name + " " + line); 196 | } 197 | in.close(); 198 | } 199 | 200 | } 201 | -------------------------------------------------------------------------------- /sequence-diagram-gen/test-case/SequenceGen.aj: -------------------------------------------------------------------------------- 1 | import java.io.FileNotFoundException; 2 | import java.io.FileOutputStream; 3 | import java.io.IOException; 4 | import java.io.OutputStream; 5 | import java.util.HashMap; 6 | import java.util.Stack; 7 | 8 | import org.aspectj.lang.JoinPoint; 9 | import org.aspectj.lang.reflect.MethodSignature; 10 | 11 | import net.sourceforge.plantuml.SourceStringReader; 12 | 13 | /** 14 | * UML Sequence diagram generator. 15 | * 1. Ignores constructor calls 16 | * 2. On method execute start and finish entry added to PlantUML grammar 17 | * 3. Relevant activate and deactivate added 18 | * 4. Generate the diagram using PlantUML grammar 19 | * @author rishi 20 | * 21 | */ 22 | public aspect SequenceGen { 23 | 24 | private int callDepth; 25 | private static StringBuffer plantUmlString = new StringBuffer(); 26 | static boolean running; 27 | 28 | final pointcut constructorExecution(): !within(Participant) && !within(SequenceGen) && execution(*.new(..)); 29 | 30 | final pointcut traced() : !within(Participant) && !within(SequenceGen) && (execution(* *.*(..)) && !call(*.new(..))); 31 | 32 | private boolean isConstructorExecution = false; 33 | private HashMap objects = new HashMap<>(); 34 | private Stack stack = new Stack<>(); 35 | 36 | before(): constructorExecution() { 37 | isConstructorExecution = true; 38 | } 39 | 40 | after(): constructorExecution() { 41 | isConstructorExecution = false; 42 | } 43 | 44 | before() : traced() { 45 | print("Before", thisJoinPoint); 46 | callDepth++; 47 | } 48 | 49 | after() : traced() { 50 | callDepth--; 51 | if(callDepth == 0){ 52 | plantUmlString.append("@enduml\n"); 53 | generateUML(); 54 | } 55 | } 56 | 57 | private void print(String prefix, JoinPoint m) { 58 | if (!isConstructorExecution) { 59 | MethodSignature signature = (MethodSignature) m.getStaticPart().getSignature(); 60 | String methodName = signature.getName() + "("; 61 | String[] paramNames = signature.getParameterNames(); 62 | Class[] paramType = signature.getParameterTypes(); 63 | 64 | for (int i = 0; i < paramNames.length; i++) { 65 | methodName += paramNames[i] + " : " + paramType[i].getSimpleName(); 66 | if (i != paramNames.length - 1) { 67 | methodName += ", "; 68 | } 69 | } 70 | methodName += ") : " + signature.getReturnType().getSimpleName() + "()"; 71 | 72 | if (callDepth == 0) { 73 | System.out.println(callDepth + " " + m.getSignature().getDeclaringTypeName()); 74 | 75 | objects.put(callDepth, new Participant(m.getSignature().getDeclaringTypeName())); 76 | plantUmlString.append("@startuml\nhide footbox\n"); 77 | stack.add(callDepth); 78 | } else { 79 | if(callDepth <= stack.peek()){ 80 | while(!stack.isEmpty() && callDepth <= stack.peek()){ 81 | int objectId = stack.pop(); 82 | plantUmlString.append("deactivate " + objects.get(objectId).getName() + "\n"); 83 | objects.get(objectId).setActive(false); 84 | } 85 | if(callDepth == 1){ 86 | plantUmlString.append("deactivate " + objects.get(stack.peek()).getName() + "\n"); 87 | objects.get(stack.peek()).setActive(false); 88 | } 89 | } 90 | 91 | if(callDepth > stack.peek()){ 92 | objects.put(callDepth, new Participant(m.getThis().getClass().getSimpleName())); 93 | Participant parent = objects.get(stack.peek()); 94 | Participant child = objects.get(callDepth); 95 | plantUmlString.append(parent.getName() + "->" + child.getName() + ":" + methodName + "\n"); 96 | if(!parent.isActive()){ 97 | plantUmlString.append("activate " + parent.getName() + "\n"); 98 | parent.setActive(true); 99 | } 100 | if(!child.isActive()){ 101 | plantUmlString.append("activate " + child.getName() + "\n"); 102 | child.setActive(true); 103 | } 104 | stack.push(callDepth); 105 | } 106 | } 107 | } 108 | } 109 | 110 | private static void generateUML() { 111 | String outputFileName = "sequence-diagram"; 112 | String umlSource = plantUmlString.toString(); 113 | 114 | System.out.println(umlSource); 115 | try { 116 | OutputStream png = new FileOutputStream(outputFileName + ".png"); 117 | SourceStringReader reader = new SourceStringReader(umlSource); 118 | reader.generateImage(png); 119 | System.out.println( 120 | "Output UML Sequence diagram with name '" + outputFileName + ".png' is generated in base directory"); 121 | } catch (FileNotFoundException exception) { 122 | System.err.println("Failed to create output file " + exception.getMessage()); 123 | } catch (IOException exception) { 124 | System.err.println("Failed to write to output file " + exception.getMessage()); 125 | } 126 | } 127 | 128 | } 129 | 130 | /** 131 | * To hold the participant in the UML sequence diagram. 132 | * Helps to keep track if the participant already active or not. 133 | * @author rishi 134 | * 135 | */ 136 | class Participant{ 137 | boolean isActive; 138 | String name; 139 | 140 | public Participant() { 141 | isActive = false; 142 | } 143 | 144 | public Participant(String name) { 145 | this.name = name; 146 | this.isActive = false; 147 | } 148 | 149 | public Participant(boolean isActive, String name) { 150 | this.isActive = isActive; 151 | this.name = name; 152 | } 153 | 154 | /** 155 | * @return the isActive 156 | */ 157 | public boolean isActive() { 158 | return isActive; 159 | } 160 | 161 | /** 162 | * @param isActive the isActive to set 163 | */ 164 | public void setActive(boolean isActive) { 165 | this.isActive = isActive; 166 | } 167 | 168 | /** 169 | * @return the name 170 | */ 171 | public String getName() { 172 | return name; 173 | } 174 | 175 | /** 176 | * @param name the name to set 177 | */ 178 | public void setName(String name) { 179 | this.name = name; 180 | } 181 | } 182 | -------------------------------------------------------------------------------- /uml-parser-webapp/.idea/jsLibraryMappings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /uml-parser-webapp/.idea/libraries/uml_parser_webapp_node_modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /uml-parser-webapp/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /uml-parser-webapp/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /uml-parser-webapp/.idea/uml-parser-webapp.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /uml-parser-webapp/.idea/workspace.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 17 | 18 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 106 | 107 | 108 | 121 | 122 | 123 | 124 | 125 | true 126 | DEFINITION_ORDER 127 | 128 | 129 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 166 | 167 | 168 | 169 | 172 | 173 | 176 | 177 | 178 | 179 | 182 | 183 | 186 | 187 | 190 | 191 | 192 | 193 | 196 | 197 | 200 | 201 | 204 | 205 | 208 | 209 | 210 | 211 | 214 | 215 | 218 | 219 | 222 | 223 | 224 | 225 | 228 | 229 | 232 | 233 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 288 | 289 | project 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | project 306 | 307 | 308 | true 309 | 310 | 311 | 312 | DIRECTORY 313 | 314 | false 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 329 | 330 | 331 | 332 | 1493011376166 333 | 340 | 341 | 342 | 343 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 389 | 392 | 393 | 394 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 | 534 | 535 | 536 | 537 | 538 | 539 | 540 | 541 | 542 | 543 | 544 | 545 | 546 | 547 | 548 | 549 | 550 | 551 | 552 | 553 | 554 | 555 | 556 | 557 | 558 | 559 | 560 | 561 | 562 | 563 | 564 | 565 | 566 | 567 | 568 | 569 | 570 | 571 | 572 | 573 | 574 | 575 | 576 | 577 | 578 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | -------------------------------------------------------------------------------- /uml-parser-webapp/app.js: -------------------------------------------------------------------------------- 1 | 2 | var express = require('express'); 3 | var path = require('path'); 4 | var favicon = require('serve-favicon'); 5 | var logger = require('morgan'); 6 | var cookieParser = require('cookie-parser'); 7 | var bodyParser = require('body-parser'); 8 | var session = require('client-sessions'); 9 | var formidable = require('formidable'); 10 | var fs = require('fs'); 11 | var exec = require('child_process').exec; 12 | 13 | var home = require('./routes/home'); 14 | 15 | var app = express(); 16 | var fileName = ''; 17 | 18 | // all environments 19 | //configure the sessions with our application 20 | app.use(session({cookieName: 'session', secret: 'auto_exchange_session', 21 | duration: 30 * 60 * 1000, //setting the time for active session 22 | activeDuration: 5 * 60 * 1000, })); // setting time for the session to be active when the window is open // 5 minutes set currently 23 | 24 | // view engine setup 25 | app.set('views', path.join(__dirname, 'views')); 26 | app.set('view engine', 'ejs'); 27 | 28 | // uncomment after placing your favicon in /public 29 | //app.use(favicon(path.join(__dirname, 'public', 'favicon.ico'))); 30 | app.use(logger('dev')); 31 | app.use(bodyParser.json()); 32 | app.use(bodyParser.urlencoded({ extended: false })); 33 | app.use(cookieParser()); 34 | app.use(express.static(path.join(__dirname, 'public'))); 35 | app.use(express.static(path.join(__dirname, 'bin'))); 36 | 37 | app.use('/', home); 38 | 39 | app.post('/upload', function(req, res){ 40 | 41 | // create an incoming form object 42 | var form = new formidable.IncomingForm(); 43 | 44 | // specify that we want to allow the user to upload multiple files in a single request 45 | form.multiples = false; 46 | 47 | // store all uploads in the /uploads directory 48 | form.uploadDir = path.join(__dirname, '/uploads'); 49 | 50 | // every time a file has been uploaded successfully, 51 | // rename it to it's orignal name 52 | form.on('file', function(field, file) { 53 | fs.rename(file.path, path.join(form.uploadDir, file.name)); 54 | fileName = file.name; 55 | }); 56 | 57 | // log any errors that occur 58 | form.on('error', function(err) { 59 | console.log('An error has occured: \n' + err); 60 | }); 61 | 62 | // once all the files have been uploaded, send a response to the client 63 | form.on('end', function() { 64 | res.end('success'); 65 | }); 66 | 67 | // parse the incoming request containing the form data 68 | form.parse(req); 69 | 70 | }); 71 | 72 | app.get('/generate', function (req, res) { 73 | var jarPath = path.join(__dirname, '/jar/UMLClassDiagramGen.jar'); 74 | var zipPath = path.join(__dirname, '/uploads/' + fileName); 75 | var d = new Date(); 76 | var umlOutputFileName = 'class-diagram-' + d.getTime(); 77 | var child = exec('java -jar ' + jarPath + ' ' + zipPath + ' ' + umlOutputFileName, 78 | function (error, stdout, stderr){ 79 | res.send({"status": 200, "data": umlOutputFileName}); 80 | if(error !== null){ 81 | res.send({"status": 400, "data": 'Failed to generate UML Class diagram'}); 82 | } 83 | }); 84 | }); 85 | 86 | // catch 404 and forward to error handler 87 | app.use(function(req, res, next) { 88 | var err = new Error('Not Found'); 89 | err.status = 404; 90 | next(err); 91 | }); 92 | 93 | // error handler 94 | app.use(function(err, req, res, next) { 95 | // set locals, only providing error in development 96 | res.locals.message = err.message; 97 | res.locals.error = req.app.get('env') === 'development' ? err : {}; 98 | 99 | // render the error page 100 | res.status(err.status || 500); 101 | res.render('error'); 102 | }); 103 | 104 | module.exports = app; 105 | -------------------------------------------------------------------------------- /uml-parser-webapp/bin/PlantUMLGrammar.txt: -------------------------------------------------------------------------------- 1 | @startuml 2 | skinparam classAttributeIconSize 0 3 | interface Component << interface >> { 4 | + {abstract}operation(): String 5 | } 6 | 7 | class ConcreteComponent { 8 | +operation(): String 9 | } 10 | 11 | class ConcreteDecoratorA { 12 | +ConcreteDecoratorA(c: Component) 13 | +operation(): String 14 | -addedState: String 15 | } 16 | 17 | class Decorator { 18 | +Decorator(c: Component) 19 | +operation(): String 20 | } 21 | 22 | class ConcreteDecoratorB { 23 | +ConcreteDecoratorB(c: Component) 24 | +operation(): String 25 | -addedState: String 26 | } 27 | 28 | class Tester { 29 | + {static}main(args: String[]): void 30 | } 31 | 32 | ConcreteComponent..|>Component 33 | 34 | ConcreteDecoratorA--|>Decorator 35 | 36 | ConcreteDecoratorA..>Component 37 | 38 | ConcreteDecoratorB--|>Decorator 39 | 40 | ConcreteDecoratorB..>Component 41 | 42 | Decorator..|>Component 43 | 44 | Decorator--Component 45 | 46 | Decorator..>Component 47 | 48 | Tester..>Component 49 | 50 | hide circle 51 | @enduml -------------------------------------------------------------------------------- /uml-parser-webapp/bin/class-diagram-1493595773602.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rishirajrandive/uml-parser/3464d55bf4d1b2070fc9dd03b90e37d0af06bc0c/uml-parser-webapp/bin/class-diagram-1493595773602.png -------------------------------------------------------------------------------- /uml-parser-webapp/bin/class-diagram-1493595785438.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rishirajrandive/uml-parser/3464d55bf4d1b2070fc9dd03b90e37d0af06bc0c/uml-parser-webapp/bin/class-diagram-1493595785438.png -------------------------------------------------------------------------------- /uml-parser-webapp/bin/class-diagram-1493595800038.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rishirajrandive/uml-parser/3464d55bf4d1b2070fc9dd03b90e37d0af06bc0c/uml-parser-webapp/bin/class-diagram-1493595800038.png -------------------------------------------------------------------------------- /uml-parser-webapp/bin/class-diagram-1493595812807.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rishirajrandive/uml-parser/3464d55bf4d1b2070fc9dd03b90e37d0af06bc0c/uml-parser-webapp/bin/class-diagram-1493595812807.png -------------------------------------------------------------------------------- /uml-parser-webapp/bin/class-diagram-1493595827831.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rishirajrandive/uml-parser/3464d55bf4d1b2070fc9dd03b90e37d0af06bc0c/uml-parser-webapp/bin/class-diagram-1493595827831.png -------------------------------------------------------------------------------- /uml-parser-webapp/bin/www: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | /** 4 | * Module dependencies. 5 | */ 6 | 7 | var app = require('../app'); 8 | var debug = require('debug')('auto-exchange:server'); 9 | var http = require('http'); 10 | 11 | /** 12 | * Get port from environment and store in Express. 13 | */ 14 | 15 | var port = normalizePort(process.env.PORT || '3000'); 16 | app.set('port', port); 17 | 18 | /** 19 | * Create HTTP server. 20 | */ 21 | 22 | var server = http.createServer(app); 23 | 24 | /** 25 | * Listen on provided port, on all network interfaces. 26 | */ 27 | 28 | server.listen(port); 29 | server.on('error', onError); 30 | server.on('listening', onListening); 31 | 32 | /** 33 | * Normalize a port into a number, string, or false. 34 | */ 35 | 36 | function normalizePort(val) { 37 | var port = parseInt(val, 10); 38 | 39 | if (isNaN(port)) { 40 | // named pipe 41 | return val; 42 | } 43 | 44 | if (port >= 0) { 45 | // port number 46 | return port; 47 | } 48 | 49 | return false; 50 | } 51 | 52 | /** 53 | * Event listener for HTTP server "error" event. 54 | */ 55 | 56 | function onError(error) { 57 | if (error.syscall !== 'listen') { 58 | throw error; 59 | } 60 | 61 | var bind = typeof port === 'string' 62 | ? 'Pipe ' + port 63 | : 'Port ' + port; 64 | 65 | // handle specific listen errors with friendly messages 66 | switch (error.code) { 67 | case 'EACCES': 68 | console.error(bind + ' requires elevated privileges'); 69 | process.exit(1); 70 | break; 71 | case 'EADDRINUSE': 72 | console.error(bind + ' is already in use'); 73 | process.exit(1); 74 | break; 75 | default: 76 | throw error; 77 | } 78 | } 79 | 80 | /** 81 | * Event listener for HTTP server "listening" event. 82 | */ 83 | 84 | function onListening() { 85 | var addr = server.address(); 86 | var bind = typeof addr === 'string' 87 | ? 'pipe ' + addr 88 | : 'port ' + addr.port; 89 | debug('Listening on ' + bind); 90 | } 91 | -------------------------------------------------------------------------------- /uml-parser-webapp/images/branches.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rishirajrandive/uml-parser/3464d55bf4d1b2070fc9dd03b90e37d0af06bc0c/uml-parser-webapp/images/branches.png -------------------------------------------------------------------------------- /uml-parser-webapp/images/cars.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rishirajrandive/uml-parser/3464d55bf4d1b2070fc9dd03b90e37d0af06bc0c/uml-parser-webapp/images/cars.png -------------------------------------------------------------------------------- /uml-parser-webapp/images/customers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rishirajrandive/uml-parser/3464d55bf4d1b2070fc9dd03b90e37d0af06bc0c/uml-parser-webapp/images/customers.png -------------------------------------------------------------------------------- /uml-parser-webapp/images/homepage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rishirajrandive/uml-parser/3464d55bf4d1b2070fc9dd03b90e37d0af06bc0c/uml-parser-webapp/images/homepage.png -------------------------------------------------------------------------------- /uml-parser-webapp/images/transaction.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rishirajrandive/uml-parser/3464d55bf4d1b2070fc9dd03b90e37d0af06bc0c/uml-parser-webapp/images/transaction.png -------------------------------------------------------------------------------- /uml-parser-webapp/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "auto-exchange", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "start": "node ./bin/www", 7 | "test": "mocha" 8 | }, 9 | "dependencies": { 10 | "body-parser": "~1.15.2", 11 | "client-sessions": "^0.7.0", 12 | "cookie-parser": "~1.4.3", 13 | "debug": "~2.2.0", 14 | "ejs": "~2.5.2", 15 | "express": "~4.14.0", 16 | "formidable": "^1.1.1", 17 | "log4js": "^1.0.1", 18 | "morgan": "~1.7.0", 19 | "request": "^2.79.0", 20 | "serve-favicon": "~2.3.0" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /uml-parser-webapp/public/javascripts/upload.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by rishi on 4/23/17. 3 | */ 4 | 5 | $('.upload-btn').on('click', function (){ 6 | $('#upload-input').click(); 7 | $('.progress-bar').text('0%'); 8 | $('.progress-bar').width('0%'); 9 | $('#placeholder').show(); 10 | $('#output-img > img').remove(); 11 | $('#output-img').hide(); 12 | }); 13 | 14 | $('#upload-input').on('change', function(){ 15 | 16 | var files = $(this).get(0).files; 17 | 18 | if (files.length > 0){ 19 | // create a FormData object which will be sent as the data payload in the 20 | // AJAX request 21 | var formData = new FormData(); 22 | 23 | // loop through all the selected files and add them to the formData object 24 | for (var i = 0; i < files.length; i++) { 25 | var file = files[i]; 26 | 27 | // add the files to formData object for the data payload 28 | formData.append('uploads[]', file, file.name); 29 | } 30 | 31 | $.ajax({ 32 | url: '/upload', 33 | type: 'POST', 34 | data: formData, 35 | processData: false, 36 | contentType: false, 37 | success: function(data){ 38 | $('.upload-btn').hide(); 39 | $('.submit-btn').show(); 40 | }, 41 | xhr: function() { 42 | // create an XMLHttpRequest 43 | var xhr = new XMLHttpRequest(); 44 | 45 | // listen to the 'progress' event 46 | xhr.upload.addEventListener('progress', function(evt) { 47 | 48 | if (evt.lengthComputable) { 49 | // calculate the percentage of upload completed 50 | var percentComplete = evt.loaded / evt.total; 51 | percentComplete = parseInt(percentComplete * 100); 52 | 53 | // update the Bootstrap progress bar with the new percentage 54 | $('.progress-bar').text(percentComplete + '%'); 55 | $('.progress-bar').width(percentComplete + '%'); 56 | 57 | // once the upload reaches 100%, set the progress bar text to done 58 | if (percentComplete === 100) { 59 | $('.progress-bar').html('Done'); 60 | } 61 | 62 | } 63 | 64 | }, false); 65 | 66 | return xhr; 67 | } 68 | }); 69 | 70 | } 71 | }); 72 | 73 | 74 | $('.submit-btn').on('click', function () { 75 | $.ajax({ 76 | url: '/generate', 77 | type: 'get', 78 | data: '', 79 | processData: false, 80 | contentType: false, 81 | success: function(res){ 82 | if(res.status == 200){ 83 | $('.submit-btn').hide(); 84 | $('.upload-btn').show(); 85 | $('#placeholder').hide(); 86 | var imageName = res.data + '.png'; 87 | $('#output-img').append("Output image"); 88 | $('.uml-output').attr('src', imageName); 89 | $('#output-img').show(); 90 | }else { 91 | console.log('UML Class diagram generation failed'); 92 | } 93 | 94 | } 95 | }); 96 | }); 97 | -------------------------------------------------------------------------------- /uml-parser-webapp/public/stylesheets/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding: 10px; 3 | font: 14px "Lucida Grande", Helvetica, Arial, sans-serif; 4 | } 5 | 6 | .padding-body{ 7 | padding: 10px; 8 | } 9 | 10 | a { 11 | color: #00B7FF; 12 | } 13 | 14 | .glyphicon-plus-sign { 15 | font-size: 22px; 16 | } 17 | 18 | 19 | 20 | .row-select { 21 | background-color: #a7dbd8; 22 | } 23 | 24 | .btn:focus, .upload-btn:focus, .submit-btn:focus{ 25 | outline: 0 !important; 26 | } 27 | 28 | html, 29 | body { 30 | height: 100%; 31 | background-color: #4791D2; 32 | } 33 | 34 | body { 35 | text-align: center; 36 | font-family: 'Raleway', sans-serif; 37 | } 38 | 39 | .row { 40 | margin-top: 20px; 41 | } 42 | 43 | .upload-btn, .submit-btn { 44 | color: #ffffff; 45 | background-color: #F89406; 46 | border: none; 47 | } 48 | 49 | .upload-btn:hover, 50 | .upload-btn:focus, 51 | .upload-btn:active, 52 | .submit-btn:hover, 53 | .submit-btn:focus, 54 | .submit-btn:active{ 55 | color: #ffffff; 56 | background-color: #FA8900; 57 | border: none; 58 | } 59 | 60 | h4 { 61 | padding-bottom: 30px; 62 | color: #B8BDC1; 63 | } 64 | 65 | .glyphicon { 66 | font-size: 5em; 67 | color: #9CA3A9; 68 | } 69 | 70 | h2 { 71 | margin-top: 15px; 72 | color: #68757E; 73 | } 74 | 75 | .panel { 76 | padding-top: 20px; 77 | padding-bottom: 20px; 78 | } 79 | 80 | #upload-input { 81 | display: none; 82 | } 83 | 84 | .h1{ 85 | color: white; 86 | } 87 | 88 | /*@media (min-width: 768px) {*/ 89 | /*.main-container {*/ 90 | /*width: 100%;*/ 91 | /*}*/ 92 | /*}*/ 93 | 94 | /*@media (min-width: 992px) {*/ 95 | /*.container {*/ 96 | /*width: 450px;*/ 97 | /*}*/ 98 | /*}*/ 99 | 100 | .download-btn{ 101 | position: absolute; 102 | bottom: 0; 103 | right: 0; 104 | margin-bottom: 30px; 105 | margin-right: 30px; 106 | } 107 | 108 | .download-btn .glyphicon{ 109 | font-size: 22px; 110 | } -------------------------------------------------------------------------------- /uml-parser-webapp/routes/home.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by rishi on 11/23/16. 3 | */ 4 | 5 | var express = require('express'); 6 | var router = express.Router(); 7 | 8 | /* GET home page. */ 9 | router.get('/', function(req, res, next) { 10 | res.render("homepage",{title: 'Auto Exchange'}); 11 | }); 12 | 13 | 14 | module.exports = router; 15 | -------------------------------------------------------------------------------- /uml-parser-webapp/uploads/test1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rishirajrandive/uml-parser/3464d55bf4d1b2070fc9dd03b90e37d0af06bc0c/uml-parser-webapp/uploads/test1.zip -------------------------------------------------------------------------------- /uml-parser-webapp/uploads/test2.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rishirajrandive/uml-parser/3464d55bf4d1b2070fc9dd03b90e37d0af06bc0c/uml-parser-webapp/uploads/test2.zip -------------------------------------------------------------------------------- /uml-parser-webapp/uploads/test3.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rishirajrandive/uml-parser/3464d55bf4d1b2070fc9dd03b90e37d0af06bc0c/uml-parser-webapp/uploads/test3.zip -------------------------------------------------------------------------------- /uml-parser-webapp/uploads/test4.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rishirajrandive/uml-parser/3464d55bf4d1b2070fc9dd03b90e37d0af06bc0c/uml-parser-webapp/uploads/test4.zip -------------------------------------------------------------------------------- /uml-parser-webapp/uploads/test5.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rishirajrandive/uml-parser/3464d55bf4d1b2070fc9dd03b90e37d0af06bc0c/uml-parser-webapp/uploads/test5.zip -------------------------------------------------------------------------------- /uml-parser-webapp/uploads/upload_fb1ca40ccaa7d99a34cd9b2f9dd4fdbf: -------------------------------------------------------------------------------- 1 | pos/pos-0.pgm 1 0 0 100 40 2 | pos/pos-1.pgm 1 0 0 100 40 3 | pos/pos-2.pgm 1 0 0 100 40 4 | pos/pos-3.pgm 1 0 0 100 40 5 | pos/pos-4.pgm 1 0 0 100 40 6 | pos/pos-5.pgm 1 0 0 100 40 7 | pos/pos-6.pgm 1 0 0 100 40 8 | pos/pos-7.pgm 1 0 0 100 40 9 | pos/pos-8.pgm 1 0 0 100 40 10 | pos/pos-9.pgm 1 0 0 100 40 11 | pos/pos-10.pgm 1 0 0 100 40 12 | pos/pos-11.pgm 1 0 0 100 40 13 | pos/pos-12.pgm 1 0 0 100 40 14 | pos/pos-13.pgm 1 0 0 100 40 15 | pos/pos-14.pgm 1 0 0 100 40 16 | pos/pos-15.pgm 1 0 0 100 40 17 | pos/pos-16.pgm 1 0 0 100 40 18 | pos/pos-17.pgm 1 0 0 100 40 19 | pos/pos-18.pgm 1 0 0 100 40 20 | pos/pos-19.pgm 1 0 0 100 40 21 | pos/pos-20.pgm 1 0 0 100 40 22 | pos/pos-21.pgm 1 0 0 100 40 23 | pos/pos-22.pgm 1 0 0 100 40 24 | pos/pos-23.pgm 1 0 0 100 40 25 | pos/pos-24.pgm 1 0 0 100 40 26 | pos/pos-25.pgm 1 0 0 100 40 27 | pos/pos-26.pgm 1 0 0 100 40 28 | pos/pos-27.pgm 1 0 0 100 40 29 | pos/pos-28.pgm 1 0 0 100 40 30 | pos/pos-29.pgm 1 0 0 100 40 31 | pos/pos-30.pgm 1 0 0 100 40 32 | pos/pos-31.pgm 1 0 0 100 40 33 | pos/pos-32.pgm 1 0 0 100 40 34 | pos/pos-33.pgm 1 0 0 100 40 35 | pos/pos-34.pgm 1 0 0 100 40 36 | pos/pos-35.pgm 1 0 0 100 40 37 | pos/pos-36.pgm 1 0 0 100 40 38 | pos/pos-37.pgm 1 0 0 100 40 39 | pos/pos-38.pgm 1 0 0 100 40 40 | pos/pos-39.pgm 1 0 0 100 40 41 | pos/pos-40.pgm 1 0 0 100 40 42 | pos/pos-41.pgm 1 0 0 100 40 43 | pos/pos-42.pgm 1 0 0 100 40 44 | pos/pos-43.pgm 1 0 0 100 40 45 | pos/pos-44.pgm 1 0 0 100 40 46 | pos/pos-45.pgm 1 0 0 100 40 47 | pos/pos-46.pgm 1 0 0 100 40 48 | pos/pos-47.pgm 1 0 0 100 40 49 | pos/pos-48.pgm 1 0 0 100 40 50 | pos/pos-49.pgm 1 0 0 100 40 51 | pos/pos-50.pgm 1 0 0 100 40 52 | pos/pos-51.pgm 1 0 0 100 40 53 | pos/pos-52.pgm 1 0 0 100 40 54 | pos/pos-53.pgm 1 0 0 100 40 55 | pos/pos-54.pgm 1 0 0 100 40 56 | pos/pos-55.pgm 1 0 0 100 40 57 | pos/pos-56.pgm 1 0 0 100 40 58 | pos/pos-57.pgm 1 0 0 100 40 59 | pos/pos-58.pgm 1 0 0 100 40 60 | pos/pos-59.pgm 1 0 0 100 40 61 | pos/pos-60.pgm 1 0 0 100 40 62 | pos/pos-61.pgm 1 0 0 100 40 63 | pos/pos-62.pgm 1 0 0 100 40 64 | pos/pos-63.pgm 1 0 0 100 40 65 | pos/pos-64.pgm 1 0 0 100 40 66 | pos/pos-65.pgm 1 0 0 100 40 67 | pos/pos-66.pgm 1 0 0 100 40 68 | pos/pos-67.pgm 1 0 0 100 40 69 | pos/pos-68.pgm 1 0 0 100 40 70 | pos/pos-69.pgm 1 0 0 100 40 71 | pos/pos-70.pgm 1 0 0 100 40 72 | pos/pos-71.pgm 1 0 0 100 40 73 | pos/pos-72.pgm 1 0 0 100 40 74 | pos/pos-73.pgm 1 0 0 100 40 75 | pos/pos-74.pgm 1 0 0 100 40 76 | pos/pos-75.pgm 1 0 0 100 40 77 | pos/pos-76.pgm 1 0 0 100 40 78 | pos/pos-77.pgm 1 0 0 100 40 79 | pos/pos-78.pgm 1 0 0 100 40 80 | pos/pos-79.pgm 1 0 0 100 40 81 | pos/pos-80.pgm 1 0 0 100 40 82 | pos/pos-81.pgm 1 0 0 100 40 83 | pos/pos-82.pgm 1 0 0 100 40 84 | pos/pos-83.pgm 1 0 0 100 40 85 | pos/pos-84.pgm 1 0 0 100 40 86 | pos/pos-85.pgm 1 0 0 100 40 87 | pos/pos-86.pgm 1 0 0 100 40 88 | pos/pos-87.pgm 1 0 0 100 40 89 | pos/pos-88.pgm 1 0 0 100 40 90 | pos/pos-89.pgm 1 0 0 100 40 91 | pos/pos-90.pgm 1 0 0 100 40 92 | pos/pos-91.pgm 1 0 0 100 40 93 | pos/pos-92.pgm 1 0 0 100 40 94 | pos/pos-93.pgm 1 0 0 100 40 95 | pos/pos-94.pgm 1 0 0 100 40 96 | pos/pos-95.pgm 1 0 0 100 40 97 | pos/pos-96.pgm 1 0 0 100 40 98 | pos/pos-97.pgm 1 0 0 100 40 99 | pos/pos-98.pgm 1 0 0 100 40 100 | pos/pos-99.pgm 1 0 0 100 40 101 | pos/pos-100.pgm 1 0 0 100 40 102 | pos/pos-101.pgm 1 0 0 100 40 103 | pos/pos-102.pgm 1 0 0 100 40 104 | pos/pos-103.pgm 1 0 0 100 40 105 | pos/pos-104.pgm 1 0 0 100 40 106 | pos/pos-105.pgm 1 0 0 100 40 107 | pos/pos-106.pgm 1 0 0 100 40 108 | pos/pos-107.pgm 1 0 0 100 40 109 | pos/pos-108.pgm 1 0 0 100 40 110 | pos/pos-109.pgm 1 0 0 100 40 111 | pos/pos-110.pgm 1 0 0 100 40 112 | pos/pos-111.pgm 1 0 0 100 40 113 | pos/pos-112.pgm 1 0 0 100 40 114 | pos/pos-113.pgm 1 0 0 100 40 115 | pos/pos-114.pgm 1 0 0 100 40 116 | pos/pos-115.pgm 1 0 0 100 40 117 | pos/pos-116.pgm 1 0 0 100 40 118 | pos/pos-117.pgm 1 0 0 100 40 119 | pos/pos-118.pgm 1 0 0 100 40 120 | pos/pos-119.pgm 1 0 0 100 40 121 | pos/pos-120.pgm 1 0 0 100 40 122 | pos/pos-121.pgm 1 0 0 100 40 123 | pos/pos-122.pgm 1 0 0 100 40 124 | pos/pos-123.pgm 1 0 0 100 40 125 | pos/pos-124.pgm 1 0 0 100 40 126 | pos/pos-125.pgm 1 0 0 100 40 127 | pos/pos-126.pgm 1 0 0 100 40 128 | pos/pos-127.pgm 1 0 0 100 40 129 | pos/pos-128.pgm 1 0 0 100 40 130 | pos/pos-129.pgm 1 0 0 100 40 131 | pos/pos-130.pgm 1 0 0 100 40 132 | pos/pos-131.pgm 1 0 0 100 40 133 | pos/pos-132.pgm 1 0 0 100 40 134 | pos/pos-133.pgm 1 0 0 100 40 135 | pos/pos-134.pgm 1 0 0 100 40 136 | pos/pos-135.pgm 1 0 0 100 40 137 | pos/pos-136.pgm 1 0 0 100 40 138 | pos/pos-137.pgm 1 0 0 100 40 139 | pos/pos-138.pgm 1 0 0 100 40 140 | pos/pos-139.pgm 1 0 0 100 40 141 | pos/pos-140.pgm 1 0 0 100 40 142 | pos/pos-141.pgm 1 0 0 100 40 143 | pos/pos-142.pgm 1 0 0 100 40 144 | pos/pos-143.pgm 1 0 0 100 40 145 | pos/pos-144.pgm 1 0 0 100 40 146 | pos/pos-145.pgm 1 0 0 100 40 147 | pos/pos-146.pgm 1 0 0 100 40 148 | pos/pos-147.pgm 1 0 0 100 40 149 | pos/pos-148.pgm 1 0 0 100 40 150 | pos/pos-149.pgm 1 0 0 100 40 151 | pos/pos-150.pgm 1 0 0 100 40 152 | pos/pos-151.pgm 1 0 0 100 40 153 | pos/pos-152.pgm 1 0 0 100 40 154 | pos/pos-153.pgm 1 0 0 100 40 155 | pos/pos-154.pgm 1 0 0 100 40 156 | pos/pos-155.pgm 1 0 0 100 40 157 | pos/pos-156.pgm 1 0 0 100 40 158 | pos/pos-157.pgm 1 0 0 100 40 159 | pos/pos-158.pgm 1 0 0 100 40 160 | pos/pos-159.pgm 1 0 0 100 40 161 | pos/pos-160.pgm 1 0 0 100 40 162 | pos/pos-161.pgm 1 0 0 100 40 163 | pos/pos-162.pgm 1 0 0 100 40 164 | pos/pos-163.pgm 1 0 0 100 40 165 | pos/pos-164.pgm 1 0 0 100 40 166 | pos/pos-165.pgm 1 0 0 100 40 167 | pos/pos-166.pgm 1 0 0 100 40 168 | pos/pos-167.pgm 1 0 0 100 40 169 | pos/pos-168.pgm 1 0 0 100 40 170 | pos/pos-169.pgm 1 0 0 100 40 171 | pos/pos-170.pgm 1 0 0 100 40 172 | pos/pos-171.pgm 1 0 0 100 40 173 | pos/pos-172.pgm 1 0 0 100 40 174 | pos/pos-173.pgm 1 0 0 100 40 175 | pos/pos-174.pgm 1 0 0 100 40 176 | pos/pos-175.pgm 1 0 0 100 40 177 | pos/pos-176.pgm 1 0 0 100 40 178 | pos/pos-177.pgm 1 0 0 100 40 179 | pos/pos-178.pgm 1 0 0 100 40 180 | pos/pos-179.pgm 1 0 0 100 40 181 | pos/pos-180.pgm 1 0 0 100 40 182 | pos/pos-181.pgm 1 0 0 100 40 183 | pos/pos-182.pgm 1 0 0 100 40 184 | pos/pos-183.pgm 1 0 0 100 40 185 | pos/pos-184.pgm 1 0 0 100 40 186 | pos/pos-185.pgm 1 0 0 100 40 187 | pos/pos-186.pgm 1 0 0 100 40 188 | pos/pos-187.pgm 1 0 0 100 40 189 | pos/pos-188.pgm 1 0 0 100 40 190 | pos/pos-189.pgm 1 0 0 100 40 191 | pos/pos-190.pgm 1 0 0 100 40 192 | pos/pos-191.pgm 1 0 0 100 40 193 | pos/pos-192.pgm 1 0 0 100 40 194 | pos/pos-193.pgm 1 0 0 100 40 195 | pos/pos-194.pgm 1 0 0 100 40 196 | pos/pos-195.pgm 1 0 0 100 40 197 | pos/pos-196.pgm 1 0 0 100 40 198 | pos/pos-197.pgm 1 0 0 100 40 199 | pos/pos-198.pgm 1 0 0 100 40 200 | pos/pos-199.pgm 1 0 0 100 40 201 | pos/pos-200.pgm 1 0 0 100 40 202 | pos/pos-201.pgm 1 0 0 100 40 203 | pos/pos-202.pgm 1 0 0 100 40 204 | pos/pos-203.pgm 1 0 0 100 40 205 | pos/pos-204.pgm 1 0 0 100 40 206 | pos/pos-205.pgm 1 0 0 100 40 207 | pos/pos-206.pgm 1 0 0 100 40 208 | pos/pos-207.pgm 1 0 0 100 40 209 | pos/pos-208.pgm 1 0 0 100 40 210 | pos/pos-209.pgm 1 0 0 100 40 211 | pos/pos-210.pgm 1 0 0 100 40 212 | pos/pos-211.pgm 1 0 0 100 40 213 | pos/pos-212.pgm 1 0 0 100 40 214 | pos/pos-213.pgm 1 0 0 100 40 215 | pos/pos-214.pgm 1 0 0 100 40 216 | pos/pos-215.pgm 1 0 0 100 40 217 | pos/pos-216.pgm 1 0 0 100 40 218 | pos/pos-217.pgm 1 0 0 100 40 219 | pos/pos-218.pgm 1 0 0 100 40 220 | pos/pos-219.pgm 1 0 0 100 40 221 | pos/pos-220.pgm 1 0 0 100 40 222 | pos/pos-221.pgm 1 0 0 100 40 223 | pos/pos-222.pgm 1 0 0 100 40 224 | pos/pos-223.pgm 1 0 0 100 40 225 | pos/pos-224.pgm 1 0 0 100 40 226 | pos/pos-225.pgm 1 0 0 100 40 227 | pos/pos-226.pgm 1 0 0 100 40 228 | pos/pos-227.pgm 1 0 0 100 40 229 | pos/pos-228.pgm 1 0 0 100 40 230 | pos/pos-229.pgm 1 0 0 100 40 231 | pos/pos-230.pgm 1 0 0 100 40 232 | pos/pos-231.pgm 1 0 0 100 40 233 | pos/pos-232.pgm 1 0 0 100 40 234 | pos/pos-233.pgm 1 0 0 100 40 235 | pos/pos-234.pgm 1 0 0 100 40 236 | pos/pos-235.pgm 1 0 0 100 40 237 | pos/pos-236.pgm 1 0 0 100 40 238 | pos/pos-237.pgm 1 0 0 100 40 239 | pos/pos-238.pgm 1 0 0 100 40 240 | pos/pos-239.pgm 1 0 0 100 40 241 | pos/pos-240.pgm 1 0 0 100 40 242 | pos/pos-241.pgm 1 0 0 100 40 243 | pos/pos-242.pgm 1 0 0 100 40 244 | pos/pos-243.pgm 1 0 0 100 40 245 | pos/pos-244.pgm 1 0 0 100 40 246 | pos/pos-245.pgm 1 0 0 100 40 247 | pos/pos-246.pgm 1 0 0 100 40 248 | pos/pos-247.pgm 1 0 0 100 40 249 | pos/pos-248.pgm 1 0 0 100 40 250 | pos/pos-249.pgm 1 0 0 100 40 251 | pos/pos-250.pgm 1 0 0 100 40 252 | pos/pos-251.pgm 1 0 0 100 40 253 | pos/pos-252.pgm 1 0 0 100 40 254 | pos/pos-253.pgm 1 0 0 100 40 255 | pos/pos-254.pgm 1 0 0 100 40 256 | pos/pos-255.pgm 1 0 0 100 40 257 | pos/pos-256.pgm 1 0 0 100 40 258 | pos/pos-257.pgm 1 0 0 100 40 259 | pos/pos-258.pgm 1 0 0 100 40 260 | pos/pos-259.pgm 1 0 0 100 40 261 | pos/pos-260.pgm 1 0 0 100 40 262 | pos/pos-261.pgm 1 0 0 100 40 263 | pos/pos-262.pgm 1 0 0 100 40 264 | pos/pos-263.pgm 1 0 0 100 40 265 | pos/pos-264.pgm 1 0 0 100 40 266 | pos/pos-265.pgm 1 0 0 100 40 267 | pos/pos-266.pgm 1 0 0 100 40 268 | pos/pos-267.pgm 1 0 0 100 40 269 | pos/pos-268.pgm 1 0 0 100 40 270 | pos/pos-269.pgm 1 0 0 100 40 271 | pos/pos-270.pgm 1 0 0 100 40 272 | pos/pos-271.pgm 1 0 0 100 40 273 | pos/pos-272.pgm 1 0 0 100 40 274 | pos/pos-273.pgm 1 0 0 100 40 275 | pos/pos-274.pgm 1 0 0 100 40 276 | pos/pos-275.pgm 1 0 0 100 40 277 | pos/pos-276.pgm 1 0 0 100 40 278 | pos/pos-277.pgm 1 0 0 100 40 279 | pos/pos-278.pgm 1 0 0 100 40 280 | pos/pos-279.pgm 1 0 0 100 40 281 | pos/pos-280.pgm 1 0 0 100 40 282 | pos/pos-281.pgm 1 0 0 100 40 283 | pos/pos-282.pgm 1 0 0 100 40 284 | pos/pos-283.pgm 1 0 0 100 40 285 | pos/pos-284.pgm 1 0 0 100 40 286 | pos/pos-285.pgm 1 0 0 100 40 287 | pos/pos-286.pgm 1 0 0 100 40 288 | pos/pos-287.pgm 1 0 0 100 40 289 | pos/pos-288.pgm 1 0 0 100 40 290 | pos/pos-289.pgm 1 0 0 100 40 291 | pos/pos-290.pgm 1 0 0 100 40 292 | pos/pos-291.pgm 1 0 0 100 40 293 | pos/pos-292.pgm 1 0 0 100 40 294 | pos/pos-293.pgm 1 0 0 100 40 295 | pos/pos-294.pgm 1 0 0 100 40 296 | pos/pos-295.pgm 1 0 0 100 40 297 | pos/pos-296.pgm 1 0 0 100 40 298 | pos/pos-297.pgm 1 0 0 100 40 299 | pos/pos-298.pgm 1 0 0 100 40 300 | pos/pos-299.pgm 1 0 0 100 40 301 | pos/pos-300.pgm 1 0 0 100 40 302 | pos/pos-301.pgm 1 0 0 100 40 303 | pos/pos-302.pgm 1 0 0 100 40 304 | pos/pos-303.pgm 1 0 0 100 40 305 | pos/pos-304.pgm 1 0 0 100 40 306 | pos/pos-305.pgm 1 0 0 100 40 307 | pos/pos-306.pgm 1 0 0 100 40 308 | pos/pos-307.pgm 1 0 0 100 40 309 | pos/pos-308.pgm 1 0 0 100 40 310 | pos/pos-309.pgm 1 0 0 100 40 311 | pos/pos-310.pgm 1 0 0 100 40 312 | pos/pos-311.pgm 1 0 0 100 40 313 | pos/pos-312.pgm 1 0 0 100 40 314 | pos/pos-313.pgm 1 0 0 100 40 315 | pos/pos-314.pgm 1 0 0 100 40 316 | pos/pos-315.pgm 1 0 0 100 40 317 | pos/pos-316.pgm 1 0 0 100 40 318 | pos/pos-317.pgm 1 0 0 100 40 319 | pos/pos-318.pgm 1 0 0 100 40 320 | pos/pos-319.pgm 1 0 0 100 40 321 | pos/pos-320.pgm 1 0 0 100 40 322 | pos/pos-321.pgm 1 0 0 100 40 323 | pos/pos-322.pgm 1 0 0 100 40 324 | pos/pos-323.pgm 1 0 0 100 40 325 | pos/pos-324.pgm 1 0 0 100 40 326 | pos/pos-325.pgm 1 0 0 100 40 327 | pos/pos-326.pgm 1 0 0 100 40 328 | pos/pos-327.pgm 1 0 0 100 40 329 | pos/pos-328.pgm 1 0 0 100 40 330 | pos/pos-329.pgm 1 0 0 100 40 331 | pos/pos-330.pgm 1 0 0 100 40 332 | pos/pos-331.pgm 1 0 0 100 40 333 | pos/pos-332.pgm 1 0 0 100 40 334 | pos/pos-333.pgm 1 0 0 100 40 335 | pos/pos-334.pgm 1 0 0 100 40 336 | pos/pos-335.pgm 1 0 0 100 40 337 | pos/pos-336.pgm 1 0 0 100 40 338 | pos/pos-337.pgm 1 0 0 100 40 339 | pos/pos-338.pgm 1 0 0 100 40 340 | pos/pos-339.pgm 1 0 0 100 40 341 | pos/pos-340.pgm 1 0 0 100 40 342 | pos/pos-341.pgm 1 0 0 100 40 343 | pos/pos-342.pgm 1 0 0 100 40 344 | pos/pos-343.pgm 1 0 0 100 40 345 | pos/pos-344.pgm 1 0 0 100 40 346 | pos/pos-345.pgm 1 0 0 100 40 347 | pos/pos-346.pgm 1 0 0 100 40 348 | pos/pos-347.pgm 1 0 0 100 40 349 | pos/pos-348.pgm 1 0 0 100 40 350 | pos/pos-349.pgm 1 0 0 100 40 351 | pos/pos-350.pgm 1 0 0 100 40 352 | pos/pos-351.pgm 1 0 0 100 40 353 | pos/pos-352.pgm 1 0 0 100 40 354 | pos/pos-353.pgm 1 0 0 100 40 355 | pos/pos-354.pgm 1 0 0 100 40 356 | pos/pos-355.pgm 1 0 0 100 40 357 | pos/pos-356.pgm 1 0 0 100 40 358 | pos/pos-357.pgm 1 0 0 100 40 359 | pos/pos-358.pgm 1 0 0 100 40 360 | pos/pos-359.pgm 1 0 0 100 40 361 | pos/pos-360.pgm 1 0 0 100 40 362 | pos/pos-361.pgm 1 0 0 100 40 363 | pos/pos-362.pgm 1 0 0 100 40 364 | pos/pos-363.pgm 1 0 0 100 40 365 | pos/pos-364.pgm 1 0 0 100 40 366 | pos/pos-365.pgm 1 0 0 100 40 367 | pos/pos-366.pgm 1 0 0 100 40 368 | pos/pos-367.pgm 1 0 0 100 40 369 | pos/pos-368.pgm 1 0 0 100 40 370 | pos/pos-369.pgm 1 0 0 100 40 371 | pos/pos-370.pgm 1 0 0 100 40 372 | pos/pos-371.pgm 1 0 0 100 40 373 | pos/pos-372.pgm 1 0 0 100 40 374 | pos/pos-373.pgm 1 0 0 100 40 375 | pos/pos-374.pgm 1 0 0 100 40 376 | pos/pos-375.pgm 1 0 0 100 40 377 | pos/pos-376.pgm 1 0 0 100 40 378 | pos/pos-377.pgm 1 0 0 100 40 379 | pos/pos-378.pgm 1 0 0 100 40 380 | pos/pos-379.pgm 1 0 0 100 40 381 | pos/pos-380.pgm 1 0 0 100 40 382 | pos/pos-381.pgm 1 0 0 100 40 383 | pos/pos-382.pgm 1 0 0 100 40 384 | pos/pos-383.pgm 1 0 0 100 40 385 | pos/pos-384.pgm 1 0 0 100 40 386 | pos/pos-385.pgm 1 0 0 100 40 387 | pos/pos-386.pgm 1 0 0 100 40 388 | pos/pos-387.pgm 1 0 0 100 40 389 | pos/pos-388.pgm 1 0 0 100 40 390 | pos/pos-389.pgm 1 0 0 100 40 391 | pos/pos-390.pgm 1 0 0 100 40 392 | pos/pos-391.pgm 1 0 0 100 40 393 | pos/pos-392.pgm 1 0 0 100 40 394 | pos/pos-393.pgm 1 0 0 100 40 395 | pos/pos-394.pgm 1 0 0 100 40 396 | pos/pos-395.pgm 1 0 0 100 40 397 | pos/pos-396.pgm 1 0 0 100 40 398 | pos/pos-397.pgm 1 0 0 100 40 399 | pos/pos-398.pgm 1 0 0 100 40 400 | pos/pos-399.pgm 1 0 0 100 40 401 | pos/pos-400.pgm 1 0 0 100 40 402 | pos/pos-401.pgm 1 0 0 100 40 403 | pos/pos-402.pgm 1 0 0 100 40 404 | pos/pos-403.pgm 1 0 0 100 40 405 | pos/pos-404.pgm 1 0 0 100 40 406 | pos/pos-405.pgm 1 0 0 100 40 407 | pos/pos-406.pgm 1 0 0 100 40 408 | pos/pos-407.pgm 1 0 0 100 40 409 | pos/pos-408.pgm 1 0 0 100 40 410 | pos/pos-409.pgm 1 0 0 100 40 411 | pos/pos-410.pgm 1 0 0 100 40 412 | pos/pos-411.pgm 1 0 0 100 40 413 | pos/pos-412.pgm 1 0 0 100 40 414 | pos/pos-413.pgm 1 0 0 100 40 415 | pos/pos-414.pgm 1 0 0 100 40 416 | pos/pos-415.pgm 1 0 0 100 40 417 | pos/pos-416.pgm 1 0 0 100 40 418 | pos/pos-417.pgm 1 0 0 100 40 419 | pos/pos-418.pgm 1 0 0 100 40 420 | pos/pos-419.pgm 1 0 0 100 40 421 | pos/pos-420.pgm 1 0 0 100 40 422 | pos/pos-421.pgm 1 0 0 100 40 423 | pos/pos-422.pgm 1 0 0 100 40 424 | pos/pos-423.pgm 1 0 0 100 40 425 | pos/pos-424.pgm 1 0 0 100 40 426 | pos/pos-425.pgm 1 0 0 100 40 427 | pos/pos-426.pgm 1 0 0 100 40 428 | pos/pos-427.pgm 1 0 0 100 40 429 | pos/pos-428.pgm 1 0 0 100 40 430 | pos/pos-429.pgm 1 0 0 100 40 431 | pos/pos-430.pgm 1 0 0 100 40 432 | pos/pos-431.pgm 1 0 0 100 40 433 | pos/pos-432.pgm 1 0 0 100 40 434 | pos/pos-433.pgm 1 0 0 100 40 435 | pos/pos-434.pgm 1 0 0 100 40 436 | pos/pos-435.pgm 1 0 0 100 40 437 | pos/pos-436.pgm 1 0 0 100 40 438 | pos/pos-437.pgm 1 0 0 100 40 439 | pos/pos-438.pgm 1 0 0 100 40 440 | pos/pos-439.pgm 1 0 0 100 40 441 | pos/pos-440.pgm 1 0 0 100 40 442 | pos/pos-441.pgm 1 0 0 100 40 443 | pos/pos-442.pgm 1 0 0 100 40 444 | pos/pos-443.pgm 1 0 0 100 40 445 | pos/pos-444.pgm 1 0 0 100 40 446 | pos/pos-445.pgm 1 0 0 100 40 447 | pos/pos-446.pgm 1 0 0 100 40 448 | pos/pos-447.pgm 1 0 0 100 40 449 | pos/pos-448.pgm 1 0 0 100 40 450 | pos/pos-449.pgm 1 0 0 100 40 451 | pos/pos-450.pgm 1 0 0 100 40 452 | pos/pos-451.pgm 1 0 0 100 40 453 | pos/pos-452.pgm 1 0 0 100 40 454 | pos/pos-453.pgm 1 0 0 100 40 455 | pos/pos-454.pgm 1 0 0 100 40 456 | pos/pos-455.pgm 1 0 0 100 40 457 | pos/pos-456.pgm 1 0 0 100 40 458 | pos/pos-457.pgm 1 0 0 100 40 459 | pos/pos-458.pgm 1 0 0 100 40 460 | pos/pos-459.pgm 1 0 0 100 40 461 | pos/pos-460.pgm 1 0 0 100 40 462 | pos/pos-461.pgm 1 0 0 100 40 463 | pos/pos-462.pgm 1 0 0 100 40 464 | pos/pos-463.pgm 1 0 0 100 40 465 | pos/pos-464.pgm 1 0 0 100 40 466 | pos/pos-465.pgm 1 0 0 100 40 467 | pos/pos-466.pgm 1 0 0 100 40 468 | pos/pos-467.pgm 1 0 0 100 40 469 | pos/pos-468.pgm 1 0 0 100 40 470 | pos/pos-469.pgm 1 0 0 100 40 471 | pos/pos-470.pgm 1 0 0 100 40 472 | pos/pos-471.pgm 1 0 0 100 40 473 | pos/pos-472.pgm 1 0 0 100 40 474 | pos/pos-473.pgm 1 0 0 100 40 475 | pos/pos-474.pgm 1 0 0 100 40 476 | pos/pos-475.pgm 1 0 0 100 40 477 | pos/pos-476.pgm 1 0 0 100 40 478 | pos/pos-477.pgm 1 0 0 100 40 479 | pos/pos-478.pgm 1 0 0 100 40 480 | pos/pos-479.pgm 1 0 0 100 40 481 | pos/pos-480.pgm 1 0 0 100 40 482 | pos/pos-481.pgm 1 0 0 100 40 483 | pos/pos-482.pgm 1 0 0 100 40 484 | pos/pos-483.pgm 1 0 0 100 40 485 | pos/pos-484.pgm 1 0 0 100 40 486 | pos/pos-485.pgm 1 0 0 100 40 487 | pos/pos-486.pgm 1 0 0 100 40 488 | pos/pos-487.pgm 1 0 0 100 40 489 | pos/pos-488.pgm 1 0 0 100 40 490 | pos/pos-489.pgm 1 0 0 100 40 491 | pos/pos-490.pgm 1 0 0 100 40 492 | pos/pos-491.pgm 1 0 0 100 40 493 | pos/pos-492.pgm 1 0 0 100 40 494 | pos/pos-493.pgm 1 0 0 100 40 495 | pos/pos-494.pgm 1 0 0 100 40 496 | pos/pos-495.pgm 1 0 0 100 40 497 | pos/pos-496.pgm 1 0 0 100 40 498 | pos/pos-497.pgm 1 0 0 100 40 499 | pos/pos-498.pgm 1 0 0 100 40 500 | pos/pos-499.pgm 1 0 0 100 40 501 | pos/pos-500.pgm 1 0 0 100 40 502 | pos/pos-501.pgm 1 0 0 100 40 503 | pos/pos-502.pgm 1 0 0 100 40 504 | pos/pos-503.pgm 1 0 0 100 40 505 | pos/pos-504.pgm 1 0 0 100 40 506 | pos/pos-505.pgm 1 0 0 100 40 507 | pos/pos-506.pgm 1 0 0 100 40 508 | pos/pos-507.pgm 1 0 0 100 40 509 | pos/pos-508.pgm 1 0 0 100 40 510 | pos/pos-509.pgm 1 0 0 100 40 511 | pos/pos-510.pgm 1 0 0 100 40 512 | pos/pos-511.pgm 1 0 0 100 40 513 | pos/pos-512.pgm 1 0 0 100 40 514 | pos/pos-513.pgm 1 0 0 100 40 515 | pos/pos-514.pgm 1 0 0 100 40 516 | pos/pos-515.pgm 1 0 0 100 40 517 | pos/pos-516.pgm 1 0 0 100 40 518 | pos/pos-517.pgm 1 0 0 100 40 519 | pos/pos-518.pgm 1 0 0 100 40 520 | pos/pos-519.pgm 1 0 0 100 40 521 | pos/pos-520.pgm 1 0 0 100 40 522 | pos/pos-521.pgm 1 0 0 100 40 523 | pos/pos-522.pgm 1 0 0 100 40 524 | pos/pos-523.pgm 1 0 0 100 40 525 | pos/pos-524.pgm 1 0 0 100 40 526 | pos/pos-525.pgm 1 0 0 100 40 527 | pos/pos-526.pgm 1 0 0 100 40 528 | pos/pos-527.pgm 1 0 0 100 40 529 | pos/pos-528.pgm 1 0 0 100 40 530 | pos/pos-529.pgm 1 0 0 100 40 531 | pos/pos-530.pgm 1 0 0 100 40 532 | pos/pos-531.pgm 1 0 0 100 40 533 | pos/pos-532.pgm 1 0 0 100 40 534 | pos/pos-533.pgm 1 0 0 100 40 535 | pos/pos-534.pgm 1 0 0 100 40 536 | pos/pos-535.pgm 1 0 0 100 40 537 | pos/pos-536.pgm 1 0 0 100 40 538 | pos/pos-537.pgm 1 0 0 100 40 539 | pos/pos-538.pgm 1 0 0 100 40 540 | pos/pos-539.pgm 1 0 0 100 40 541 | pos/pos-540.pgm 1 0 0 100 40 542 | pos/pos-541.pgm 1 0 0 100 40 543 | pos/pos-542.pgm 1 0 0 100 40 544 | pos/pos-543.pgm 1 0 0 100 40 545 | pos/pos-544.pgm 1 0 0 100 40 546 | pos/pos-545.pgm 1 0 0 100 40 547 | pos/pos-546.pgm 1 0 0 100 40 548 | pos/pos-547.pgm 1 0 0 100 40 549 | pos/pos-548.pgm 1 0 0 100 40 550 | pos/pos-549.pgm 1 0 0 100 40 551 | -------------------------------------------------------------------------------- /uml-parser-webapp/views/error.ejs: -------------------------------------------------------------------------------- 1 |

<%= message %>

2 |

<%= error.status %>

3 |
<%= error.stack %>
4 | -------------------------------------------------------------------------------- /uml-parser-webapp/views/homepage.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <%= title %> 5 | 7 | 8 | 9 | 10 | 11 |
12 |
13 |

Welcome!

14 |

Generate UML Class diagram for Java files

15 |
16 |
17 |
18 |
19 |

Upload ZIP with Java files in home directory to start

20 |
21 | 22 |

File Uploader

23 |
24 |
25 |
26 | 27 | 28 |
29 |
30 |
31 |
32 |
33 |
34 | 35 |
36 |
37 |

Output image will be displayed here

38 |
39 |
40 |
41 |
42 |
43 | 44 |
45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /uml-parser-webapp/views/index.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <%= title %> 5 | 6 | 7 | 8 |

<%= title %>

9 |

Welcome to <%= title %>

10 | 11 | 12 | --------------------------------------------------------------------------------