├── UmlGenerator ├── .gitignore ├── .settings │ ├── org.eclipse.m2e.core.prefs │ └── org.eclipse.jdt.core.prefs ├── src │ └── main │ │ └── java │ │ └── com │ │ └── uml │ │ └── generator │ │ ├── classDiagram │ │ ├── models │ │ │ ├── ModifierType.java │ │ │ ├── ClassType.java │ │ │ ├── PackageModel.java │ │ │ ├── MethodModel.java │ │ │ ├── ClassDiagramModel.java │ │ │ ├── FieldModel.java │ │ │ └── ClassModel.java │ │ └── ClassDiagramGenerator.java │ │ ├── spring │ │ ├── models │ │ │ ├── DependencyType.java │ │ │ ├── SpringClassType.java │ │ │ ├── SpringDependencyDiagramModel.java │ │ │ └── SpringClassModel.java │ │ └── SpringDependencyDiagramGenerator.java │ │ ├── jpa │ │ ├── models │ │ │ ├── JpaEntityType.java │ │ │ ├── JpaDependencyType.java │ │ │ ├── JpaDependencyDiagramModel.java │ │ │ └── JpaClassModel.java │ │ └── JpaMappingDiagramGenerator.java │ │ ├── componentDiagram │ │ ├── models │ │ │ ├── ComponentType.java │ │ │ ├── ComponentGroupModel.java │ │ │ ├── ComponentModel.java │ │ │ └── ComponentDiagramModel.java │ │ └── ComponentDiagramGenerator.java │ │ ├── UmlOptions.java │ │ ├── models │ │ └── UmlModel.java │ │ ├── UmlGeneratorUtility.java │ │ └── UmlGenerator.java ├── .classpath ├── .project └── pom.xml ├── UmlGeneratorTool ├── .gitignore ├── icons │ ├── JPAIcon.png │ ├── SpringIcon.png │ ├── ._SpringIcon.png │ ├── ClassDiagramIcon.png │ └── ComponentDiagramIcon.png ├── .settings │ ├── org.eclipse.m2e.core.prefs │ └── org.eclipse.jdt.core.prefs ├── .project ├── .classpath ├── META-INF │ └── MANIFEST.MF ├── build.properties ├── pom.xml ├── src │ └── main │ │ └── java │ │ └── umlGenerator │ │ ├── Activator.java │ │ ├── windows │ │ ├── GenerateComponentDiagramOptionsDialog.java │ │ └── GenerateUMLOptionsDialog.java │ │ ├── actions │ │ ├── GenerateComponentDiagramAction.java │ │ ├── GenerateJpaMappingDiagramAction.java │ │ ├── GenerateSpringClassDiagramAction.java │ │ └── GenerateClassDiagramAction.java │ │ └── MultipleProjectAction.java └── plugin.xml ├── .DS_Store ├── Resources ├── UmlGeneratorMenu.png ├── SampleClassDiagram.png ├── SampleComponentDiagram.png ├── SampleJPAMappingDiagram.png ├── ComponentDiagramOptionsDialog.png ├── SampleSpringDependencyDiagram.png ├── ClassAndSpringDiagramOptionsDialog.png └── .project └── README.md /UmlGenerator/.gitignore: -------------------------------------------------------------------------------- 1 | /bin/ 2 | /target 3 | -------------------------------------------------------------------------------- /UmlGeneratorTool/.gitignore: -------------------------------------------------------------------------------- 1 | /bin/ 2 | /.gitignore 3 | /target 4 | -------------------------------------------------------------------------------- /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/suken/UmlGeneratorTool/HEAD/.DS_Store -------------------------------------------------------------------------------- /Resources/UmlGeneratorMenu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/suken/UmlGeneratorTool/HEAD/Resources/UmlGeneratorMenu.png -------------------------------------------------------------------------------- /Resources/SampleClassDiagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/suken/UmlGeneratorTool/HEAD/Resources/SampleClassDiagram.png -------------------------------------------------------------------------------- /UmlGeneratorTool/icons/JPAIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/suken/UmlGeneratorTool/HEAD/UmlGeneratorTool/icons/JPAIcon.png -------------------------------------------------------------------------------- /Resources/SampleComponentDiagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/suken/UmlGeneratorTool/HEAD/Resources/SampleComponentDiagram.png -------------------------------------------------------------------------------- /Resources/SampleJPAMappingDiagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/suken/UmlGeneratorTool/HEAD/Resources/SampleJPAMappingDiagram.png -------------------------------------------------------------------------------- /UmlGeneratorTool/icons/SpringIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/suken/UmlGeneratorTool/HEAD/UmlGeneratorTool/icons/SpringIcon.png -------------------------------------------------------------------------------- /UmlGeneratorTool/icons/._SpringIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/suken/UmlGeneratorTool/HEAD/UmlGeneratorTool/icons/._SpringIcon.png -------------------------------------------------------------------------------- /Resources/ComponentDiagramOptionsDialog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/suken/UmlGeneratorTool/HEAD/Resources/ComponentDiagramOptionsDialog.png -------------------------------------------------------------------------------- /Resources/SampleSpringDependencyDiagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/suken/UmlGeneratorTool/HEAD/Resources/SampleSpringDependencyDiagram.png -------------------------------------------------------------------------------- /UmlGeneratorTool/icons/ClassDiagramIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/suken/UmlGeneratorTool/HEAD/UmlGeneratorTool/icons/ClassDiagramIcon.png -------------------------------------------------------------------------------- /UmlGenerator/.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /UmlGeneratorTool/icons/ComponentDiagramIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/suken/UmlGeneratorTool/HEAD/UmlGeneratorTool/icons/ComponentDiagramIcon.png -------------------------------------------------------------------------------- /Resources/ClassAndSpringDiagramOptionsDialog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/suken/UmlGeneratorTool/HEAD/Resources/ClassAndSpringDiagramOptionsDialog.png -------------------------------------------------------------------------------- /UmlGeneratorTool/.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /UmlGenerator/src/main/java/com/uml/generator/classDiagram/models/ModifierType.java: -------------------------------------------------------------------------------- 1 | package com.uml.generator.classDiagram.models; 2 | 3 | public enum ModifierType { 4 | 5 | PUBLIC, 6 | PRIVATE, 7 | PROTECTED, 8 | DEFAULT, 9 | NONE; 10 | } 11 | -------------------------------------------------------------------------------- /Resources/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | Resources 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /UmlGenerator/src/main/java/com/uml/generator/spring/models/DependencyType.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.uml.generator.spring.models; 5 | 6 | /** 7 | * @author sukenshah 8 | * 9 | */ 10 | public enum DependencyType { 11 | 12 | AUTOWIRED, 13 | REQUIRED, 14 | BEAN; 15 | } 16 | -------------------------------------------------------------------------------- /UmlGenerator/src/main/java/com/uml/generator/jpa/models/JpaEntityType.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.uml.generator.jpa.models; 5 | 6 | /** 7 | * @author SShah 8 | * 9 | */ 10 | public enum JpaEntityType { 11 | 12 | TABLE, 13 | MAPPED_SUPER_CLASS, 14 | ENTITY; 15 | } 16 | -------------------------------------------------------------------------------- /UmlGenerator/src/main/java/com/uml/generator/componentDiagram/models/ComponentType.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.uml.generator.componentDiagram.models; 5 | 6 | /** 7 | * @author shahs 8 | */ 9 | public enum ComponentType { 10 | 11 | LIB, 12 | DATABASE, 13 | INTERFACE, 14 | SOURCE; 15 | } 16 | -------------------------------------------------------------------------------- /UmlGenerator/src/main/java/com/uml/generator/jpa/models/JpaDependencyType.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.uml.generator.jpa.models; 5 | 6 | /** 7 | * @author SShah 8 | * 9 | */ 10 | public enum JpaDependencyType { 11 | 12 | ONE_TO_MANY, 13 | ONE_TO_ONE, 14 | MANY_TO_ONE, 15 | MANY_TO_MANY; 16 | } 17 | -------------------------------------------------------------------------------- /UmlGenerator/src/main/java/com/uml/generator/spring/models/SpringClassType.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.uml.generator.spring.models; 5 | 6 | /** 7 | * @author sukenshah 8 | * 9 | */ 10 | public enum SpringClassType { 11 | 12 | COMPONENT, 13 | CONTROLLER, 14 | REPOSITORY, 15 | SERVICE, 16 | CONFIGURATION, 17 | NONE; 18 | } 19 | -------------------------------------------------------------------------------- /UmlGenerator/src/main/java/com/uml/generator/UmlOptions.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.uml.generator; 5 | 6 | import lombok.Getter; 7 | import lombok.Setter; 8 | import net.sourceforge.plantuml.FileFormat; 9 | 10 | /** 11 | * @author Suken Shah 12 | */ 13 | @Getter 14 | @Setter 15 | public class UmlOptions { 16 | private boolean packagesIncluded; 17 | private boolean fieldsIncluded; 18 | private boolean methodsIncluded; 19 | private boolean testIncluded; 20 | private String includePatterns; 21 | private String excludePatterns; 22 | private FileFormat fileFormat; 23 | } 24 | -------------------------------------------------------------------------------- /UmlGenerator/src/main/java/com/uml/generator/classDiagram/models/ClassType.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.uml.generator.classDiagram.models; 5 | 6 | import lombok.Getter; 7 | 8 | /** 9 | * @author sukenshah 10 | */ 11 | public enum ClassType { 12 | CLASS(" class "), 13 | INTERFACE(" interface "), 14 | ABSTRACT(" abstract "), 15 | ENUM(" enum "), 16 | ANNOTATION(" annotation "); 17 | 18 | @Getter 19 | private final String umlStr; 20 | 21 | ClassType(final String uml) { 22 | umlStr = uml; 23 | } 24 | 25 | public static String convert(final ClassType type) { 26 | return type.getUmlStr(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /UmlGenerator/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /UmlGenerator/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | UmlGenerator 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.m2e.core.maven2Builder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.m2e.core.maven2Nature 21 | org.eclipse.jdt.core.javanature 22 | 23 | 24 | -------------------------------------------------------------------------------- /UmlGeneratorTool/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | UmlGeneratorTool 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.m2e.core.maven2Builder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.m2e.core.maven2Nature 21 | org.eclipse.pde.PluginNature 22 | org.eclipse.jdt.core.javanature 23 | 24 | 25 | -------------------------------------------------------------------------------- /UmlGenerator/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 4 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve 5 | org.eclipse.jdt.core.compiler.compliance=1.7 6 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate 7 | org.eclipse.jdt.core.compiler.debug.localVariable=generate 8 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate 9 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 10 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 11 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning 12 | org.eclipse.jdt.core.compiler.source=1.7 13 | -------------------------------------------------------------------------------- /UmlGeneratorTool/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /UmlGeneratorTool/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate 4 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 5 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve 6 | org.eclipse.jdt.core.compiler.compliance=1.5 7 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate 8 | org.eclipse.jdt.core.compiler.debug.localVariable=generate 9 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate 10 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 11 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 12 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning 13 | org.eclipse.jdt.core.compiler.source=1.5 14 | -------------------------------------------------------------------------------- /UmlGenerator/src/main/java/com/uml/generator/spring/models/SpringDependencyDiagramModel.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.uml.generator.spring.models; 5 | 6 | import java.util.List; 7 | 8 | import com.google.common.collect.Lists; 9 | import com.uml.generator.models.UmlModel; 10 | 11 | /** 12 | * @author sukenshah 13 | * 14 | */ 15 | public class SpringDependencyDiagramModel extends UmlModel { 16 | 17 | private final List classes = Lists.newArrayList(); 18 | 19 | public void addClass(final SpringClassModel classModel) { 20 | classes.add(classModel); 21 | } 22 | 23 | /** 24 | * {@inheritDoc} 25 | */ 26 | @Override 27 | public String getUml() { 28 | StringBuffer uml = new StringBuffer(); 29 | uml.append(START_UML); 30 | 31 | // add classes 32 | for(SpringClassModel clazz : classes) { 33 | uml.append(NEW_LINE).append(clazz.getUml()); 34 | } 35 | 36 | uml.append(NEW_LINE).append(END_UML); 37 | return uml.toString(); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /UmlGenerator/src/main/java/com/uml/generator/models/UmlModel.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.uml.generator.models; 5 | 6 | /** 7 | * @author sukenshah 8 | */ 9 | public abstract class UmlModel { 10 | 11 | public static final String START_UML = "@startuml"; 12 | 13 | public static final String END_UML = "@enduml"; 14 | 15 | public static final String NEW_LINE = "\n"; 16 | 17 | public static final String OPEN_PARENTHESIS = "{"; 18 | 19 | public static final String CLOSE_PARENTHESIS = "}"; 20 | 21 | public static final String OPEN_BRACKET = "("; 22 | 23 | public static final String CLOSE_BRACKET = ")"; 24 | 25 | public static final String SPACE = " "; 26 | 27 | public static final String EXTENDS = " --|> "; 28 | 29 | public static final String DEPENDS = " --> "; 30 | 31 | public static final String PUBLIC = " + "; 32 | 33 | public static final String PRIVATE = " - "; 34 | 35 | public static final String PROTECTED = " # "; 36 | 37 | public static final String METHOD = "()"; 38 | 39 | public abstract String getUml(); 40 | } 41 | -------------------------------------------------------------------------------- /UmlGeneratorTool/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Bundle-ManifestVersion: 2 3 | Bundle-Name: UmlGenerator Plug-in 4 | Bundle-SymbolicName: UmlGenerator;singleton:=true 5 | Bundle-Version: 1.0 6 | Bundle-Activator: umlGenerator.Activator 7 | Require-Bundle: org.eclipse.ui, 8 | org.eclipse.core.runtime, 9 | org.eclipse.core.resources, 10 | org.eclipse.jdt.core, 11 | org.eclipse.jdt.ui, 12 | org.eclipse.ltk.core.refactoring;bundle-version="3.4.1" 13 | Bundle-Vendor: Suken Shah 14 | Bundle-RequiredExecutionEnvironment: JavaSE-1.6 15 | Bundle-ClassPath: lib/plantuml.jar, 16 | lib/UmlGenerator.jar, 17 | lib/maven-aether-provider-3.0.4.jar, 18 | lib/maven-artifact-3.0.4.jar, 19 | lib/maven-compat-3.0.4.jar, 20 | lib/maven-core-3.0.4.jar, 21 | lib/maven-embedder-3.0.4.jar, 22 | lib/maven-model-3.0.4.jar, 23 | lib/maven-model-builder-3.0.4.jar, 24 | lib/maven-plugin-api-3.0.4.jar, 25 | lib/maven-repository-metadata-3.0.4.jar, 26 | lib/maven-settings-3.0.4.jar, 27 | lib/maven-settings-builder-3.0.4.jar, 28 | lib/plexus-utils-2.0.6.jar, 29 | . 30 | -------------------------------------------------------------------------------- /UmlGenerator/src/main/java/com/uml/generator/classDiagram/models/PackageModel.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.uml.generator.classDiagram.models; 5 | 6 | import java.util.List; 7 | 8 | import lombok.Getter; 9 | 10 | import com.google.common.collect.Lists; 11 | import com.uml.generator.models.UmlModel; 12 | 13 | /** 14 | * @author sukenshah 15 | */ 16 | public class PackageModel extends UmlModel { 17 | 18 | @Getter 19 | private final String name; 20 | 21 | @Getter 22 | private final List classes = Lists.newArrayList(); 23 | 24 | public PackageModel(final String name) { 25 | this.name = name; 26 | } 27 | 28 | public void addClass(final ClassModel clazz) { 29 | classes.add(clazz); 30 | } 31 | 32 | @Override 33 | public String getUml() { 34 | StringBuilder uml = new StringBuilder(); 35 | uml.append(" package ").append(name).append(NEW_LINE).append(OPEN_PARENTHESIS); 36 | for (ClassModel clazz : classes) { 37 | uml.append(clazz.getUml()); 38 | uml.append(NEW_LINE); 39 | } 40 | uml.append(CLOSE_PARENTHESIS); 41 | return uml.toString(); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /UmlGenerator/src/main/java/com/uml/generator/jpa/models/JpaDependencyDiagramModel.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.uml.generator.jpa.models; 5 | 6 | import java.util.Map; 7 | 8 | import com.google.common.collect.Maps; 9 | import com.uml.generator.models.UmlModel; 10 | 11 | /** 12 | * @author sukenshah 13 | * 14 | */ 15 | public class JpaDependencyDiagramModel extends UmlModel { 16 | 17 | private final Map classes = Maps.newLinkedHashMap(); 18 | 19 | public void addClass(final JpaClassModel classModel) { 20 | classes.put(classModel.getName(), classModel); 21 | } 22 | 23 | public JpaClassModel getClass(final String name) { 24 | return classes.get(name); 25 | } 26 | 27 | /** 28 | * {@inheritDoc} 29 | */ 30 | @Override 31 | public String getUml() { 32 | StringBuffer uml = new StringBuffer(); 33 | uml.append(START_UML); 34 | 35 | // add classes 36 | for(JpaClassModel clazz : classes.values()) { 37 | uml.append(NEW_LINE).append(clazz.getUml()); 38 | } 39 | 40 | uml.append(NEW_LINE).append(END_UML); 41 | return uml.toString(); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /UmlGeneratorTool/build.properties: -------------------------------------------------------------------------------- 1 | source.. = src_old/,\ 2 | lib/ 3 | output.. = classes/,\ 4 | bin/ 5 | bin.includes = plugin.xml,\ 6 | META-INF/,\ 7 | .,\ 8 | UmlGenerator.jar,\ 9 | classes/,\ 10 | icons/,\ 11 | lib/,\ 12 | lib/plantuml.jar,\ 13 | lib/UmlGenerator.jar,\ 14 | bin/,\ 15 | lib/maven-aether-provider-3.0.4.jar,\ 16 | lib/maven-artifact-3.0.4.jar,\ 17 | lib/maven-compat-3.0.4.jar,\ 18 | lib/maven-core-3.0.4.jar,\ 19 | lib/maven-embedder-3.0.4.jar,\ 20 | lib/maven-model-3.0.4.jar,\ 21 | lib/maven-model-builder-3.0.4.jar,\ 22 | lib/maven-plugin-api-3.0.4.jar,\ 23 | lib/maven-repository-metadata-3.0.4.jar,\ 24 | lib/maven-settings-3.0.4.jar,\ 25 | lib/maven-settings-builder-3.0.4.jar,\ 26 | lib/plexus-utils-2.0.6.jar 27 | source.UmlGenerator.jar = src_old/ 28 | output.UmlGenerator.jar = bin/ 29 | jars.compile.order = UmlGenerator.jar,\ 30 | . 31 | jre.compilation.profile = JavaSE-1.6 32 | -------------------------------------------------------------------------------- /UmlGenerator/src/main/java/com/uml/generator/classDiagram/models/MethodModel.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.uml.generator.classDiagram.models; 5 | 6 | import java.lang.reflect.Modifier; 7 | 8 | import com.uml.generator.models.UmlModel; 9 | 10 | /** 11 | * @author sukenshah 12 | * 13 | */ 14 | public class MethodModel extends UmlModel { 15 | 16 | private final String name; 17 | 18 | private ModifierType access; 19 | 20 | public MethodModel(final String name, final int modifier) { 21 | this.name = name; 22 | switch (modifier) { 23 | case Modifier.PUBLIC: 24 | access = ModifierType.PUBLIC; 25 | break; 26 | case Modifier.PRIVATE: 27 | access = ModifierType.PRIVATE; 28 | break; 29 | case Modifier.PROTECTED: 30 | access = ModifierType.PROTECTED; 31 | break; 32 | default: 33 | access = ModifierType.PROTECTED; 34 | break; 35 | } 36 | } 37 | 38 | public boolean isPublicOrProtected() { 39 | return !(access == ModifierType.PRIVATE); 40 | } 41 | 42 | @Override 43 | public String getUml() { 44 | String modifier = PRIVATE; 45 | if (access == ModifierType.PUBLIC) { 46 | modifier = PUBLIC; 47 | } 48 | else if (access == ModifierType.PROTECTED) { 49 | modifier = PROTECTED; 50 | } 51 | return modifier + name + METHOD; 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /UmlGeneratorTool/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | UmlGeneratorTool 4 | UmlGeneratorTool 5 | 1.0.1-SNAPSHOT 6 | UmlGeneratorTool 7 | 8 | src 9 | 10 | Eclipse plugin for UmlGenerator. The plugin supports generation of class diagram, sping dependency diagram, component diagram and JPA mapping diagram. 11 | https://github.com/suken/UmlGeneratorTool 12 | 13 | Suken Shah 14 | https://github.com/suken/UmlGeneratorTool 15 | 16 | 17 | 18 | UmlGenerator 19 | UmlGenerator 20 | 21 | 22 | 23 | 24 | 25 | UmlGenerator 26 | UmlGenerator 27 | 1.0.1-SNAPSHOT 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /UmlGenerator/src/main/java/com/uml/generator/classDiagram/models/ClassDiagramModel.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.uml.generator.classDiagram.models; 5 | 6 | import java.util.List; 7 | 8 | import com.google.common.collect.Lists; 9 | import com.uml.generator.models.UmlModel; 10 | 11 | /** 12 | * @author sukenshah 13 | */ 14 | public class ClassDiagramModel extends UmlModel { 15 | 16 | private final List classes = Lists.newArrayList(); 17 | 18 | private final List packages = Lists.newArrayList(); 19 | 20 | public void addClass(final ClassModel classModel) { 21 | classes.add(classModel); 22 | } 23 | 24 | public void addPackage(final PackageModel packageModel) { 25 | packages.add(packageModel); 26 | } 27 | 28 | /** 29 | * {@inheritDoc} 30 | */ 31 | @Override 32 | public String getUml() { 33 | StringBuilder uml = new StringBuilder(); 34 | uml.append(START_UML); 35 | 36 | // add number of pages 37 | uml.append(NEW_LINE).append("page 2x2").append(NEW_LINE); 38 | 39 | // add packages 40 | for(PackageModel packaze : packages) { 41 | uml.append(NEW_LINE).append(packaze.getUml()); 42 | } 43 | 44 | // add classes 45 | for(ClassModel clazz : classes) { 46 | uml.append(NEW_LINE).append(clazz.getUml()); 47 | } 48 | 49 | uml.append(NEW_LINE).append(END_UML); 50 | return uml.toString(); 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /UmlGenerator/src/main/java/com/uml/generator/classDiagram/models/FieldModel.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.uml.generator.classDiagram.models; 5 | 6 | import java.lang.reflect.Modifier; 7 | 8 | import com.uml.generator.models.UmlModel; 9 | 10 | /** 11 | * @author sukenshah 12 | */ 13 | public class FieldModel extends UmlModel { 14 | 15 | private String name; 16 | 17 | private String type; 18 | 19 | private ModifierType access; 20 | 21 | public FieldModel(String name, String type, int modifier) { 22 | this.name = name; 23 | this.type = type; 24 | switch (modifier) { 25 | case Modifier.PUBLIC: 26 | this.access = ModifierType.PUBLIC; 27 | break; 28 | case Modifier.PRIVATE: 29 | this.access = ModifierType.PRIVATE; 30 | break; 31 | case Modifier.PROTECTED: 32 | this.access = ModifierType.PROTECTED; 33 | break; 34 | default: 35 | this.access = ModifierType.PRIVATE; 36 | break; 37 | } 38 | } 39 | 40 | public boolean isPublicOrProtected() { 41 | return !(access == ModifierType.PRIVATE); 42 | } 43 | 44 | /** 45 | * {@inheritDoc} 46 | */ 47 | @Override 48 | public String getUml() { 49 | String modifier = PRIVATE; 50 | if (access == ModifierType.PUBLIC) { 51 | modifier = PUBLIC; 52 | } 53 | else if (access == ModifierType.PROTECTED) { 54 | modifier = PROTECTED; 55 | } 56 | return modifier + type + SPACE + name; 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /UmlGeneratorTool/src/main/java/umlGenerator/Activator.java: -------------------------------------------------------------------------------- 1 | package umlGenerator; 2 | 3 | import org.eclipse.jface.resource.ImageDescriptor; 4 | import org.eclipse.ui.plugin.AbstractUIPlugin; 5 | import org.osgi.framework.BundleContext; 6 | 7 | /** 8 | * @author shahs 9 | */ 10 | public class Activator extends AbstractUIPlugin { 11 | 12 | /** 13 | * The plug-in ID. 14 | */ 15 | public static final String PLUGIN_ID = "UmlGenerator"; 16 | 17 | /** 18 | * The shared instance. 19 | */ 20 | private static Activator plugin; 21 | 22 | /** 23 | * The constructor. 24 | */ 25 | public Activator() { 26 | } 27 | 28 | /** 29 | * {@inheritDoc} 30 | */ 31 | @Override 32 | public void start(BundleContext context) throws Exception { 33 | super.start(context); 34 | plugin = this; 35 | } 36 | 37 | /** 38 | * {@inheritDoc} 39 | */ 40 | @Override 41 | public void stop(BundleContext context) throws Exception { 42 | plugin = null; 43 | super.stop(context); 44 | } 45 | 46 | /** 47 | * @return the shared instance 48 | */ 49 | public static Activator getDefault() { 50 | return plugin; 51 | } 52 | 53 | /** 54 | * @param path the path 55 | * @return the image descriptor 56 | */ 57 | public static ImageDescriptor getImageDescriptor(String path) { 58 | return imageDescriptorFromPlugin(PLUGIN_ID, path); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /UmlGenerator/src/main/java/com/uml/generator/componentDiagram/models/ComponentGroupModel.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.uml.generator.componentDiagram.models; 5 | 6 | import java.util.Map; 7 | 8 | import com.google.common.collect.Maps; 9 | import com.uml.generator.models.UmlModel; 10 | 11 | /** 12 | * @author shahs 13 | */ 14 | public class ComponentGroupModel extends UmlModel { 15 | 16 | private static final String GROUP = " frame "; 17 | private static final String GROUP_NAME_PRE_POST_FIX = "\" "; 18 | 19 | private final String name; 20 | 21 | private final Map components = Maps.newHashMap(); 22 | 23 | public ComponentGroupModel(final String name) { 24 | this.name = name; 25 | } 26 | 27 | public void addComponent(final ComponentModel model) { 28 | components.put(model.getName(), model); 29 | } 30 | 31 | public boolean containsComponent(final String artifactId) { 32 | return components.containsKey(artifactId); 33 | } 34 | 35 | /** 36 | * {@inheritDoc} 37 | */ 38 | @Override 39 | public String getUml() { 40 | StringBuilder uml = new StringBuilder(); 41 | uml.append(GROUP).append(GROUP_NAME_PRE_POST_FIX).append(name) 42 | .append(GROUP_NAME_PRE_POST_FIX).append(OPEN_PARENTHESIS); 43 | uml.append(NEW_LINE); 44 | 45 | // add all components 46 | for (ComponentModel component : components.values()) { 47 | uml.append(component.getUml()).append(NEW_LINE); 48 | } 49 | 50 | uml.append(CLOSE_PARENTHESIS).append(NEW_LINE); 51 | return uml.toString(); 52 | } 53 | 54 | public String getDependencyUML() { 55 | StringBuilder uml = new StringBuilder(); 56 | for (ComponentModel component : components.values()) { 57 | uml.append(component.getDependencyUML()).append(NEW_LINE); 58 | } 59 | return uml.toString(); 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /UmlGenerator/src/main/java/com/uml/generator/componentDiagram/models/ComponentModel.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.uml.generator.componentDiagram.models; 5 | 6 | import java.util.List; 7 | 8 | import lombok.Getter; 9 | 10 | import com.google.common.collect.Lists; 11 | import com.uml.generator.models.UmlModel; 12 | 13 | /** 14 | * @author shahs 15 | * 16 | */ 17 | public class ComponentModel extends UmlModel { 18 | 19 | private static final String DATABASE = " database "; 20 | 21 | private static final String SOURCE_START = " ["; 22 | 23 | private static final String END_SOURCE = "] "; 24 | 25 | @Getter 26 | private final String name; 27 | 28 | private final ComponentType type; 29 | 30 | private final List dependentComponents = Lists.newArrayList(); 31 | 32 | public ComponentModel(final String name, final ComponentType type) { 33 | this.name = name; 34 | this.type = type; 35 | } 36 | 37 | public void addDepedentComponent(final String name) { 38 | dependentComponents.add(name); 39 | } 40 | 41 | /** 42 | * {@inheritDoc} 43 | */ 44 | @Override 45 | public String getUml() { 46 | StringBuilder uml = new StringBuilder(); 47 | switch (type) { 48 | case DATABASE: 49 | uml.append(DATABASE).append("db").append(SPACE).append(OPEN_PARENTHESIS).append(NEW_LINE); 50 | uml.append(SOURCE_START).append(name).append(END_SOURCE).append(NEW_LINE).append(CLOSE_PARENTHESIS); 51 | break; 52 | case SOURCE: 53 | uml.append(SOURCE_START).append(name).append(END_SOURCE); 54 | break; 55 | case INTERFACE: 56 | uml.append(name); 57 | break; 58 | case LIB: 59 | uml.append(SOURCE_START).append(name).append(END_SOURCE).append(" <<" + ComponentType.LIB.toString() + ">> "); 60 | break; 61 | default: 62 | break; 63 | } 64 | uml.append(NEW_LINE); 65 | 66 | return uml.toString(); 67 | } 68 | 69 | public String getDependencyUML() { 70 | StringBuilder uml = new StringBuilder(); 71 | // add dependencies 72 | String componentName = SOURCE_START + name + END_SOURCE; 73 | for (String dependentComponent : dependentComponents) { 74 | uml.append(componentName).append(" --> ").append(SOURCE_START) 75 | .append(dependentComponent).append(END_SOURCE) 76 | .append(NEW_LINE); 77 | } 78 | return uml.toString(); 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /UmlGenerator/src/main/java/com/uml/generator/componentDiagram/models/ComponentDiagramModel.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.uml.generator.componentDiagram.models; 5 | 6 | import java.util.Map; 7 | 8 | import com.google.common.collect.Maps; 9 | import com.uml.generator.models.UmlModel; 10 | 11 | /** 12 | * @author shahs 13 | */ 14 | public class ComponentDiagramModel extends UmlModel { 15 | 16 | private final Map groups = Maps.newHashMap(); 17 | 18 | private final Map components = Maps.newHashMap(); 19 | 20 | private ComponentGroupModel getGroup(final String name) { 21 | ComponentGroupModel group = groups.get(name); 22 | if (group == null) { 23 | group = new ComponentGroupModel(name); 24 | groups.put(name, group); 25 | } 26 | return group; 27 | } 28 | 29 | public void addComponent(final ComponentModel component, final String group) { 30 | if (group != null && !group.isEmpty()) { 31 | getGroup(group).addComponent(component); 32 | } 33 | else { 34 | components.put(component.getName(), component); 35 | } 36 | } 37 | 38 | public boolean containsComponent(final String artifactId, final String groupId) { 39 | boolean exists = false; 40 | if (groupId != null && !groupId.isEmpty()) { 41 | exists = groups.containsKey(groupId); 42 | if (exists) { 43 | exists = groups.get(groupId).containsComponent(artifactId); 44 | } 45 | } 46 | else { 47 | exists = components.containsKey(artifactId); 48 | } 49 | return exists; 50 | } 51 | 52 | /** 53 | * {@inheritDoc} 54 | */ 55 | @Override 56 | public String getUml() { 57 | StringBuilder uml = new StringBuilder(START_UML + NEW_LINE); 58 | 59 | // add all components without groups 60 | for (ComponentModel component : components.values()) { 61 | uml.append(component.getUml()); 62 | uml.append(NEW_LINE); 63 | } 64 | 65 | // add all groups 66 | for (ComponentGroupModel groupModel : groups.values()) { 67 | uml.append(groupModel.getUml()); 68 | uml.append(NEW_LINE); 69 | } 70 | 71 | // add component dependencies 72 | for (ComponentModel component : components.values()) { 73 | uml.append(component.getDependencyUML()); 74 | uml.append(NEW_LINE); 75 | } 76 | 77 | // add component dependencies 78 | for (ComponentGroupModel groupModel : groups.values()) { 79 | uml.append(groupModel.getDependencyUML()); 80 | uml.append(NEW_LINE); 81 | } 82 | 83 | uml.append(END_UML); 84 | return uml.toString(); 85 | } 86 | 87 | } 88 | -------------------------------------------------------------------------------- /UmlGenerator/src/main/java/com/uml/generator/UmlGeneratorUtility.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.uml.generator; 5 | 6 | import java.io.File; 7 | import java.io.FileFilter; 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | import java.util.regex.Matcher; 11 | import java.util.regex.Pattern; 12 | 13 | /** 14 | * @author SShah 15 | */ 16 | public class UmlGeneratorUtility { 17 | 18 | public static List getClasses(File directory, boolean includeTests) { 19 | List classes = new ArrayList(); 20 | File[] directories = directory.listFiles(new FileFilter() { 21 | 22 | @Override 23 | public boolean accept(File file) { 24 | return file.isDirectory(); 25 | } 26 | }); 27 | 28 | File[] files = directory.listFiles(new FileFilter() { 29 | 30 | @Override 31 | public boolean accept(File file) { 32 | return file.isFile() && file.getName().endsWith(".class"); 33 | } 34 | }); 35 | 36 | for (File file : files) { 37 | if (includeTests || !file.getName().endsWith("Test.class")) { 38 | String className = file.getName().replace('/', '.').replace(".class", ""); 39 | classes.add(className); 40 | } 41 | } 42 | 43 | for (File dir : directories) { 44 | classes.addAll(getClasses(dir, includeTests)); 45 | } 46 | return classes; 47 | } 48 | 49 | public static boolean isIncluded(String className, boolean hasAnyPatterns, String[] includePatterns, String[] excludePatterns) { 50 | if (!hasAnyPatterns) { 51 | return true; 52 | } 53 | 54 | // check exclude patterns 55 | for (String patternText : excludePatterns) { 56 | if (!patternText.isEmpty()) { 57 | Pattern pattern = Pattern.compile(patternText); 58 | Matcher matcher = pattern.matcher(className); 59 | if (matcher.matches()) { 60 | return false; 61 | } 62 | } 63 | } 64 | 65 | // check for include pattern 66 | for (String patternText : includePatterns) { 67 | if (!patternText.isEmpty()) { 68 | Pattern pattern = Pattern.compile(patternText); 69 | Matcher matcher = pattern.matcher(className); 70 | if (matcher.matches()) { 71 | return true; 72 | } 73 | } 74 | } 75 | // by default the artifact is not included 76 | return false; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /UmlGenerator/src/main/java/com/uml/generator/spring/models/SpringClassModel.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.uml.generator.spring.models; 5 | 6 | import java.util.Map; 7 | import java.util.Map.Entry; 8 | 9 | import lombok.Setter; 10 | 11 | import com.google.common.collect.Maps; 12 | import com.uml.generator.classDiagram.models.ClassModel; 13 | import com.uml.generator.classDiagram.models.ClassType; 14 | 15 | /** 16 | * @author sukenshah 17 | */ 18 | public class SpringClassModel extends ClassModel { 19 | 20 | private static final String CONTROLLER = " << (C,#FF7700) Controller >> "; 21 | 22 | private static final String COMPONENT = " << (C,#AA5337) Component >> "; 23 | 24 | private static final String SERVICE = " << (S,#BB4830) Service >> "; 25 | 26 | private static final String REPOSITORY = " << (R,#CC2200) Repository >> "; 27 | 28 | private static final String CONFIGURATION = " << (C,#DD9900) Configuration >> "; 29 | 30 | private static final String INJECTED_RELATIONSHIP = "<--"; 31 | 32 | @Setter 33 | private SpringClassType springClassType = SpringClassType.NONE; 34 | 35 | private final StringBuffer note = new StringBuffer(); 36 | 37 | private final Map springDependencies = Maps.newHashMap(); 38 | 39 | public SpringClassModel(final String name) { 40 | super(name); 41 | } 42 | 43 | public void addDepedency(final String name, final DependencyType type) { 44 | springDependencies.put(name, type); 45 | } 46 | 47 | public void addNote(final String text) { 48 | note.append(text).append("\\n"); 49 | } 50 | 51 | /** 52 | * {@inheritDoc} 53 | */ 54 | @Override 55 | public String getUml() { 56 | StringBuilder uml = new StringBuilder(); 57 | uml.append(ClassType.convert(getType())).append(getName()); 58 | 59 | switch (springClassType) { 60 | case COMPONENT: 61 | uml.append(COMPONENT); 62 | break; 63 | case CONTROLLER: 64 | uml.append(CONTROLLER); 65 | break; 66 | case REPOSITORY: 67 | uml.append(REPOSITORY); 68 | break; 69 | case SERVICE: 70 | uml.append(SERVICE); 71 | break; 72 | case CONFIGURATION: 73 | uml.append(CONFIGURATION); 74 | break; 75 | case NONE: 76 | default: 77 | break; 78 | } 79 | 80 | uml.append(OPEN_PARENTHESIS).append(NEW_LINE); 81 | 82 | // all fields 83 | getFieldsUml(uml); 84 | 85 | // all methods 86 | getMethodsUml(uml); 87 | uml.append(CLOSE_PARENTHESIS); 88 | 89 | // add notes 90 | if (note.length() > 0) { 91 | uml.append(NEW_LINE).append("note left of ").append(getName()).append(" : ") 92 | .append(note.substring(0, note.length() - 2)); 93 | } 94 | uml.append(NEW_LINE); 95 | 96 | // parent relationship 97 | getDepenciesUml(uml); 98 | 99 | // spring dependencies 100 | for (Entry dependency : springDependencies.entrySet()) { 101 | uml.append(NEW_LINE).append(getName()).append(INJECTED_RELATIONSHIP).append(dependency.getKey()).append(" : ").append(dependency.getValue().toString()).append(" "); 102 | } 103 | 104 | uml.append(NEW_LINE); 105 | return uml.toString(); 106 | } 107 | 108 | } 109 | -------------------------------------------------------------------------------- /UmlGenerator/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | UmlGenerator 4 | UmlGenerator 5 | 1.0.1-SNAPSHOT 6 | UmlGenerator 7 | Utility project which provides generation of class, spring, JPA and component diagrams. 8 | 9 | src 10 | 11 | 12 | maven-compiler-plugin 13 | 3.1 14 | 15 | 1.7 16 | 1.7 17 | 18 | 19 | 20 | 21 | 22 | Suken Shah 23 | https://github.com/suken/UmlGeneratorTool 24 | 25 | https://github.com/suken/UmlGeneratorTool 26 | 27 | 28 | org.codehaus.plexus 29 | plexus-utils 30 | 3.0 31 | 32 | 33 | org.apache.maven 34 | maven-model 35 | 3.0.4 36 | 37 | 38 | org.apache.maven 39 | maven-core 40 | 3.0.4 41 | 42 | 43 | net.sourceforge.plantuml 44 | plantuml 45 | 8001 46 | 47 | 48 | org.projectlombok 49 | lombok 50 | 1.16.4 51 | provided 52 | 53 | 54 | com.google.guava 55 | guava 56 | 18.0 57 | provided 58 | 59 | 60 | javax 61 | javaee-api 62 | 7.0 63 | provided 64 | 65 | 66 | org.springframework 67 | spring 68 | 2.5.6.SEC03 69 | provided 70 | 71 | 72 | 73 | 74 | 75 | org.codehaus.plexus 76 | plexus-utils 77 | 3.0 78 | 79 | 80 | org.apache.maven 81 | maven-model 82 | 3.0.4 83 | 84 | 85 | org.apache.maven 86 | maven-core 87 | 3.0.4 88 | 89 | 90 | net.sourceforge.plantuml 91 | plantuml 92 | 8001 93 | 94 | 95 | 96 | -------------------------------------------------------------------------------- /UmlGenerator/src/main/java/com/uml/generator/classDiagram/models/ClassModel.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.uml.generator.classDiagram.models; 5 | 6 | import java.lang.reflect.Modifier; 7 | import java.util.List; 8 | 9 | import lombok.Getter; 10 | import lombok.Setter; 11 | 12 | import com.google.common.collect.Lists; 13 | import com.uml.generator.models.UmlModel; 14 | 15 | /** 16 | * @author sukenshah 17 | */ 18 | public class ClassModel extends UmlModel { 19 | 20 | @Getter 21 | private final String name; 22 | 23 | @Getter 24 | private ClassType type; 25 | 26 | @Getter 27 | @Setter 28 | private String parent; 29 | 30 | private final List fields = Lists.newArrayList(); 31 | 32 | private final List methods = Lists.newArrayList(); 33 | 34 | private final List interfaces = Lists.newArrayList(); 35 | 36 | private final List dependencies = Lists.newArrayList(); 37 | 38 | public ClassModel(final String name) { 39 | this.name = name; 40 | } 41 | 42 | public void addField(final FieldModel field) { 43 | fields.add(field); 44 | } 45 | 46 | public void addInterface(final String interfaze) { 47 | interfaces.add(interfaze); 48 | } 49 | 50 | public void addMethod(final MethodModel method) { 51 | methods.add(method); 52 | } 53 | 54 | public void addDependency(final String clazz) { 55 | dependencies.add(clazz); 56 | } 57 | 58 | public void setType(final Class clazz) { 59 | type = ClassType.CLASS; 60 | if (clazz.isInterface()) { 61 | type = ClassType.INTERFACE; 62 | } 63 | else if (clazz.isEnum()) { 64 | type = ClassType.ENUM; 65 | } 66 | else if (clazz.isAnnotation()) { 67 | type = ClassType.ANNOTATION; 68 | } 69 | else if (clazz.getModifiers() == Modifier.ABSTRACT) { 70 | type = ClassType.ABSTRACT; 71 | } 72 | } 73 | 74 | @Override 75 | public String getUml() { 76 | StringBuilder uml = new StringBuilder(); 77 | uml.append(ClassType.convert(type)).append(name).append(OPEN_PARENTHESIS).append(NEW_LINE); 78 | getFieldsUml(uml); 79 | 80 | // all methods 81 | getMethodsUml(uml); 82 | uml.append(CLOSE_PARENTHESIS); 83 | 84 | // parent relationship 85 | getDepenciesUml(uml); 86 | 87 | uml.append(NEW_LINE); 88 | return uml.toString(); 89 | } 90 | 91 | protected void getDepenciesUml(final StringBuilder uml) { 92 | if (parent != null) { 93 | uml.append(NEW_LINE).append(name).append(EXTENDS).append(parent); 94 | } 95 | 96 | // interfaces 97 | for (String interfaze : interfaces) { 98 | uml.append(NEW_LINE).append(name).append(EXTENDS).append(interfaze); 99 | } 100 | 101 | // dependencies 102 | for (String clazz : dependencies) { 103 | uml.append(NEW_LINE).append(name).append(DEPENDS).append(clazz); 104 | } 105 | } 106 | 107 | protected void getMethodsUml(final StringBuilder uml) { 108 | for (MethodModel method : methods) { 109 | if (method.isPublicOrProtected()) { 110 | uml.append(method.getUml()); 111 | uml.append(NEW_LINE); 112 | } 113 | } 114 | } 115 | 116 | protected void getFieldsUml(final StringBuilder uml) { 117 | // all public fields 118 | for (FieldModel field : fields) { 119 | if (field.isPublicOrProtected()) { 120 | uml.append(field.getUml()); 121 | uml.append(NEW_LINE); 122 | } 123 | } 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /UmlGeneratorTool/plugin.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 12 | 13 | 14 | 15 | 18 | 27 | 28 | 29 | 30 | 31 | 35 | 44 | 45 | 46 | 47 | 48 | 52 | 61 | 62 | 63 | 64 | 65 | 69 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /UmlGeneratorTool/src/main/java/umlGenerator/windows/GenerateComponentDiagramOptionsDialog.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package umlGenerator.windows; 5 | 6 | import net.sourceforge.plantuml.FileFormat; 7 | 8 | import org.eclipse.jface.dialogs.Dialog; 9 | import org.eclipse.swt.SWT; 10 | import org.eclipse.swt.layout.GridData; 11 | import org.eclipse.swt.widgets.Combo; 12 | import org.eclipse.swt.widgets.Composite; 13 | import org.eclipse.swt.widgets.Control; 14 | import org.eclipse.swt.widgets.Label; 15 | import org.eclipse.swt.widgets.Shell; 16 | import org.eclipse.swt.widgets.Text; 17 | 18 | /** 19 | * @author sukenshah 20 | */ 21 | public class GenerateComponentDiagramOptionsDialog extends Dialog { 22 | 23 | private Text includePatternsArea; 24 | private Text excludePatternsArea; 25 | private String includePatterns; 26 | private String excludePatterns; 27 | private FileFormat fileFormat; 28 | private Combo fileFormatChoice; 29 | 30 | public GenerateComponentDiagramOptionsDialog(Shell parentShell) { 31 | super(parentShell); 32 | } 33 | 34 | /** 35 | * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite) 36 | * @param parent 37 | * @return 38 | */ 39 | @Override 40 | protected Control createDialogArea(Composite parent) { 41 | Composite container = (Composite) super.createDialogArea(parent); 42 | Label includeLabel = new Label(container, SWT.NONE); 43 | includeLabel.setLayoutData(new GridData(SWT.FILL, SWT.LEFT, false, false)); 44 | includeLabel.setText("Include Patterns (comma separated)"); 45 | includePatternsArea = new Text(container, SWT.BORDER); 46 | includePatternsArea.setLayoutData(new GridData(SWT.FILL, SWT.RIGHT, false, false)); 47 | includePatternsArea.setMessage("No pattern."); 48 | 49 | Label excludeLabel = new Label(container, SWT.NONE); 50 | excludeLabel.setLayoutData(new GridData(SWT.FILL, SWT.LEFT, false, false)); 51 | excludeLabel.setText("Exclude Patterns (command separated)"); 52 | excludePatternsArea = new Text(container, SWT.BORDER); 53 | excludePatternsArea.setLayoutData(new GridData(SWT.FILL, SWT.RIGHT, false, false)); 54 | excludePatternsArea.setMessage("No pattern."); 55 | 56 | Label fileFormatLabel = new Label(container, SWT.None); 57 | fileFormatLabel.setLayoutData(new GridData(SWT.FILL, SWT.LEFT, false, false)); 58 | fileFormatLabel.setText("Export File Format"); 59 | fileFormatChoice = new Combo(container, SWT.READ_ONLY); 60 | fileFormatChoice.setLayoutData(new GridData(SWT.FILL, SWT.RIGHT, false, false)); 61 | fileFormatChoice.setItems(new String[] {FileFormat.PNG.toString(), 62 | FileFormat.PDF.toString(), 63 | FileFormat.HTML.toString(), 64 | FileFormat.SVG.toString(), 65 | FileFormat.MJPEG.toString()}); 66 | fileFormatChoice.select(0); 67 | 68 | getShell().setText("Generate Component Diagram options"); 69 | return container; 70 | } 71 | 72 | /** 73 | * Save the state of the checkboxes 74 | * @see org.eclipse.jface.dialogs.Dialog#okPressed() 75 | */ 76 | @Override 77 | protected void okPressed() { 78 | includePatterns = this.includePatternsArea.getText(); 79 | excludePatterns = this.excludePatternsArea.getText(); 80 | fileFormat = FileFormat.valueOf(this.fileFormatChoice.getItem(this.fileFormatChoice.getSelectionIndex())); 81 | super.okPressed(); 82 | } 83 | 84 | public String getIncludePattern() { 85 | return includePatterns.trim(); 86 | } 87 | 88 | public String getExcludePatterns() { 89 | return excludePatterns.trim(); 90 | } 91 | 92 | public FileFormat getFileFormat() { 93 | return fileFormat; 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /UmlGeneratorTool/src/main/java/umlGenerator/actions/GenerateComponentDiagramAction.java: -------------------------------------------------------------------------------- 1 | package umlGenerator.actions; 2 | 3 | import java.net.MalformedURLException; 4 | import java.util.logging.Level; 5 | import java.util.logging.Logger; 6 | 7 | import org.codehaus.plexus.util.ExceptionUtils; 8 | import org.eclipse.core.resources.IProject; 9 | import org.eclipse.core.runtime.CoreException; 10 | import org.eclipse.core.runtime.IProgressMonitor; 11 | import org.eclipse.core.runtime.IStatus; 12 | import org.eclipse.core.runtime.Status; 13 | import org.eclipse.core.runtime.jobs.Job; 14 | import org.eclipse.swt.widgets.Display; 15 | import org.eclipse.swt.widgets.Shell; 16 | 17 | import umlGenerator.MultipleProjectAction; 18 | import umlGenerator.windows.GenerateComponentDiagramOptionsDialog; 19 | 20 | import com.uml.generator.UmlGenerator; 21 | import com.uml.generator.UmlOptions; 22 | 23 | public class GenerateComponentDiagramAction extends MultipleProjectAction { 24 | 25 | /** 26 | * Logger. 27 | */ 28 | private static final Logger LOGGER = Logger.getLogger("GenerateComponentDiagramAction"); 29 | 30 | /** 31 | * Generate UML for the given java project. 32 | * 33 | * @param javaProject 34 | * the project for which the UML is to be generated. 35 | * @param shell 36 | * The current shell used to display progress monitors. 37 | * @throws CoreException 38 | * If unable to deploy the project. 39 | * @throws MalformedURLException 40 | * @throws DeployFailedException 41 | * If unable to deploy the project. 42 | */ 43 | @Override 44 | protected void generateUml(final IProject project, final Shell shell) throws CoreException, MalformedURLException { 45 | LOGGER.log(Level.ALL, "Starting generation of component diagram for project : " + project.getName()); 46 | 47 | // create a job such that the long running process can run in background. 48 | Job generateJob = new Job("Component Diagram Job") { 49 | 50 | @Override 51 | protected IStatus run(IProgressMonitor progress) { 52 | boolean success = true; 53 | String reason = ""; 54 | 55 | progress.beginTask("Start generating Component Diagram", 100); 56 | progress.subTask("Getting user options."); 57 | final GenerateComponentDiagramOptionsDialog dialog = new GenerateComponentDiagramOptionsDialog(shell); 58 | // create sync execution to make sure that the UI updates are performed in main UI thread. 59 | Display.getDefault().syncExec(new Runnable() { 60 | public void run() { 61 | dialog.open(); 62 | } 63 | }); 64 | 65 | // only proceed with UML generation if user pressed OK 66 | if (dialog.getReturnCode() == 0) { 67 | progress.worked(20); 68 | 69 | try { 70 | progress.subTask("Generating Component Diagram."); 71 | UmlOptions options = new UmlOptions(); 72 | options.setIncludePatterns(dialog.getIncludePattern()); 73 | options.setExcludePatterns(dialog.getExcludePatterns()); 74 | options.setFileFormat(dialog.getFileFormat()); 75 | UmlGenerator.generateComponentDiagram(project.getLocation().toFile().getPath(), 76 | project.getName(), project.getFolder("uml").getLocation().toFile().getPath(), options); 77 | progress.worked(80); 78 | LOGGER.log(Level.ALL, "Finished generation of component diagram for project : " + project.getName()); 79 | } 80 | catch (Exception e) { 81 | success = false; 82 | reason = ExceptionUtils.getStackTrace(e); 83 | } 84 | 85 | showResultDialog(shell, project.getName(), success, reason); 86 | } 87 | return Status.OK_STATUS; 88 | } 89 | 90 | }; 91 | generateJob.setPriority(Job.SHORT); 92 | generateJob.schedule(); 93 | } 94 | 95 | } 96 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | UmlGenerator 2 | ============ 3 |

4 | UML Generator provides APIs for generating UML diagrams from java source. The UML Generator uses plantuml and graphviz liraries for generating diagrams. The utility outputs UML in following format files: 5 |

    6 |
  • Plantuml text file (.plantuml) - Any plantuml standard viewer can be used to view the UML diagram.
    7 |
  • Diagram UML file (.png) 8 |
9 |

10 | 11 | The library supports following UML diagrams: 12 | 13 |

Class Diagram

14 | ![ScreenShot](https://github.com/suken/UmlGeneratorTool/blob/master/UmlGeneratorTool/icons/ClassDiagramIcon.png) 15 | The class diagram generates the followings:
16 |
    17 |
  • Fields if {@code fieldsIncluded} set to TRUE 18 |
  • Methods if {@code methodIncluded} set TRUE 19 |
  • Parent class depedencies 20 |
  • Implemented interfaces 21 |
  • Composite class dependencies 22 |
23 | ![ScreenShot](https://github.com/suken/UmlGeneratorTool/blob/master/Resources/SampleClassDiagram.png) 24 | 25 |

Spring Dependency Diagram

26 | ![ScreenShot](https://github.com/suken/UmlGeneratorTool/blob/master/UmlGeneratorTool/icons/SpringIcon.png) 27 | In addition to plain class diagram, the spring class diagram also generates followings: 28 |
    29 |
  • Autowired depedencies 30 |
  • Required depedencies 31 |
  • Resource depedencies 32 |
  • Component classes 33 |
  • Controller classes 34 |
  • Service classes 35 |
  • Repository classes 36 |
  • Bean classes 37 |
  • Configuration classes 38 |
  • Additional comments are provided for class level annotations. 39 |
40 | ![ScreenShot](https://github.com/suken/UmlGeneratorTool/blob/master/Resources/SampleSpringDependencyDiagram.png) 41 | 42 | 43 | 44 |

JPA Mapping diagram

45 | ![ScreenShot](https://github.com/suken/UmlGeneratorTool/blob/master/UmlGeneratorTool/icons/JPAIcon.png) 46 | The JPA mapping diagram utility can be used to identify the relationship between persistent classes. The utility generates the following: 47 |
    48 |
  • Persistent entity types (ENTITY, TABLE or MAPPED SUPER CLASSES) 49 |
  • Inheritance of persistent entities. 50 |
  • Mapped relationships (OntToOne, ManyToOne, OneToMany) 51 |
  • Database table name 52 |
  • Mapped database columns 53 |
  • Identifier columns 54 |
55 | Following is the sample generated JPA mapping diagram. 56 | ![ScreenShot](https://github.com/suken/UmlGeneratorTool/blob/master/Resources/SampleJPAMappingDiagram.png) 57 | 58 | 59 |

Component Diagram (Maven)

60 | ![ScreenShot](https://github.com/suken/UmlGeneratorTool/blob/master/UmlGeneratorTool/icons/ComponentDiagramIcon.png) 61 | The method recursively inspects the given source directory to parse all POM files.
62 | ![ScreenShot](https://github.com/suken/UmlGeneratorTool/blob/master/Resources/SampleComponentDiagram.png) 63 | 64 | 65 |

Warning

66 | If the UML diagram is too complicated then the GraphViz may not generate the PNG file. Try opening the plantuml file in plantuml eclipse plugin. 67 | 68 | 69 | UmlGeneratorTool 70 | ================== 71 | The UmlGeneratorTool is an Eclipse plugin to allow developers to generate UML diagrams from eclipse projects. The Eclipse plugin is compatible with Eclipse 3.5+ distributions. If you are using older version of Eclipse than God Bless You ;) 72 | 73 |

Installation Guilde

74 | Under construction. I am still setting up the maven repository for the two UML projects. Its too early for me to start releasing versions officially. 75 | But if you really feel like trying the tool out then simply import UmlGeneratorTool project in you eclipse and then export it as "Deployable plug-ins and fragments" into your eclipse plugin directory. 76 | 77 |

How to Generate UML diagrams

78 | All the available UML diagrams can be generated from project contextual menu. Here is a screen shot:
79 | ![ScreenShot](https://github.com/suken/UmlGeneratorTool/blob/master/Resources/UmlGeneratorMenu.png) 80 | 81 | Each diagram has its own options for UML generation. Please refer to the following:
82 | 83 | Class Diagram and Spring Depedency Diagram
84 | 85 | 86 | Component Diagram and JPA Mapping diagram
87 | 88 | -------------------------------------------------------------------------------- /UmlGenerator/src/main/java/com/uml/generator/jpa/models/JpaClassModel.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.uml.generator.jpa.models; 5 | 6 | import java.util.List; 7 | import java.util.Map; 8 | import java.util.Map.Entry; 9 | 10 | import lombok.Setter; 11 | 12 | import com.google.common.collect.Lists; 13 | import com.google.common.collect.Maps; 14 | import com.uml.generator.classDiagram.models.ClassModel; 15 | import com.uml.generator.classDiagram.models.ClassType; 16 | 17 | /** 18 | * @author SShah 19 | */ 20 | public class JpaClassModel extends ClassModel { 21 | 22 | private static final String TABEL = " << (T,#BB3255) TABLE >> "; 23 | private static final String MAPPED_SUPER_CLASS = " << (M,#CD45FF) MAPPED SUPER CLASS >> "; 24 | private static final String ENTITY_CLASS = " << (E,#ACFFFF) ENTITY >> "; 25 | private static final String COLUMNS_SEPARATOR = "__COLUMNS__"; 26 | private static final String ID_COLUMNS_SEPARATOR ="__ID COLUMNS__"; 27 | private static final String TABLE_NAME_SEPARATOR = "__TABLE__"; 28 | private static final String ONE_TO_ONE_UML_STR = "--"; 29 | 30 | @Setter 31 | private String tableName; 32 | @Setter 33 | private JpaEntityType jpaEntityType; 34 | private final Map jpaDependencies = Maps 35 | .newHashMap(); 36 | private final List columns = Lists.newArrayList(); 37 | private final List idColumns = Lists.newArrayList(); 38 | private final StringBuffer note = new StringBuffer(); 39 | 40 | public JpaClassModel(final String name) { 41 | super(name); 42 | } 43 | 44 | public void addJpaDependency(final String className, final JpaDependencyType type) { 45 | jpaDependencies.put(className, type); 46 | } 47 | 48 | public void removeJpaDependency(final String className) { 49 | jpaDependencies.remove(className); 50 | } 51 | 52 | public void addColumn(final String columnName) { 53 | columns.add(columnName); 54 | } 55 | 56 | public void addIdColumn(final String columnName) { 57 | idColumns.add(columnName); 58 | } 59 | 60 | public void addNote(final String text) { 61 | note.append(text).append("\\n"); 62 | } 63 | 64 | @Override 65 | public String getUml() { 66 | StringBuilder uml = new StringBuilder(); 67 | uml.append(ClassType.convert(getType())).append(getName()); 68 | 69 | switch (jpaEntityType) { 70 | case TABLE: 71 | uml.append(TABEL); 72 | break; 73 | case MAPPED_SUPER_CLASS: 74 | uml.append(MAPPED_SUPER_CLASS); 75 | break; 76 | case ENTITY: 77 | uml.append(ENTITY_CLASS); 78 | default: 79 | break; 80 | } 81 | 82 | uml.append(OPEN_PARENTHESIS).append(NEW_LINE); 83 | 84 | // add table name 85 | if (tableName != null) { 86 | uml.append(TABLE_NAME_SEPARATOR).append(NEW_LINE).append(tableName).append(NEW_LINE); 87 | } 88 | 89 | // all columns 90 | getColumnsUml(uml); 91 | 92 | uml.append(CLOSE_PARENTHESIS); 93 | 94 | // add notes 95 | if (note.length() > 0) { 96 | uml.append(NEW_LINE).append("note left of ").append(getName()).append(" : ") 97 | .append(note.substring(0, note.length() - 2)); 98 | } 99 | uml.append(NEW_LINE); 100 | 101 | // parent relationship 102 | getDepenciesUml(uml); 103 | 104 | getJpaDependenciesUml(uml); 105 | 106 | uml.append(NEW_LINE); 107 | return uml.toString(); 108 | } 109 | 110 | private void getJpaDependenciesUml(final StringBuilder uml) { 111 | for (Entry dependency : jpaDependencies.entrySet()) { 112 | String dependsUmlString = DEPENDS; 113 | if (dependency.getValue() == JpaDependencyType.ONE_TO_ONE 114 | || dependency.getValue() == JpaDependencyType.MANY_TO_MANY) { 115 | dependsUmlString = ONE_TO_ONE_UML_STR; 116 | } 117 | uml.append(NEW_LINE).append(getName()).append(dependsUmlString).append(dependency.getKey()).append(" : ").append(dependency.getValue().toString()).append(" "); 118 | } 119 | } 120 | 121 | protected void getColumnsUml(final StringBuilder uml) { 122 | if (!idColumns.isEmpty()) { 123 | uml.append(ID_COLUMNS_SEPARATOR).append(NEW_LINE); 124 | // all id columns 125 | for (String column : idColumns) { 126 | uml.append(column); 127 | uml.append(NEW_LINE); 128 | } 129 | } 130 | 131 | if (!columns.isEmpty()) { 132 | uml.append(COLUMNS_SEPARATOR).append(NEW_LINE); 133 | // all non-id columns 134 | for (String column : columns) { 135 | uml.append(column); 136 | uml.append(NEW_LINE); 137 | } 138 | } 139 | } 140 | 141 | } 142 | -------------------------------------------------------------------------------- /UmlGeneratorTool/src/main/java/umlGenerator/actions/GenerateJpaMappingDiagramAction.java: -------------------------------------------------------------------------------- 1 | package umlGenerator.actions; 2 | 3 | import java.io.File; 4 | import java.net.MalformedURLException; 5 | import java.net.URL; 6 | import java.util.List; 7 | import java.util.logging.Level; 8 | import java.util.logging.Logger; 9 | 10 | import org.codehaus.plexus.util.ExceptionUtils; 11 | import org.eclipse.core.resources.IProject; 12 | import org.eclipse.core.runtime.CoreException; 13 | import org.eclipse.core.runtime.IPath; 14 | import org.eclipse.core.runtime.IProgressMonitor; 15 | import org.eclipse.core.runtime.IStatus; 16 | import org.eclipse.core.runtime.Status; 17 | import org.eclipse.core.runtime.jobs.Job; 18 | import org.eclipse.jdt.core.IJavaProject; 19 | import org.eclipse.jdt.core.JavaCore; 20 | import org.eclipse.swt.widgets.Display; 21 | import org.eclipse.swt.widgets.Shell; 22 | 23 | import umlGenerator.MultipleProjectAction; 24 | import umlGenerator.windows.GenerateComponentDiagramOptionsDialog; 25 | 26 | import com.uml.generator.UmlGenerator; 27 | import com.uml.generator.UmlOptions; 28 | 29 | public class GenerateJpaMappingDiagramAction extends MultipleProjectAction { 30 | 31 | /** 32 | * Logger. 33 | */ 34 | private static final Logger LOGGER = Logger.getLogger("GenerateJpaMappingDiagramAction"); 35 | 36 | /** 37 | * @param javaProject 38 | * The project to deploy 39 | * @param shell 40 | * The current shell used to display progress monitors. 41 | * @throws CoreException 42 | * If unable to deploy the project. 43 | * @throws MalformedURLException 44 | * @throws DeployFailedException 45 | * If unable to deploy the project. 46 | */ 47 | @Override 48 | protected void generateUml(final IProject project, final Shell shell) throws CoreException, MalformedURLException { 49 | LOGGER.log(Level.ALL, "Starting generation of JPA mapping diagram for project : " + project.getName()); 50 | 51 | // create a job such that the long running process can run in background. 52 | Job generationJob = new Job("Generation of JPA mapping diagram") { 53 | 54 | @Override 55 | protected IStatus run(IProgressMonitor progress) { 56 | boolean success = true; 57 | String reason = ""; 58 | progress.beginTask("Starting generation of JPA mapping diagram.", 100); 59 | 60 | // get user options for uml generation 61 | progress.subTask("Get user options."); 62 | final GenerateComponentDiagramOptionsDialog dialog = new GenerateComponentDiagramOptionsDialog(shell); 63 | // create sync execution to make sure that the UI updates are performed in main UI thread. 64 | Display.getDefault().syncExec(new Runnable() { 65 | public void run() { 66 | dialog.open(); 67 | } 68 | }); 69 | 70 | // only proceed with UML generation if user pressed OK 71 | if (dialog.getReturnCode() == 0) { 72 | progress.worked(10); 73 | 74 | try { 75 | IJavaProject javaProject = JavaCore.create(project); 76 | progress.subTask("Export the project " + project.getName() + " jar file."); 77 | IPath deployedJarFile = exportProjectJar(project, shell); 78 | progress.worked(40); 79 | 80 | progress.subTask("Extracting dependent jars for project " + project.getName()); 81 | List urls = getDepedentJars(project, javaProject, javaProject.getRawClasspath(), deployedJarFile); 82 | progress.worked(10); 83 | 84 | // create output directory 85 | File umlDir = project.getFolder("uml").getLocation().toFile(); 86 | if (!umlDir.exists()) { 87 | umlDir.mkdir(); 88 | } 89 | 90 | progress.subTask("Generating JPA mapping diagram."); 91 | UmlOptions options = new UmlOptions(); 92 | options.setIncludePatterns(dialog.getIncludePattern()); 93 | options.setExcludePatterns(dialog.getExcludePatterns()); 94 | options.setFileFormat(dialog.getFileFormat()); 95 | UmlGenerator.generateJPAMappingDiagram(urls.get(0), urls.toArray(new URL[] {}), 96 | project.getName(), project.getFolder("uml").getLocation().toFile().getPath(), options); 97 | progress.worked(40); 98 | LOGGER.log(Level.ALL, "Finished generation of JPA mapping diagram for project : " + project.getName()); 99 | } 100 | catch (Exception e) { 101 | e.printStackTrace(); 102 | reason = ExceptionUtils.getStackTrace(e); 103 | success = false; 104 | } 105 | 106 | showResultDialog(shell, project.getName(), success, reason); 107 | } 108 | return Status.OK_STATUS; 109 | } 110 | }; 111 | generationJob.setPriority(Job.SHORT); 112 | generationJob.schedule(); 113 | } 114 | 115 | } 116 | -------------------------------------------------------------------------------- /UmlGeneratorTool/src/main/java/umlGenerator/actions/GenerateSpringClassDiagramAction.java: -------------------------------------------------------------------------------- 1 | package umlGenerator.actions; 2 | 3 | import java.io.File; 4 | import java.net.MalformedURLException; 5 | import java.net.URL; 6 | import java.util.List; 7 | import java.util.logging.Level; 8 | import java.util.logging.Logger; 9 | 10 | import org.codehaus.plexus.util.ExceptionUtils; 11 | import org.eclipse.core.resources.IProject; 12 | import org.eclipse.core.runtime.CoreException; 13 | import org.eclipse.core.runtime.IPath; 14 | import org.eclipse.core.runtime.IProgressMonitor; 15 | import org.eclipse.core.runtime.IStatus; 16 | import org.eclipse.core.runtime.Status; 17 | import org.eclipse.core.runtime.jobs.Job; 18 | import org.eclipse.jdt.core.IJavaProject; 19 | import org.eclipse.jdt.core.JavaCore; 20 | import org.eclipse.swt.widgets.Display; 21 | import org.eclipse.swt.widgets.Shell; 22 | 23 | import umlGenerator.MultipleProjectAction; 24 | import umlGenerator.windows.GenerateUMLOptionsDialog; 25 | 26 | import com.uml.generator.UmlGenerator; 27 | import com.uml.generator.UmlOptions; 28 | 29 | public class GenerateSpringClassDiagramAction extends MultipleProjectAction { 30 | 31 | /** 32 | * Logger. 33 | */ 34 | private static final Logger LOGGER = Logger.getLogger("GenerateSpringClassDiagramAction"); 35 | 36 | /** 37 | * Generate UML for the given project. 38 | * 39 | * @param javaProject 40 | * The project for which UML is to be generated. 41 | * @param shell 42 | * The current shell used to display progress monitors. 43 | * @throws CoreException 44 | * If unable to deploy the project. 45 | * @throws MalformedURLException 46 | * @throws DeployFailedException 47 | * If unable to deploy the project. 48 | */ 49 | @Override 50 | protected void generateUml(final IProject project, final Shell shell) throws CoreException, MalformedURLException { 51 | LOGGER.log(Level.ALL, "Starting generation of spring class diagram for project : " + project.getName()); 52 | 53 | // create a job such that the long running process can run in background. 54 | Job generationJob = new Job("Generation of Spring class diagram") { 55 | 56 | @Override 57 | protected IStatus run(IProgressMonitor progress) { 58 | boolean success = true; 59 | String reason = ""; 60 | progress.beginTask("Starting generation of spring class diagram.", 100); 61 | 62 | // get user options for uml generation 63 | progress.subTask("Get user options."); 64 | final GenerateUMLOptionsDialog dialog = new GenerateUMLOptionsDialog(shell); 65 | // create sync execution to make sure that the UI updates are performed in main UI thread. 66 | Display.getDefault().syncExec(new Runnable() { 67 | public void run() { 68 | dialog.open(); 69 | } 70 | }); 71 | 72 | // only proceed with UML generation if user pressed OK 73 | if (dialog.getReturnCode() == 0) { 74 | progress.worked(10); 75 | 76 | try { 77 | IJavaProject javaProject = JavaCore.create(project); 78 | progress.subTask("Export the project " + project.getName() + " jar file."); 79 | IPath deployedJarFile = exportProjectJar(project, shell); 80 | progress.worked(40); 81 | 82 | progress.subTask("Extracting dependent jars for project " + project.getName()); 83 | List urls = getDepedentJars(project, javaProject, javaProject.getRawClasspath(), deployedJarFile); 84 | progress.worked(10); 85 | 86 | // create output directory 87 | File umlDir = project.getFolder("uml").getLocation().toFile(); 88 | if (!umlDir.exists()) { 89 | umlDir.mkdir(); 90 | } 91 | 92 | progress.subTask("Generating Spring class diagram."); 93 | UmlOptions options = new UmlOptions(); 94 | options.setPackagesIncluded(dialog.arePackagesIncluded()); 95 | options.setTestIncluded(dialog.areTestsIncluded()); 96 | options.setFieldsIncluded(dialog.areFieldsIncluded()); 97 | options.setMethodsIncluded(dialog.areMethodsIncluded()); 98 | options.setIncludePatterns(dialog.getIncludePattern()); 99 | options.setExcludePatterns(dialog.getExcludePatterns()); 100 | options.setFileFormat(dialog.getFileFormat()); 101 | UmlGenerator.generateSpringClassDiagram(urls.get(0), urls.toArray(new URL[] {}), project.getName(), project.getFolder("uml").getLocation().toFile().getPath(), options); 102 | progress.worked(40); 103 | LOGGER.log(Level.ALL, "Finished generation of spring class diagram for project : " + project.getName()); 104 | } 105 | catch (Exception e) { 106 | e.printStackTrace(); 107 | reason = ExceptionUtils.getStackTrace(e); 108 | success = false; 109 | } 110 | 111 | showResultDialog(shell, project.getName(), success, reason); 112 | } 113 | return Status.OK_STATUS; 114 | } 115 | }; 116 | generationJob.setPriority(Job.SHORT); 117 | generationJob.schedule(); 118 | } 119 | 120 | } 121 | -------------------------------------------------------------------------------- /UmlGeneratorTool/src/main/java/umlGenerator/actions/GenerateClassDiagramAction.java: -------------------------------------------------------------------------------- 1 | package umlGenerator.actions; 2 | 3 | import java.io.File; 4 | import java.net.MalformedURLException; 5 | import java.net.URL; 6 | import java.util.List; 7 | import java.util.logging.Level; 8 | import java.util.logging.Logger; 9 | 10 | import org.codehaus.plexus.util.ExceptionUtils; 11 | import org.eclipse.core.resources.IProject; 12 | import org.eclipse.core.runtime.CoreException; 13 | import org.eclipse.core.runtime.IPath; 14 | import org.eclipse.core.runtime.IProgressMonitor; 15 | import org.eclipse.core.runtime.IStatus; 16 | import org.eclipse.core.runtime.Status; 17 | import org.eclipse.core.runtime.jobs.Job; 18 | import org.eclipse.jdt.core.IJavaProject; 19 | import org.eclipse.jdt.core.JavaCore; 20 | import org.eclipse.jface.action.IAction; 21 | import org.eclipse.swt.widgets.Display; 22 | import org.eclipse.swt.widgets.Shell; 23 | import org.eclipse.ui.IWorkbenchPart; 24 | 25 | import umlGenerator.MultipleProjectAction; 26 | import umlGenerator.windows.GenerateUMLOptionsDialog; 27 | 28 | import com.uml.generator.UmlGenerator; 29 | import com.uml.generator.UmlOptions; 30 | 31 | public class GenerateClassDiagramAction extends MultipleProjectAction { 32 | 33 | private static final Logger LOGGER = Logger.getLogger("GenerateClassDiagramAction"); 34 | 35 | /** 36 | * {@inheritDoc} 37 | */ 38 | public void setActivePart(IAction action, IWorkbenchPart targetPart) { 39 | } 40 | 41 | /** 42 | * Generate UML diagram for the given project. 43 | * 44 | * @param javaProject 45 | * The project for which the UML is to be generated. 46 | * @param shell 47 | * The current shell used to display progress monitors. 48 | * @throws CoreException 49 | * If unable to deploy the project. 50 | * @throws MalformedURLException 51 | * @throws DeployFailedException 52 | * If unable to deploy the project. 53 | */ 54 | @Override 55 | protected void generateUml(final IProject project, final Shell shell) throws CoreException, MalformedURLException { 56 | LOGGER.log(Level.INFO, "Starting generation of class diagram for project : " + project.getName()); 57 | 58 | // create a job such that the long running process can run in background. 59 | Job generateJob = new Job("Class Diagram Job") { 60 | 61 | @Override 62 | protected IStatus run(IProgressMonitor progress) { 63 | boolean success = true; 64 | String reason = ""; 65 | 66 | progress.beginTask("Starting the task.", 100); 67 | progress.subTask("Getting user UML generation options."); 68 | 69 | // get user options for uml generation 70 | final GenerateUMLOptionsDialog dialog = new GenerateUMLOptionsDialog(shell); 71 | // create sync execution to make sure that the UI updates are performed in main UI thread. 72 | Display.getDefault().syncExec(new Runnable() { 73 | public void run() { 74 | dialog.open(); 75 | } 76 | }); 77 | 78 | // only proceed with UML generation if user pressed OK 79 | if (dialog.getReturnCode() == 0) { 80 | IJavaProject javaProject = JavaCore.create(project); 81 | progress.worked(10); 82 | 83 | try { 84 | progress.subTask("Exporting project " 85 | + project.getName() + " to jar file."); 86 | final IPath deployedJarFile = exportProjectJar(project, 87 | shell); 88 | progress.worked(40); 89 | 90 | progress.subTask("Extracting dependent jars for " 91 | + project.getName()); 92 | List urls = getDepedentJars(project, javaProject, 93 | javaProject.getRawClasspath(), deployedJarFile); 94 | progress.worked(10); 95 | 96 | // create output directory 97 | File umlDir = project.getFolder("uml").getLocation() 98 | .toFile(); 99 | if (!umlDir.exists()) { 100 | umlDir.mkdir(); 101 | } 102 | 103 | progress.subTask("Generating class diagram for " 104 | + project.getName()); 105 | UmlOptions options = new UmlOptions(); 106 | options.setPackagesIncluded(dialog 107 | .arePackagesIncluded()); 108 | options.setTestIncluded(dialog.areTestsIncluded()); 109 | options.setFieldsIncluded(dialog.areFieldsIncluded()); 110 | options.setMethodsIncluded(dialog.areMethodsIncluded()); 111 | options.setIncludePatterns(dialog.getIncludePattern()); 112 | options.setExcludePatterns(dialog.getExcludePatterns()); 113 | options.setFileFormat(dialog.getFileFormat()); 114 | UmlGenerator.generateClassDiagram(urls.get(0), 115 | urls.toArray(new URL[] {}), project.getName(), 116 | umlDir.getPath(), options); 117 | LOGGER.log(Level.INFO, 118 | "Finished generation of class diagram for project : " 119 | + project.getName()); 120 | progress.worked(40); 121 | } catch (Exception e) { 122 | // capture exception and show it to user 123 | e.printStackTrace(); 124 | reason = ExceptionUtils.getStackTrace(e); 125 | success = false; 126 | } 127 | 128 | // show the final result 129 | showResultDialog(shell, project.getName(), success, reason); 130 | } 131 | return Status.OK_STATUS; 132 | } 133 | }; 134 | generateJob.setPriority(Job.SHORT); 135 | generateJob.schedule(); 136 | } 137 | 138 | } 139 | -------------------------------------------------------------------------------- /UmlGenerator/src/main/java/com/uml/generator/componentDiagram/ComponentDiagramGenerator.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.uml.generator.componentDiagram; 5 | 6 | import java.io.File; 7 | import java.io.FileFilter; 8 | import java.io.FileInputStream; 9 | import java.io.FileNotFoundException; 10 | import java.io.IOException; 11 | import java.util.ArrayList; 12 | import java.util.Arrays; 13 | import java.util.List; 14 | import java.util.regex.Matcher; 15 | import java.util.regex.Pattern; 16 | 17 | import org.apache.maven.model.Dependency; 18 | import org.apache.maven.model.Model; 19 | import org.apache.maven.model.io.xpp3.MavenXpp3Reader; 20 | import org.apache.maven.project.MavenProject; 21 | import org.codehaus.plexus.util.xml.pull.XmlPullParserException; 22 | 23 | import com.uml.generator.UmlOptions; 24 | import com.uml.generator.componentDiagram.models.ComponentDiagramModel; 25 | import com.uml.generator.componentDiagram.models.ComponentModel; 26 | import com.uml.generator.componentDiagram.models.ComponentType; 27 | 28 | /** 29 | * @author shahs 30 | */ 31 | public class ComponentDiagramGenerator { 32 | 33 | public static String generateComponentDiagram(String srcDir, UmlOptions options) throws FileNotFoundException, IOException, XmlPullParserException { 34 | String uml = ""; 35 | // extract all POM files from the source dir 36 | List pomFiles = getAllPOMFiles(new File(srcDir)); 37 | uml = processPomFiles(pomFiles, options.getIncludePatterns(), options.getExcludePatterns()); 38 | return uml; 39 | } 40 | 41 | private static String processPomFiles(List pomFiles, String includePatternsString, String excludePatternsString) throws FileNotFoundException, IOException, XmlPullParserException { 42 | ComponentDiagramModel diagramModel = new ComponentDiagramModel(); 43 | MavenXpp3Reader reader = new MavenXpp3Reader(); 44 | String[] includePatterns = includePatternsString.split(","); 45 | String[] excludePatterns = excludePatternsString.split(","); 46 | 47 | // process all POM files 48 | for (File pomFile : pomFiles) { 49 | Model model = reader.read(new FileInputStream(pomFile)); 50 | MavenProject project = new MavenProject(model); 51 | 52 | // check if the packaging is jar 53 | if (!project.getPackaging().equalsIgnoreCase("pom")) { 54 | String groupId = project.getGroupId(); 55 | ComponentModel component = new ComponentModel(project.getArtifactId(), ComponentType.SOURCE); 56 | diagramModel.addComponent(component, groupId); 57 | 58 | // find out dependencies 59 | for (Dependency dependency : project.getDependencies()) { 60 | // only add the dependency if it satisfies the include/exclude patterns 61 | if (isIncluded(dependency.getArtifactId(), includePatterns, excludePatterns)) { 62 | if (!diagramModel.containsComponent(dependency.getArtifactId(), dependency.getGroupId())) { 63 | diagramModel.addComponent(new ComponentModel(dependency.getArtifactId(), ComponentType.SOURCE), dependency.getGroupId()); 64 | } 65 | component.addDepedentComponent(dependency.getArtifactId()); 66 | } 67 | } 68 | } 69 | } 70 | return diagramModel.getUml(); 71 | } 72 | 73 | private static boolean isIncluded(String artifactId, String[] includePatterns, String[] excludePatterns) { 74 | if (includePatterns.length == 1 && excludePatterns.length == 1 75 | && includePatterns[0].isEmpty() && excludePatterns[0].isEmpty()) { 76 | return true; 77 | } 78 | 79 | // check exclude patterns 80 | for (String patternText : excludePatterns) { 81 | if (!patternText.isEmpty()) { 82 | Pattern pattern = Pattern.compile(patternText); 83 | Matcher matcher = pattern.matcher(artifactId); 84 | if (matcher.matches()) { 85 | return false; 86 | } 87 | } 88 | } 89 | 90 | // check for include pattern 91 | for (String patternText : includePatterns) { 92 | if (!patternText.isEmpty()) { 93 | Pattern pattern = Pattern.compile(patternText); 94 | Matcher matcher = pattern.matcher(artifactId); 95 | if (matcher.matches()) { 96 | return true; 97 | } 98 | } 99 | } 100 | // by default the artifact is included 101 | return true; 102 | } 103 | 104 | private static List getAllPOMFiles(File srcDir) { 105 | List pomFiles = new ArrayList(); 106 | if (srcDir.exists()) { 107 | // get all POM files at this level 108 | File[] files = srcDir.listFiles(new FileFilter() { 109 | 110 | @Override 111 | public boolean accept(File file) { 112 | return file.isFile() 113 | && file.getName().equalsIgnoreCase("pom.xml") ? true 114 | : false; 115 | } 116 | }); 117 | if (files != null) { 118 | pomFiles.addAll(Arrays.asList(files)); 119 | } 120 | 121 | // inspect the sub directories 122 | File[] directories = srcDir.listFiles(new FileFilter() { 123 | 124 | @Override 125 | public boolean accept(File file) { 126 | return file.isDirectory(); 127 | } 128 | }); 129 | 130 | if (directories != null) { 131 | // recursive call to get all POM files 132 | for (File dir : directories) { 133 | pomFiles.addAll(getAllPOMFiles(dir)); 134 | } 135 | } 136 | } 137 | return pomFiles; 138 | } 139 | 140 | } 141 | -------------------------------------------------------------------------------- /UmlGeneratorTool/src/main/java/umlGenerator/windows/GenerateUMLOptionsDialog.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package umlGenerator.windows; 5 | 6 | import net.sourceforge.plantuml.FileFormat; 7 | 8 | import org.eclipse.jface.dialogs.Dialog; 9 | import org.eclipse.swt.SWT; 10 | import org.eclipse.swt.layout.GridData; 11 | import org.eclipse.swt.widgets.Button; 12 | import org.eclipse.swt.widgets.Combo; 13 | import org.eclipse.swt.widgets.Composite; 14 | import org.eclipse.swt.widgets.Control; 15 | import org.eclipse.swt.widgets.Label; 16 | import org.eclipse.swt.widgets.Shell; 17 | import org.eclipse.swt.widgets.Text; 18 | 19 | /** 20 | * @author sukenshah 21 | */ 22 | public class GenerateUMLOptionsDialog extends Dialog { 23 | 24 | private boolean packagesVisible = true; 25 | private Button packagesCheckbox; 26 | private boolean methodsVisible = true; 27 | private Button methodsCheckbox; 28 | private boolean fieldsVisible = false; 29 | private Button fieldsCheckbox; 30 | private boolean testsVisible = false; 31 | private Button testsCheckbox; 32 | private Text includePatternsArea; 33 | private Text excludePatternsArea; 34 | private String includePatterns; 35 | private String excludePatterns; 36 | private FileFormat fileFormat; 37 | private Combo fileFormatChoice; 38 | 39 | public GenerateUMLOptionsDialog(Shell parentShell) { 40 | super(parentShell); 41 | } 42 | 43 | /** 44 | * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite) 45 | * @param parent 46 | * @return 47 | */ 48 | @Override 49 | protected Control createDialogArea(Composite parent) { 50 | Composite container = (Composite) super.createDialogArea(parent); 51 | 52 | packagesCheckbox = new Button(container, SWT.CHECK); 53 | packagesCheckbox.setLayoutData(new GridData(SWT.LEFT_TO_RIGHT, SWT.CENTER, false, false)); 54 | packagesCheckbox.setText("Packages"); 55 | packagesCheckbox.setSelection(true); 56 | 57 | methodsCheckbox = new Button(container, SWT.CHECK); 58 | methodsCheckbox.setLayoutData(new GridData(SWT.LEFT_TO_RIGHT, SWT.CENTER, false, false)); 59 | methodsCheckbox.setText("Methods"); 60 | methodsCheckbox.setSelection(true); 61 | 62 | fieldsCheckbox = new Button(container, SWT.CHECK); 63 | fieldsCheckbox.setLayoutData(new GridData(SWT.LEFT_TO_RIGHT, SWT.CENTER, false, false)); 64 | fieldsCheckbox.setText("Fields"); 65 | fieldsCheckbox.setSelection(false); 66 | 67 | testsCheckbox = new Button(container, SWT.CHECK); 68 | testsCheckbox.setLayoutData(new GridData(SWT.LEFT_TO_RIGHT, SWT.CENTER, false, false)); 69 | testsCheckbox.setText("Tests"); 70 | testsCheckbox.setSelection(false); 71 | 72 | Label includeLabel = new Label(container, SWT.NONE); 73 | includeLabel.setLayoutData(new GridData(SWT.FILL, SWT.LEFT, false, false)); 74 | includeLabel.setText("Include Patterns (comma separated)"); 75 | includePatternsArea = new Text(container, SWT.BORDER); 76 | includePatternsArea.setLayoutData(new GridData(SWT.FILL, SWT.RIGHT, false, false)); 77 | includePatternsArea.setMessage("No pattern."); 78 | 79 | Label excludeLabel = new Label(container, SWT.NONE); 80 | excludeLabel.setLayoutData(new GridData(SWT.FILL, SWT.LEFT, false, false)); 81 | excludeLabel.setText("Exclude Patterns (command separated)"); 82 | excludePatternsArea = new Text(container, SWT.BORDER); 83 | excludePatternsArea.setLayoutData(new GridData(SWT.FILL, SWT.RIGHT, false, false)); 84 | excludePatternsArea.setMessage("No pattern."); 85 | 86 | Label fileFormatLabel = new Label(container, SWT.None); 87 | fileFormatLabel.setLayoutData(new GridData(SWT.FILL, SWT.LEFT, false, false)); 88 | fileFormatLabel.setText("Export File Format"); 89 | fileFormatChoice = new Combo(container, SWT.READ_ONLY); 90 | fileFormatChoice.setLayoutData(new GridData(SWT.FILL, SWT.RIGHT, false, false)); 91 | fileFormatChoice.setItems(new String[] {FileFormat.PNG.toString(), 92 | FileFormat.PDF.toString(), 93 | FileFormat.HTML.toString(), 94 | FileFormat.SVG.toString(), 95 | FileFormat.MJPEG.toString()}); 96 | fileFormatChoice.select(0); 97 | 98 | getShell().setText("Generate UML options"); 99 | return container; 100 | } 101 | 102 | /** 103 | * Save the state of the checkboxes 104 | * @see org.eclipse.jface.dialogs.Dialog#okPressed() 105 | */ 106 | @Override 107 | protected void okPressed() { 108 | fieldsVisible = this.fieldsCheckbox.getSelection(); 109 | methodsVisible = this.methodsCheckbox.getSelection(); 110 | testsVisible = this.testsCheckbox.getSelection(); 111 | packagesVisible = this.packagesCheckbox.getSelection(); 112 | includePatterns = this.includePatternsArea.getText(); 113 | excludePatterns = this.excludePatternsArea.getText(); 114 | fileFormat = FileFormat.valueOf(this.fileFormatChoice.getItem(this.fileFormatChoice.getSelectionIndex())); 115 | super.okPressed(); 116 | } 117 | 118 | public boolean areFieldsIncluded() { 119 | return fieldsVisible; 120 | } 121 | 122 | public boolean areMethodsIncluded() { 123 | return methodsVisible; 124 | } 125 | 126 | public boolean areTestsIncluded() { 127 | return testsVisible; 128 | } 129 | 130 | public boolean arePackagesIncluded() { 131 | return packagesVisible; 132 | } 133 | 134 | public String getIncludePattern() { 135 | return includePatterns.trim(); 136 | } 137 | 138 | public String getExcludePatterns() { 139 | return excludePatterns.trim(); 140 | } 141 | 142 | public FileFormat getFileFormat() { 143 | return fileFormat; 144 | } 145 | 146 | } 147 | -------------------------------------------------------------------------------- /UmlGenerator/src/main/java/com/uml/generator/classDiagram/ClassDiagramGenerator.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.uml.generator.classDiagram; 5 | 6 | import java.beans.IntrospectionException; 7 | import java.lang.reflect.Field; 8 | import java.lang.reflect.Method; 9 | import java.net.URL; 10 | import java.net.URLClassLoader; 11 | import java.util.ArrayList; 12 | import java.util.Enumeration; 13 | import java.util.List; 14 | import java.util.jar.JarEntry; 15 | import java.util.jar.JarFile; 16 | import java.util.logging.Level; 17 | import java.util.logging.Logger; 18 | 19 | import com.uml.generator.UmlGeneratorUtility; 20 | import com.uml.generator.UmlOptions; 21 | import com.uml.generator.classDiagram.models.ClassDiagramModel; 22 | import com.uml.generator.classDiagram.models.ClassModel; 23 | import com.uml.generator.classDiagram.models.ClassType; 24 | import com.uml.generator.classDiagram.models.FieldModel; 25 | import com.uml.generator.classDiagram.models.MethodModel; 26 | 27 | /** 28 | * @author suken shah 29 | */ 30 | public class ClassDiagramGenerator { 31 | 32 | private static Logger LOGGER = Logger.getLogger(ClassDiagramGenerator.class.getSimpleName()); 33 | 34 | public static ClassDiagramModel generateClassDependencies(URLClassLoader classLoader, URL jarUrl, UmlOptions options) throws Exception { 35 | ClassDiagramModel classDiagramModel = new ClassDiagramModel(); 36 | LOGGER.log(Level.INFO, "Loading classes"); 37 | JarFile jarFile = null; 38 | try { 39 | List classes = new ArrayList(); 40 | jarFile = new JarFile(jarUrl.getFile()); 41 | if (jarFile != null) { 42 | Enumeration entries = jarFile.entries(); 43 | while (entries.hasMoreElements()) { 44 | JarEntry jarEntry = entries.nextElement(); 45 | String jarEntryName = jarEntry.getName(); 46 | // exclude test classes if testIncluded is set to FALSE 47 | if (jarEntryName.endsWith(".class") && (options.isTestIncluded() || !jarEntryName.contains("Test"))) { 48 | String className = jarEntryName.replace('/', '.').replace(".class", ""); 49 | classes.add(className); 50 | } 51 | } 52 | } 53 | 54 | // Parse all the classes for UML 55 | extractClassInformation(classLoader, classes, classDiagramModel, options.isPackagesIncluded(), options.isFieldsIncluded(), options.isMethodsIncluded(), options.getIncludePatterns(), 56 | options.getExcludePatterns()); 57 | 58 | } 59 | catch (Exception e) { 60 | e.printStackTrace(); 61 | LOGGER.log(Level.INFO, "exception while loading and parsing class information." + e.getMessage()); 62 | } 63 | finally { 64 | if (jarFile != null) { 65 | jarFile.close(); 66 | } 67 | } 68 | return classDiagramModel; 69 | } 70 | 71 | private static void extractClassInformation(URLClassLoader classLoader, List classes, ClassDiagramModel classDiagramModel, boolean packagesIncluded, // 72 | boolean fieldsVisible, boolean methodsVisible, String includePatternString, String excludePatternString) // 73 | throws ClassNotFoundException, IntrospectionException { 74 | String[] includePatterns = includePatternString.split(","); 75 | String[] excludePatterns = excludePatternString.split(","); 76 | boolean hasAnyPatterns = !(includePatterns.length == 1 && includePatterns[0].isEmpty()) // 77 | || !(excludePatterns.length == 1 && excludePatterns[0].isEmpty()); 78 | for (String className : classes) { 79 | if (UmlGeneratorUtility.isIncluded(className, hasAnyPatterns, includePatterns, excludePatterns)) { 80 | Class loadClass = classLoader.loadClass(className); 81 | if (!loadClass.getSimpleName().isEmpty()) { 82 | // extract class info 83 | ClassModel classModel = new ClassModel(packagesIncluded ? loadClass.getName() : loadClass.getSimpleName()); 84 | classModel.setType(loadClass); 85 | 86 | // do not extract field and method information for ENUM 87 | if (classModel.getType() != ClassType.ENUM) { 88 | extractFieldsAndMethods(classes, packagesIncluded, fieldsVisible, methodsVisible, includePatterns, // 89 | excludePatterns, hasAnyPatterns, loadClass, classModel); 90 | } 91 | 92 | // extract interfaces 93 | for (Class interfaceClass : loadClass.getInterfaces()) { 94 | if (UmlGeneratorUtility.isIncluded(interfaceClass.getName(), hasAnyPatterns, includePatterns, excludePatterns)) { 95 | classModel.addInterface(packagesIncluded ? interfaceClass.getName() : interfaceClass.getSimpleName()); 96 | } 97 | } 98 | 99 | // extract parent class 100 | Class superclass = loadClass.getSuperclass(); 101 | if (superclass != null && !superclass.equals(Object.class)) { 102 | if (UmlGeneratorUtility.isIncluded(superclass.getName(), hasAnyPatterns, includePatterns, excludePatterns)) { 103 | classModel.setParent(packagesIncluded ? superclass.getName() : superclass.getSimpleName()); 104 | } 105 | } 106 | 107 | // extract dependencies 108 | for (Class dependentClass : loadClass.getDeclaredClasses()) { 109 | if (UmlGeneratorUtility.isIncluded(dependentClass.getName(), hasAnyPatterns, includePatterns, excludePatterns)) { 110 | classModel.addDependency(packagesIncluded ? dependentClass.getName() : dependentClass.getSimpleName()); 111 | } 112 | } 113 | 114 | // add prepared class model to class diagram 115 | classDiagramModel.addClass(classModel); 116 | } 117 | } 118 | } 119 | } 120 | 121 | private static void extractFieldsAndMethods(List classes, boolean packagesIncluded, boolean fieldsVisible, boolean methodsVisible, // 122 | String[] includePatterns, String[] excludePatterns, 123 | boolean hasAnyPatterns, Class loadClass, ClassModel classModel) { 124 | // extract fields 125 | for (Field field : loadClass.getDeclaredFields()) { 126 | try { 127 | Class fieldType = field.getType(); 128 | String type = fieldType.getName().replace("[", "").replace("]", ""); 129 | if (classes.contains(type) && UmlGeneratorUtility.isIncluded(fieldType.getName(), hasAnyPatterns, includePatterns, excludePatterns)) { 130 | classModel.addDependency(packagesIncluded ? fieldType.getName() : fieldType.getSimpleName()); 131 | } 132 | else if (fieldsVisible && !field.isSynthetic()) { 133 | // only add field if visibility is set 134 | classModel.addField(new FieldModel(field.getName(), fieldType.getSimpleName(), field.getModifiers())); 135 | } 136 | } 137 | catch (Exception e) { 138 | // no need to do anything 139 | continue; 140 | } 141 | catch (NoClassDefFoundError error) { 142 | // no need to do anything 143 | continue; 144 | } 145 | } 146 | 147 | // extract methods 148 | if (methodsVisible) { 149 | for (Method method : loadClass.getDeclaredMethods()) { 150 | if (!method.isSynthetic() && !method.isBridge()) { 151 | classModel.addMethod(new MethodModel(method.getName(), method.getModifiers())); 152 | } 153 | } 154 | } 155 | } 156 | 157 | } 158 | -------------------------------------------------------------------------------- /UmlGenerator/src/main/java/com/uml/generator/UmlGenerator.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.uml.generator; 5 | 6 | import java.io.BufferedWriter; 7 | import java.io.File; 8 | import java.io.FileWriter; 9 | import java.io.IOException; 10 | import java.net.URL; 11 | import java.net.URLClassLoader; 12 | import java.util.logging.Level; 13 | import java.util.logging.Logger; 14 | 15 | import net.sourceforge.plantuml.FileFormat; 16 | import net.sourceforge.plantuml.FileFormatOption; 17 | import net.sourceforge.plantuml.SourceFileReader; 18 | 19 | import com.uml.generator.classDiagram.ClassDiagramGenerator; 20 | import com.uml.generator.classDiagram.models.ClassDiagramModel; 21 | import com.uml.generator.componentDiagram.ComponentDiagramGenerator; 22 | import com.uml.generator.jpa.JpaMappingDiagramGenerator; 23 | import com.uml.generator.spring.SpringDependencyDiagramGenerator; 24 | 25 | /** 26 | * @author sukenshah 27 | */ 28 | public class UmlGenerator { 29 | 30 | private static final Logger LOGGER = Logger.getLogger("UmlGenerator"); 31 | 32 | /** 33 | * Generate the Spring class diagram for the given project jar. The method generates following: 34 | *
    35 | *
  • plant uml text file (*.plantuml) 36 | *
  • class diagram UML file (*.png) 37 | *
38 | * 39 | * The class diagram generates the followings: 40 | *
    41 | *
  • Fields if {@code fieldsIncluded} set to TRUE 42 | *
  • Methods if {@code methodIncluded} set TRUE 43 | *
  • Parent class depedencies 44 | *
  • Implemented interfaces 45 | *
  • Composite class dependencies 46 | *
47 | * 48 | * Warning
49 | * If the component diagram is too complicated then the GraphViz may not generate the PNG file. Try opening the plantuml file in plantuml eclipse plugin. 50 | *

51 | * 52 | * @param projectJarUrl URL of the project jar for which the class diagram is to be generated. 53 | * @param jarURLs dependent jars 54 | * @param packagesIncluded Are packages included? 55 | * @param fieldsIncluded Are fields included? 56 | * @param methodsIncluded Are methods included? 57 | * @param testIncluded Are tests included? 58 | * @param projectName name of the project 59 | * @param umlDirPath Output directory path 60 | * @throws Exception If anything goes wrong just raise it to the caller. 61 | */ 62 | public static void generateClassDiagram(URL projectJarUrl, URL[] jarURLs, String projectName, String umlDirPath, UmlOptions options) throws Exception { 63 | ClassLoader loader = Thread.currentThread().getContextClassLoader(); 64 | try { 65 | // parse all the classes from the jars 66 | URLClassLoader classLoader = new URLClassLoader(jarURLs); 67 | Thread.currentThread().setContextClassLoader(classLoader); 68 | ClassDiagramModel classDiagramModel = ClassDiagramGenerator.generateClassDependencies(classLoader, projectJarUrl, options); 69 | String uml = classDiagramModel.getUml().replace("$", "_Inner"); 70 | 71 | // generate the UML and plant uml text files 72 | String sourceFilePath = exportToPlantUMLFile(projectName, umlDirPath, uml, "_ClassDiagram"); 73 | exportToFile(projectName, umlDirPath, sourceFilePath, "_ClassDiagram", options.getFileFormat()); 74 | } 75 | finally { 76 | Thread.currentThread().setContextClassLoader(loader); 77 | } 78 | } 79 | 80 | /** 81 | * Generate the Spring class diagram for the given project jar. The method generates following: 82 | *

    83 | *
  • plant uml text file (*.plantuml) 84 | *
  • class diagram UML file (*.png) 85 | *
86 | * 87 | * In addition to plain class diagram, the spring class diagram also generates followings: 88 | *
    89 | *
  • Autowired depedencies 90 | *
  • Required depedencies 91 | *
  • Resource depedencies 92 | *
  • Component classes 93 | *
  • Controller classes 94 | *
  • Service classes 95 | *
  • Repository classes 96 | *
  • Bean classes 97 | *
  • Configuration classes 98 | *
  • Additional comments are provided for class level annotations. 99 | *
100 | * 101 | * Warning
102 | * If the component diagram is too complicated then the GraphViz may not generate the PNG file. Try opening the plantuml file in plantuml eclipse plugin. 103 | *

104 | * 105 | * @param projectJarUrl URL of the project jar for which the class diagram is to be generated. 106 | * @param jarURLs dependent jars 107 | * @param packagesIncluded Are packages included? 108 | * @param fieldsIncluded Are fields included? 109 | * @param methodsIncluded Are methods included? 110 | * @param testIncluded Are tests included? 111 | * @param projectName name of the project 112 | * @param umlDirPath Output directory path 113 | * @throws Exception If anything goes wrong just raise it to the caller. 114 | */ 115 | public static void generateSpringClassDiagram(URL projectJarUrl, URL[] jarURLs, String projectName, String umlDirPath, UmlOptions options) throws IOException { 116 | ClassLoader loader = Thread.currentThread().getContextClassLoader(); 117 | try { 118 | // parse all the classes from the jars 119 | URLClassLoader classLoader = new URLClassLoader(jarURLs); 120 | Thread.currentThread().setContextClassLoader(classLoader); 121 | String uml = SpringDependencyDiagramGenerator.generateSpringDependencies(classLoader, projectJarUrl, options).replace("$", "_Inner"); 122 | 123 | // generate the UML and plant uml text files 124 | exportToPlantUMLFile(projectName, umlDirPath, uml, "_SpringDependencyDiagram"); 125 | exportToFile(projectName, umlDirPath, uml, "_SpringDependencyDiagram", options.getFileFormat()); 126 | } 127 | finally { 128 | Thread.currentThread().setContextClassLoader(loader); 129 | } 130 | } 131 | 132 | /** 133 | * Generates the component diagram for the given MAVEN project. The method generates the following: 134 | *

    135 | *
  • plantuml text file (*.plantuml) 136 | *
  • component diagram image file (*.png) 137 | *
138 | * 139 | * NOTE:
140 | * The method recursively inspects the given source directory to parse all POM files. 141 | *

142 | * 143 | * Warning
144 | * If the component diagram is too complicated then the GraphViz may not generate the PNG file. Try opening the plantuml file in plantuml eclipse plugin. 145 | * 146 | * @param srcDir directory which contains the POM files. 147 | * @param projectName Name of the project for which the component diagram is to be generated. 148 | * @param includePatterns regular expression of included artifact id patterns 149 | * @param excludePatterns regular expression of excluded artifact id patterns 150 | * @param umlDirPath output directory to write UML 151 | * @throws Exception If anything goes wrong then raise it to the caller. 152 | */ 153 | public static void generateComponentDiagram(String srcDir, String projectName, String umlDirPath, UmlOptions options) throws Exception { 154 | String uml = ComponentDiagramGenerator.generateComponentDiagram(srcDir, options); 155 | // generate the UML and plant uml text files 156 | exportToPlantUMLFile(projectName, umlDirPath, uml, "_ComponentDiagram"); 157 | exportToFile(projectName, umlDirPath, uml, "_ComponentDiagram", options.getFileFormat()); 158 | } 159 | 160 | /** 161 | * Generates the JPA mapping diagram for the given project. The method generates the following: 162 | *

    163 | *
  • plantuml text file (*.plantuml) 164 | *
  • component diagram image file (*.png) 165 | *
166 | * 167 | * Warning
168 | * If the component diagram is too complicated then the GraphViz may not generate the PNG file. Try opening the plantuml file in plantuml eclipse plugin. 169 | * 170 | * @param srcDir directory which contains the POM files. 171 | * @param projectName Name of the project for which the component diagram is to be generated. 172 | * @param includePatterns regular expression of included artifact id patterns 173 | * @param excludePatterns regular expression of excluded artifact id patterns 174 | * @param umlDirPath output directory to write UML 175 | * @throws Exception If anything goes wrong then raise it to the caller. 176 | */ 177 | public static void generateJPAMappingDiagram(URL projectJarUrl, URL[] jarURLs, String projectName, String umlDirPath, UmlOptions options) throws Exception { 178 | ClassLoader loader = Thread.currentThread().getContextClassLoader(); 179 | try { 180 | // parse all the classes from the jars 181 | URLClassLoader classLoader = new URLClassLoader(jarURLs); 182 | Thread.currentThread().setContextClassLoader(classLoader); 183 | String uml = JpaMappingDiagramGenerator.generateJpaDependencies(classLoader, projectJarUrl, options).replace("$", "_Inner"); 184 | 185 | // generate the UML and plant uml text files 186 | exportToPlantUMLFile(projectName, umlDirPath, uml, "_JPAMappingDiagram"); 187 | exportToFile(projectName, umlDirPath, uml, "_JPAMappingDiagram", options.getFileFormat()); 188 | } 189 | finally { 190 | Thread.currentThread().setContextClassLoader(loader); 191 | } 192 | } 193 | 194 | private static String exportToPlantUMLFile(String projectName, String umlDirPath, String uml, String filePostfix) throws IOException { 195 | LOGGER.log(Level.INFO, "Writing PlantUML string to *.plantuml file"); 196 | String umlStringFile = umlDirPath + File.separator + projectName + filePostfix + ".plantuml"; 197 | // write plant UML text file 198 | BufferedWriter writer = new BufferedWriter(new FileWriter(umlStringFile)); 199 | writer.write(uml); 200 | writer.flush(); 201 | writer.close(); 202 | LOGGER.log(Level.INFO, "The UML diagram is generated under " + umlDirPath); 203 | return umlStringFile; 204 | } 205 | 206 | private static void exportToFile(String projectName, String umlDirPath, String sourceFilePath, String filePostfix, FileFormat format) throws IOException { 207 | LOGGER.log(Level.INFO, "Writing PlantUML string to *." + format + " file"); 208 | // String umlFile = umlDirPath + File.separator + projectName + filePostfix + ".png"; 209 | // File umlDir = new File(umlDirPath); 210 | // if (umlDir.exists()) { 211 | // umlDir.delete(); 212 | // } 213 | 214 | // write the plant UML image file 215 | SourceFileReader reader = new SourceFileReader(new File(sourceFilePath), new File(umlDirPath), new FileFormatOption(format)); 216 | reader.getGeneratedImages(); 217 | } 218 | 219 | } 220 | -------------------------------------------------------------------------------- /UmlGenerator/src/main/java/com/uml/generator/jpa/JpaMappingDiagramGenerator.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.uml.generator.jpa; 5 | 6 | import java.lang.annotation.Annotation; 7 | import java.lang.reflect.Field; 8 | import java.lang.reflect.InvocationTargetException; 9 | import java.lang.reflect.Method; 10 | import java.lang.reflect.ParameterizedType; 11 | import java.lang.reflect.Type; 12 | import java.net.URL; 13 | import java.net.URLClassLoader; 14 | import java.util.ArrayList; 15 | import java.util.Enumeration; 16 | import java.util.HashMap; 17 | import java.util.List; 18 | import java.util.Map; 19 | import java.util.jar.JarEntry; 20 | import java.util.jar.JarFile; 21 | 22 | import javax.persistence.Column; 23 | import javax.persistence.Entity; 24 | import javax.persistence.Id; 25 | import javax.persistence.ManyToMany; 26 | import javax.persistence.ManyToOne; 27 | import javax.persistence.MappedSuperclass; 28 | import javax.persistence.OneToMany; 29 | import javax.persistence.OneToOne; 30 | import javax.persistence.Table; 31 | 32 | import com.uml.generator.UmlGeneratorUtility; 33 | import com.uml.generator.UmlOptions; 34 | import com.uml.generator.jpa.models.JpaClassModel; 35 | import com.uml.generator.jpa.models.JpaDependencyDiagramModel; 36 | import com.uml.generator.jpa.models.JpaDependencyType; 37 | import com.uml.generator.jpa.models.JpaEntityType; 38 | 39 | /** 40 | * @author SShah 41 | */ 42 | public class JpaMappingDiagramGenerator { 43 | 44 | public static String generateJpaDependencies(final URLClassLoader classLoader, final URL jarUrl, final UmlOptions options) { 45 | JpaDependencyDiagramModel dependencyModel = new JpaDependencyDiagramModel(); 46 | try { 47 | List classes = new ArrayList(); 48 | final JarFile jarFile = new JarFile(jarUrl.getFile()); 49 | if (jarFile != null) { 50 | Enumeration entries = jarFile.entries(); 51 | while (entries.hasMoreElements()) { 52 | JarEntry jarEntry = entries.nextElement(); 53 | String jarEntryName = jarEntry.getName(); 54 | if (jarEntryName.endsWith(".class") && !jarEntryName.contains("Test")) { 55 | String className = jarEntryName.replace('/', '.').replace(".class", ""); 56 | classes.add(className); 57 | } 58 | } 59 | jarFile.close(); 60 | } 61 | 62 | // Parse all the classes for UML 63 | extractJpaClasses(classLoader, classes, dependencyModel, options.getIncludePatterns(), options.getExcludePatterns()); 64 | 65 | } catch (Exception e) { 66 | e.printStackTrace(); 67 | } 68 | return dependencyModel.getUml(); 69 | } 70 | 71 | static void extractJpaClasses(final URLClassLoader classLoader, final List classes, final JpaDependencyDiagramModel dependencyModel, final String includePatternString, final String excludePatternString) throws ClassNotFoundException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException { 72 | String[] includePatterns = includePatternString.split(","); 73 | String[] excludePatterns = excludePatternString.split(","); 74 | boolean hasAnyPatterns = !(includePatterns.length == 1 && includePatterns[0].isEmpty()) || !(excludePatterns.length == 1 && excludePatterns[0].isEmpty()); 75 | Map> jpaDependencyCache = new HashMap>(); 76 | for (String className : classes) { 77 | if (UmlGeneratorUtility.isIncluded(className, hasAnyPatterns, includePatterns, excludePatterns)) { 78 | Class loadClass = classLoader.loadClass(className); 79 | // check if its an persistent entity 80 | if (isPersistentEntity(loadClass)) { 81 | System.out.println("Parsing persistent class " + loadClass.getSimpleName()); 82 | // extract class info 83 | JpaClassModel classModel = new JpaClassModel(loadClass.getName()); 84 | 85 | // determine class types 86 | extractJpaClassAnnotations(loadClass, classModel); 87 | 88 | // extract fields 89 | extractColumnsAndEntityDependencies(dependencyModel, loadClass, classModel, jpaDependencyCache, hasAnyPatterns, includePatterns, excludePatterns); 90 | 91 | // extract interfaces 92 | extractInterfaces(loadClass, classModel, hasAnyPatterns, includePatterns, excludePatterns); 93 | 94 | // extract parent class 95 | Class superclass = loadClass.getSuperclass(); 96 | if (superclass != null && !superclass.equals(Object.class) 97 | && UmlGeneratorUtility.isIncluded(superclass.getName(), hasAnyPatterns, includePatterns, excludePatterns)) { 98 | classModel.setParent(superclass.getName()); 99 | } 100 | 101 | // add prepared class model to class diagram 102 | dependencyModel.addClass(classModel); 103 | } 104 | } 105 | } 106 | } 107 | 108 | private static boolean isPersistentEntity(final Class loadClass) { 109 | return loadClass.isAnnotationPresent(Entity.class) 110 | || loadClass.isAnnotationPresent(MappedSuperclass.class); 111 | } 112 | 113 | private static void extractJpaClassAnnotations(final Class loadClass, final JpaClassModel classModel) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException { 114 | classModel.setType(loadClass); 115 | classModel.setJpaEntityType(JpaEntityType.ENTITY); 116 | if (loadClass.isAnnotationPresent(MappedSuperclass.class)) { 117 | classModel.setJpaEntityType(JpaEntityType.MAPPED_SUPER_CLASS); 118 | } 119 | else if (loadClass.isAnnotationPresent(Table.class)) { 120 | classModel.setJpaEntityType(JpaEntityType.TABLE); 121 | // extract the table name 122 | Annotation annotation = loadClass.getAnnotation(Table.class); 123 | classModel.setTableName(String.valueOf(annotation.annotationType() 124 | .getDeclaredMethod("name") 125 | .invoke(annotation, (Object[]) null))); 126 | } 127 | } 128 | 129 | private static void extractInterfaces(final Class loadClass, final JpaClassModel classModel, final boolean hasAnyPatterns, final String[] includePatterns, final String[] excludePatterns) { 130 | for (Class interfaceClass : loadClass.getInterfaces()) { 131 | if (UmlGeneratorUtility.isIncluded(interfaceClass.getName(), hasAnyPatterns, includePatterns, excludePatterns)) { 132 | classModel.addInterface(interfaceClass.getName()); 133 | } 134 | } 135 | } 136 | 137 | private static void extractColumnsAndEntityDependencies(final JpaDependencyDiagramModel dependencyModel, final Class loadClass, final JpaClassModel classModel, final Map> jpaDependencyCache, final boolean hasAnyPatterns, final String[] includePatterns, final String[] excludePatterns) { 138 | for (Field field : loadClass.getDeclaredFields()) { 139 | try { 140 | Class fieldType = field.getType(); 141 | if (UmlGeneratorUtility.isIncluded(fieldType.getName(), hasAnyPatterns, includePatterns, excludePatterns)) { 142 | // check for spring dependencies 143 | if (field.isAnnotationPresent(Column.class)) { 144 | extractColumn(classModel, 145 | field.getAnnotation(Column.class)); 146 | } 147 | else if (field.isAnnotationPresent(OneToMany.class)) { 148 | for (Type type : ((ParameterizedType)field.getGenericType()).getActualTypeArguments()) { 149 | if (type instanceof Class) { 150 | updateDependencyCache(dependencyModel, jpaDependencyCache, classModel, ((Class) type).getName(), JpaDependencyType.ONE_TO_MANY); 151 | } 152 | } 153 | } 154 | else if (field.isAnnotationPresent(ManyToOne.class)) { 155 | updateDependencyCache(dependencyModel, jpaDependencyCache, classModel, fieldType.getName(), JpaDependencyType.MANY_TO_ONE); 156 | } 157 | else if (field.isAnnotationPresent(OneToOne.class)) { 158 | updateDependencyCache(dependencyModel, jpaDependencyCache, classModel, fieldType.getName(), JpaDependencyType.ONE_TO_ONE); 159 | } 160 | else if (field.isAnnotationPresent(ManyToMany.class)) { 161 | updateDependencyCache(dependencyModel, jpaDependencyCache, classModel, fieldType.getName(), JpaDependencyType.MANY_TO_MANY); 162 | } 163 | else if (field.isAnnotationPresent(Id.class)) { 164 | classModel.addIdColumn(field.getName()); 165 | } 166 | } 167 | } 168 | catch (Exception e) { 169 | // no need to do anything 170 | continue; 171 | } 172 | catch (NoClassDefFoundError error) { 173 | // no need to do anything 174 | continue; 175 | } 176 | } 177 | } 178 | 179 | private static void updateDependencyCache(final JpaDependencyDiagramModel diagramModel, final Map> jpaDependencyCache, final JpaClassModel classModel, final String dependentClassName, JpaDependencyType dependencyType) { 180 | // check if the dependent class already has the mapping 181 | JpaClassModel dependentClass = diagramModel.getClass(dependentClassName); 182 | Map cache = jpaDependencyCache.get(dependentClassName); 183 | if (cache != null && dependentClass != null) { 184 | JpaDependencyType type = cache.get(classModel.getName()); 185 | if (type != null) { 186 | int result = type.compareTo(dependencyType); 187 | // check if higher priority JPA mapping already exists between 188 | // the classes 189 | if (result < 0 || result == 0 190 | && type != JpaDependencyType.ONE_TO_MANY) { 191 | return; 192 | } 193 | if (result == 0 && type == JpaDependencyType.ONE_TO_MANY) { 194 | // the one-to-many relationship is present both the sides so 195 | // convert it to many-to-many 196 | dependencyType = JpaDependencyType.MANY_TO_MANY; 197 | } 198 | // remove entry from the cache and JpaClassModel of the 199 | // associated class 200 | cache.remove(classModel.getName()); 201 | dependentClass.removeJpaDependency(classModel.getName()); 202 | } 203 | } 204 | 205 | // no mapping or lower priority mapping exists between the entities so create new entry in cache 206 | cache = jpaDependencyCache.get(classModel.getName()); 207 | if (cache == null) { 208 | cache = new HashMap(3); 209 | } 210 | cache.put(dependentClass.getName(), dependencyType); 211 | classModel.addJpaDependency(dependentClassName, dependencyType); 212 | } 213 | 214 | protected static void extractColumn(final JpaClassModel classModel, final Annotation annotation) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { 215 | // get column name from annotation attribute 216 | Method method = annotation.annotationType().getDeclaredMethod("name"); 217 | Object value = method.invoke(annotation, (Object[])null); 218 | classModel.addColumn(String.valueOf(value)); 219 | } 220 | 221 | } 222 | -------------------------------------------------------------------------------- /UmlGeneratorTool/src/main/java/umlGenerator/MultipleProjectAction.java: -------------------------------------------------------------------------------- 1 | package umlGenerator; 2 | 3 | import java.io.File; 4 | import java.io.FileInputStream; 5 | import java.io.FileOutputStream; 6 | import java.io.IOException; 7 | import java.net.MalformedURLException; 8 | import java.net.URL; 9 | import java.nio.channels.FileChannel; 10 | import java.util.ArrayList; 11 | import java.util.LinkedList; 12 | import java.util.List; 13 | import java.util.logging.Level; 14 | import java.util.logging.Logger; 15 | 16 | import org.eclipse.core.resources.IFile; 17 | import org.eclipse.core.resources.IProject; 18 | import org.eclipse.core.resources.IResource; 19 | import org.eclipse.core.runtime.CoreException; 20 | import org.eclipse.core.runtime.IPath; 21 | import org.eclipse.jdt.core.IClasspathContainer; 22 | import org.eclipse.jdt.core.IClasspathEntry; 23 | import org.eclipse.jdt.core.IJavaProject; 24 | import org.eclipse.jdt.core.JavaCore; 25 | import org.eclipse.jdt.core.JavaModelException; 26 | import org.eclipse.jdt.ui.jarpackager.IJarExportRunnable; 27 | import org.eclipse.jdt.ui.jarpackager.JarPackageData; 28 | import org.eclipse.jface.action.IAction; 29 | import org.eclipse.jface.dialogs.MessageDialog; 30 | import org.eclipse.jface.dialogs.ProgressMonitorDialog; 31 | import org.eclipse.jface.viewers.ISelection; 32 | import org.eclipse.jface.viewers.IStructuredSelection; 33 | import org.eclipse.swt.SWT; 34 | import org.eclipse.swt.widgets.Display; 35 | import org.eclipse.swt.widgets.MessageBox; 36 | import org.eclipse.swt.widgets.Shell; 37 | import org.eclipse.ui.IObjectActionDelegate; 38 | import org.eclipse.ui.IWorkbenchPart; 39 | import org.eclipse.ui.PlatformUI; 40 | 41 | /** 42 | * Abstract action that provides support for operating on multiple actions at the 43 | * same time. 44 | *

45 | * Subclasses of this class can get the projects selected by the user by calling 46 | * {@link MultipleProjectAction#getSelectedProjects()} 47 | * 48 | */ 49 | public abstract class MultipleProjectAction implements IObjectActionDelegate { 50 | 51 | private static final Logger LOGGER = Logger.getLogger("MultipleProjectAction"); 52 | 53 | /** 54 | * Projects selected by the user. 55 | */ 56 | private List selectedProjects; 57 | 58 | /** 59 | * Get the list of currently selected projects. 60 | * 61 | * @return the list of currently selected projects. 62 | */ 63 | protected List getSelectedProjects() { 64 | return selectedProjects; 65 | } 66 | 67 | /** 68 | * {@inheritDoc} 69 | */ 70 | public void selectionChanged(IAction action, ISelection selection) { 71 | 72 | boolean enableAction = true; 73 | 74 | selectedProjects = new LinkedList(); 75 | 76 | IStructuredSelection selected = (IStructuredSelection) selection; 77 | 78 | for (Object resource : selected.toArray()) { 79 | try { 80 | if (resource instanceof IProject 81 | && ((IProject)resource).hasNature(JavaCore.NATURE_ID)) { 82 | selectedProjects.add((IProject) resource); 83 | } else { 84 | enableAction = false; 85 | break; 86 | } 87 | } catch (CoreException e) { 88 | e.printStackTrace(); 89 | } 90 | } 91 | action.setEnabled(enableAction); 92 | } 93 | 94 | /** 95 | * {@inheritDoc} 96 | */ 97 | public void run(IAction action) { 98 | Shell shell = new Shell(); 99 | 100 | List failedProjectsMessages = new LinkedList(); 101 | 102 | PlatformUI.getWorkbench().saveAllEditors(true); 103 | 104 | for (IProject project : getSelectedProjects()) { 105 | try { 106 | generateUml(project, shell); 107 | } catch (Exception exception) { 108 | LOGGER.log(Level.SEVERE, "UML not generated for project : " + project.getName()); 109 | exception.printStackTrace(); 110 | } 111 | } 112 | 113 | if (!failedProjectsMessages.isEmpty()) { 114 | StringBuilder message = new StringBuilder(); 115 | 116 | for (String projectMessage : failedProjectsMessages) { 117 | message.append(projectMessage); 118 | message.append("\n"); 119 | } 120 | 121 | String errorTitle = failedProjectsMessages.size() > 1 ? "Unable to generate UML for Projects " 122 | : "Unable to generate UML for Project"; 123 | 124 | MessageDialog 125 | .openInformation(shell, errorTitle, message.toString()); 126 | } 127 | } 128 | 129 | protected IPath exportProjectJar(IProject project, final Shell shell) throws Exception { 130 | IPath deployedJarFile = generateProjectJar(project); 131 | IPath deployedProjectLocation = deployedJarFile.removeLastSegments(1); 132 | 133 | File destinationFile = deployedProjectLocation.toFile(); 134 | // make sure the destination directory exists 135 | if (!destinationFile.exists()) { 136 | destinationFile.mkdirs(); 137 | } 138 | // copy any files in the root of the project directory 139 | IResource[] resources = project.members(); 140 | for (IResource resource : resources) { 141 | if (resource.getType() == IResource.FILE 142 | && !resource.getName().startsWith(".")) { 143 | IPath deployedResouceFile = deployedProjectLocation 144 | .append(resource.getName()); 145 | copyFile(resource.getLocation().toFile(), 146 | deployedResouceFile.toFile()); 147 | } 148 | } 149 | 150 | IFile file = project.getFile(".project"); 151 | JarPackageData jarConfig = createJar(deployedJarFile, new IFile[] {file}); 152 | jarConfig.setOverwrite(true); 153 | final IJarExportRunnable runnable = jarConfig.createJarExportRunnable(shell); 154 | 155 | // create sync execution to make sure that the UI updates are performed in main UI thread. 156 | Display.getDefault().syncExec(new Runnable() { 157 | public void run() { 158 | try { 159 | new ProgressMonitorDialog(shell).run(false, true, runnable); 160 | } catch (Exception e) { 161 | e.printStackTrace(); 162 | } 163 | } 164 | 165 | }); 166 | return deployedJarFile; 167 | } 168 | 169 | /** 170 | * Get the deployed location of a project 171 | * 172 | * @param project 173 | * The project 174 | * @return The location of the project on the disk 175 | */ 176 | private IPath generateProjectJar(IProject project) { 177 | String jarFileLocation = File.separator + project.getName(); 178 | IPath deployedJarFile = project.getParent().getLocation().append(File.separator + "uml" + File.separator + project.getName() + File.separator).append(jarFileLocation); 179 | return deployedJarFile.addFileExtension("jar"); 180 | } 181 | 182 | /** 183 | * Creates a new .jar file at location path containing all of the output 184 | * folders of the project which contains 185 | * 186 | * @param path 187 | * Output location of the file 188 | * @param filestoExport 189 | * File within the project to export. 190 | * @return The packaged jar file configuration. 191 | */ 192 | private JarPackageData createJar(IPath path, IFile[] filestoExport) { 193 | JarPackageData description = new JarPackageData(); 194 | description.setJarLocation(path); 195 | description.setSaveManifest(false); 196 | description.setElements(filestoExport); 197 | description.setCompress(true); 198 | description.setExportClassFiles(true); 199 | description.setExportJavaFiles(false); 200 | description.setExportWarnings(true); 201 | description.setExportOutputFolders(true); 202 | return description; 203 | } 204 | 205 | /** 206 | * Copies a file from one location to another 207 | * 208 | * @param srcFile 209 | * The absolute location of the source file. 210 | * @param dstFile 211 | * The absolute location of the destination file. 212 | * @throws DeployFailedException 213 | * If any error occurs. 214 | */ 215 | @SuppressWarnings("resource") 216 | protected void copyFile(File srcFile, File dstFile) throws IOException { 217 | // Create channel for the source 218 | FileChannel srcChannel = new FileInputStream(srcFile).getChannel(); 219 | 220 | // Create channel for the destination 221 | FileChannel dstChannel = new FileOutputStream(dstFile).getChannel(); 222 | 223 | // Copy file contents from source to destination 224 | dstChannel.transferFrom(srcChannel, 0, srcChannel.size()); 225 | 226 | // Close the channels 227 | srcChannel.close(); 228 | dstChannel.close(); 229 | } 230 | 231 | @SuppressWarnings("deprecation") 232 | protected List getDepedentJars(IProject project, IJavaProject javaProject, IClasspathEntry[] classpathEntries, IPath deployedJarFile) throws MalformedURLException, JavaModelException { 233 | List urls = new ArrayList(); 234 | urls.add(deployedJarFile.toFile().toURL()); 235 | for (IClasspathEntry classpathEntry : classpathEntries) { 236 | urls.addAll(extractClassPathEntry(project, javaProject, classpathEntry, true)); 237 | } 238 | return urls; 239 | } 240 | 241 | @SuppressWarnings("deprecation") 242 | private List extractClassPathEntry(IProject project, IJavaProject javaProject, IClasspathEntry classpathEntry, boolean relativeProjectPath) throws MalformedURLException, JavaModelException { 243 | List urls = new ArrayList(); 244 | if (classpathEntry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) { 245 | URL url = null; 246 | if (relativeProjectPath) { 247 | url = project.getLocation().append(classpathEntry.getPath().removeFirstSegments(1).makeRelative()).toFile().toURL(); 248 | } 249 | else { 250 | url = classpathEntry.getPath().toFile().toURL(); 251 | } 252 | System.err.println("Jar entry added : " + url.toString()); 253 | urls.add(url); 254 | } 255 | else if (classpathEntry.getEntryKind() == IClasspathEntry.CPE_CONTAINER) { 256 | // its some sort of container like JRE or MAVEN so please extract all the entries from container 257 | IClasspathContainer container = JavaCore.getClasspathContainer(classpathEntry.getPath(), javaProject); 258 | for (IClasspathEntry entry : container.getClasspathEntries()) { 259 | urls.addAll(extractClassPathEntry(project, javaProject, entry, false)); 260 | } 261 | } 262 | //TODO: To check how to add project dependencies into ClassLoader. 263 | // else if (classpathEntry.getEntryKind() == IClasspathEntry.CPE_PROJECT) { 264 | // urls.add(project.getLocation().append(classpathEntry.getPath().removeFirstSegments(1).makeRelative()).toFile().toURL()); 265 | // } 266 | return urls; 267 | } 268 | 269 | protected void showResultDialog(final Shell shell, final String projectName, final boolean success, final String reason) { 270 | // create sync execution to make sure that the UI updates are performed in main UI thread. 271 | Display.getDefault().syncExec(new Runnable() { 272 | public void run() { 273 | MessageBox messageDialog = new MessageBox(shell, SWT.OK); 274 | messageDialog.setText("UML diagram generation"); 275 | messageDialog.setMessage(success ? "UML digram is generated successfully under " + projectName + "/uml directory." : "Opps some issue generating UML diagram. Contact Suken Shah. \n\n " + reason); 276 | messageDialog.open(); 277 | } 278 | }); 279 | } 280 | 281 | protected abstract void generateUml(IProject javaProject, Shell shell) throws Exception; 282 | 283 | /** 284 | * {@inheritDoc} 285 | */ 286 | public void setActivePart(IAction action, IWorkbenchPart targetPart) { 287 | } 288 | } 289 | -------------------------------------------------------------------------------- /UmlGenerator/src/main/java/com/uml/generator/spring/SpringDependencyDiagramGenerator.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.uml.generator.spring; 5 | 6 | import java.lang.annotation.Annotation; 7 | import java.lang.reflect.Constructor; 8 | import java.lang.reflect.Field; 9 | import java.lang.reflect.Method; 10 | import java.net.URL; 11 | import java.net.URLClassLoader; 12 | import java.util.ArrayList; 13 | import java.util.Arrays; 14 | import java.util.Enumeration; 15 | import java.util.List; 16 | import java.util.jar.JarEntry; 17 | import java.util.jar.JarFile; 18 | 19 | import org.springframework.beans.factory.annotation.Autowired; 20 | import org.springframework.beans.factory.annotation.Configurable; 21 | import org.springframework.beans.factory.annotation.Required; 22 | import org.springframework.stereotype.Component; 23 | import org.springframework.stereotype.Controller; 24 | import org.springframework.stereotype.Repository; 25 | import org.springframework.stereotype.Service; 26 | 27 | import com.uml.generator.UmlGeneratorUtility; 28 | import com.uml.generator.UmlOptions; 29 | import com.uml.generator.classDiagram.models.ClassType; 30 | import com.uml.generator.classDiagram.models.FieldModel; 31 | import com.uml.generator.classDiagram.models.MethodModel; 32 | import com.uml.generator.spring.models.DependencyType; 33 | import com.uml.generator.spring.models.SpringClassModel; 34 | import com.uml.generator.spring.models.SpringClassType; 35 | import com.uml.generator.spring.models.SpringDependencyDiagramModel; 36 | 37 | /** 38 | * @author sukenshah 39 | */ 40 | public class SpringDependencyDiagramGenerator { 41 | 42 | private static final String ANNOTATION_STR = "@"; 43 | 44 | public static String generateSpringDependencies(final URLClassLoader classLoader, final URL jarUrl, final UmlOptions options) { 45 | SpringDependencyDiagramModel dependencyModel = new SpringDependencyDiagramModel(); 46 | try { 47 | List classes = new ArrayList(); 48 | final JarFile jarFile = new JarFile(jarUrl.getFile()); 49 | if (jarFile != null) { 50 | Enumeration entries = jarFile.entries(); 51 | while (entries.hasMoreElements()) { 52 | JarEntry jarEntry = entries.nextElement(); 53 | String jarEntryName = jarEntry.getName(); 54 | if (jarEntryName.endsWith(".class") 55 | && (options.isTestIncluded() || !jarEntryName.contains("Test"))) { 56 | String className = jarEntryName.replace('/', '.').replace(".class", ""); 57 | classes.add(className); 58 | } 59 | } 60 | jarFile.close(); 61 | } 62 | 63 | // Parse all the classes for UML 64 | extractClassInformation(classLoader, classes, dependencyModel, options.isPackagesIncluded(), options.isFieldsIncluded(), options.isMethodsIncluded(), options.getIncludePatterns(), options.getExcludePatterns()); 65 | 66 | } catch (Exception e) { 67 | e.printStackTrace(); 68 | } 69 | return dependencyModel.getUml(); 70 | } 71 | 72 | static void extractClassInformation(final URLClassLoader classLoader, final List classes, final SpringDependencyDiagramModel dependencyModel, final boolean packagesIncluded, final boolean fieldsVisible, final boolean methodsVisible, final String includePatternString, final String excludePatternString) throws ClassNotFoundException { 73 | String[] includePatterns = includePatternString.split(","); 74 | String[] excludePatterns = excludePatternString.split(","); 75 | boolean hasAnyPatterns = !(includePatterns.length == 1 && includePatterns[0].isEmpty()) || !(excludePatterns.length == 1 && excludePatterns[0].isEmpty()); 76 | for (String className : classes) { 77 | if (UmlGeneratorUtility.isIncluded(className, hasAnyPatterns, includePatterns, excludePatterns)) { 78 | Class loadClass = classLoader.loadClass(className); 79 | if (!loadClass.getSimpleName().isEmpty()) { 80 | System.out.println("Parsing class " + loadClass.getSimpleName()); 81 | // extract class info 82 | SpringClassModel classModel = new SpringClassModel(packagesIncluded ? loadClass.getName() : loadClass.getSimpleName()); 83 | 84 | // determine class types 85 | extractSpringClassAnnotations(loadClass, classModel); 86 | 87 | // do not extract fields and methods for enums. 88 | if (classModel.getType() != ClassType.ENUM) { 89 | // extract fields 90 | extractFields(classes, packagesIncluded, fieldsVisible, loadClass, classModel, hasAnyPatterns, includePatterns, excludePatterns); 91 | 92 | // extract methods 93 | extractMethods(packagesIncluded, methodsVisible, loadClass, classModel, hasAnyPatterns, includePatterns, excludePatterns); 94 | 95 | // extract constructors for spring depedencies 96 | extractConstructorDependencies(packagesIncluded, loadClass, classModel, hasAnyPatterns, includePatterns, excludePatterns); 97 | } 98 | 99 | // extract interfaces 100 | extractInterfaces(loadClass, classModel, packagesIncluded, hasAnyPatterns, includePatterns, excludePatterns); 101 | 102 | // extract parent class 103 | Class superclass = loadClass.getSuperclass(); 104 | if (superclass != null && !superclass.equals(Object.class) 105 | && UmlGeneratorUtility.isIncluded(superclass.getName(), hasAnyPatterns, includePatterns, excludePatterns)) { 106 | classModel.setParent(packagesIncluded ? superclass.getName() : superclass.getSimpleName()); 107 | } 108 | 109 | extractClassDependencies(loadClass, classModel, packagesIncluded, hasAnyPatterns, includePatterns, excludePatterns); 110 | 111 | // add prepared class model to class diagram 112 | dependencyModel.addClass(classModel); 113 | } 114 | } 115 | } 116 | } 117 | 118 | @SuppressWarnings("finally") 119 | private static void extractSpringClassAnnotations(final Class loadClass, 120 | final SpringClassModel classModel) { 121 | classModel.setType(loadClass); 122 | for (Annotation annotation : loadClass.getAnnotations()) { 123 | Class annotationType = annotation.annotationType(); 124 | if (annotationType.isAssignableFrom(Controller.class)) { 125 | classModel.setSpringClassType(SpringClassType.CONTROLLER); 126 | } 127 | else if (annotationType.isAssignableFrom(Component.class)) { 128 | classModel.setSpringClassType(SpringClassType.COMPONENT); 129 | } 130 | else if (annotationType.isAssignableFrom(Service.class)) { 131 | classModel.setSpringClassType(SpringClassType.SERVICE); 132 | } 133 | else if (annotationType.isAssignableFrom(Repository.class)) { 134 | classModel.setSpringClassType(SpringClassType.REPOSITORY); 135 | } 136 | else if (annotationType.isAssignableFrom(Configurable.class)) { 137 | classModel.setSpringClassType(SpringClassType.CONFIGURATION); 138 | } 139 | else { 140 | // adding other annotations as note 141 | StringBuffer note = new StringBuffer(); 142 | note.append(ANNOTATION_STR + annotationType.getSimpleName()).append(" ( \\n"); 143 | boolean hasAnyAttributes = false; 144 | for (Method method : annotationType.getDeclaredMethods()) { 145 | try { 146 | Object defaultValue = method.getDefaultValue(); 147 | Object value = method.invoke(annotation, (Object[])null); 148 | if (value != null && !value.equals(defaultValue)) { 149 | String stringValue = String.valueOf(value); 150 | if (method.getReturnType().isArray() && ((Object[]) value).length > 0) { 151 | stringValue = Arrays.toString((Object[])value); 152 | stringValue = stringValue.substring(1, stringValue.length() - 1); 153 | } 154 | if (!stringValue.startsWith("[L")) { 155 | note.append(" ").append(method.getName()).append(" = ").append(stringValue).append("\\n"); 156 | hasAnyAttributes = true; 157 | } 158 | } 159 | } catch (Exception e) { 160 | // no need to do anything 161 | } 162 | finally { 163 | continue; 164 | } 165 | } 166 | 167 | if (hasAnyAttributes) { 168 | note.append(") \\n"); 169 | } 170 | else { 171 | int startIndex = note.indexOf(" ( \\n"); 172 | note.delete(startIndex, startIndex + 5); 173 | } 174 | classModel.addNote(note.toString()); 175 | } 176 | } 177 | } 178 | 179 | private static void extractClassDependencies(final Class loadClass, 180 | final SpringClassModel classModel, final boolean packagesIncluded, 181 | final boolean hasAnyPatterns, final String[] includePatterns, final String[] excludePatterns) { 182 | // extract dependencies 183 | for (Class dependentClass : loadClass.getDeclaredClasses()) { 184 | if (UmlGeneratorUtility.isIncluded(dependentClass.getName(), hasAnyPatterns, includePatterns, excludePatterns)) { 185 | classModel.addDependency(packagesIncluded ? dependentClass.getName() : dependentClass.getSimpleName()); 186 | } 187 | } 188 | } 189 | 190 | private static void extractInterfaces(final Class loadClass, 191 | final SpringClassModel classModel, final boolean packagesIncluded, 192 | final boolean hasAnyPatterns, final String[] includePatterns, final String[] excludePatterns) { 193 | for (Class interfaceClass : loadClass.getInterfaces()) { 194 | if (UmlGeneratorUtility.isIncluded(interfaceClass.getName(), hasAnyPatterns, includePatterns, excludePatterns)) { 195 | classModel.addInterface(packagesIncluded ? interfaceClass.getName() : interfaceClass.getSimpleName()); 196 | } 197 | } 198 | } 199 | 200 | private static void extractMethods(final boolean packagesIncluded, final boolean methodsVisible, 201 | final Class loadClass, final SpringClassModel classModel, 202 | final boolean hasAnyPatterns, final String[] includePatterns, final String[] excludePatterns) { 203 | for (Method method : loadClass.getDeclaredMethods()) { 204 | boolean hasSpringDependency = false; 205 | if (method.isAnnotationPresent(Autowired.class) 206 | && UmlGeneratorUtility.isIncluded(method.getParameterTypes()[0].getName(), hasAnyPatterns, includePatterns, excludePatterns)) { 207 | classModel.addDepedency(packagesIncluded ? method.getParameterTypes()[0].getName() : method.getParameterTypes()[0].getSimpleName(), DependencyType.AUTOWIRED); 208 | hasSpringDependency = true; 209 | } 210 | else if (method.isAnnotationPresent(Required.class) 211 | && UmlGeneratorUtility.isIncluded(method.getParameterTypes()[0].getName(), hasAnyPatterns, includePatterns, excludePatterns)) { 212 | classModel.addDepedency(packagesIncluded ? method.getParameterTypes()[0].getName() : method.getParameterTypes()[0].getSimpleName(), DependencyType.REQUIRED); 213 | hasSpringDependency = true; 214 | } 215 | // else if (method.isAnnotationPresent(ANNOTATION_BEAN) 216 | // && UmlGeneratorUtility.isIncluded(method.getParameterTypes()[0].getName(), hasAnyPatterns, includePatterns, excludePatterns)) { 217 | // classModel.addDepedency(packagesIncluded ? method.getParameterTypes()[0].getName() : method.getReturnType().getSimpleName(), DependencyType.BEAN); 218 | // hasSpringDependency = true; 219 | // } 220 | if (methodsVisible && !hasSpringDependency && !method.isSynthetic() 221 | && !method.isBridge()) { 222 | classModel.addMethod(new MethodModel(method.getName(), method 223 | .getModifiers())); 224 | } 225 | } 226 | } 227 | 228 | private static void extractConstructorDependencies(final boolean packagesIncluded, final Class loadClass, final SpringClassModel classModel, final boolean hasAnyPatterns, final String[] includePatterns, final String[] excludePatterns) { 229 | for (Constructor constructor : loadClass.getDeclaredConstructors()) { 230 | if (constructor.isAnnotationPresent(Autowired.class)) { 231 | extractConstructorParameterDependecies(packagesIncluded, classModel, 232 | hasAnyPatterns, includePatterns, excludePatterns, constructor, DependencyType.AUTOWIRED); 233 | } 234 | else if (constructor.isAnnotationPresent(Required.class)) { 235 | extractConstructorParameterDependecies(packagesIncluded, classModel, 236 | hasAnyPatterns, includePatterns, excludePatterns, constructor, DependencyType.REQUIRED); 237 | } 238 | // else if (constructor.isAnnotationPresent(ANNOTATION_BEAN)) { 239 | // extractConstructorParameterDependecies(packagesIncluded, classModel, 240 | // hasAnyPatterns, includePatterns, excludePatterns, constructor, DependencyType.BEAN); 241 | // } 242 | } 243 | } 244 | 245 | protected static void extractConstructorParameterDependecies(final boolean packagesIncluded, final SpringClassModel classModel, final boolean hasAnyPatterns, 246 | final String[] includePatterns, final String[] excludePatterns, final Constructor constructor, final DependencyType type) { 247 | for (Class argumentType : constructor.getParameterTypes()) { 248 | if (UmlGeneratorUtility.isIncluded(argumentType.getName(), hasAnyPatterns, includePatterns, excludePatterns)) { 249 | classModel.addDepedency(packagesIncluded ? argumentType.getName() : argumentType.getSimpleName(), type); 250 | } 251 | } 252 | } 253 | 254 | private static void extractFields(final List classes, final boolean packagesIncluded, 255 | final boolean fieldsVisible, final Class loadClass, final SpringClassModel classModel, 256 | final boolean hasAnyPatterns, final String[] includePatterns, final String[] excludePatterns) { 257 | for (Field field : loadClass.getDeclaredFields()) { 258 | try { 259 | Class fieldType = field.getType(); 260 | if (UmlGeneratorUtility.isIncluded(fieldType.getName(), hasAnyPatterns, includePatterns, excludePatterns)) { 261 | boolean isSpringDepedency = false; 262 | // check for spring dependencies 263 | if (field.isAnnotationPresent(Autowired.class)) { 264 | classModel.addDepedency(packagesIncluded ? fieldType.getName() : fieldType.getSimpleName(), DependencyType.AUTOWIRED); 265 | isSpringDepedency = true; 266 | } 267 | else if (field.isAnnotationPresent(Required.class)) { 268 | classModel.addDepedency(packagesIncluded ? fieldType.getName() : fieldType.getSimpleName(), DependencyType.REQUIRED); 269 | isSpringDepedency = true; 270 | } 271 | if (!isSpringDepedency) { 272 | String type = fieldType.getName().replace("[", "").replace("]", ""); 273 | if (classes.contains(type)) { 274 | classModel.addDependency(packagesIncluded ? fieldType.getName() : fieldType.getSimpleName()); 275 | } 276 | else if (fieldsVisible && !field.isSynthetic()) { 277 | // only add field if visibility is set 278 | classModel.addField(new FieldModel(field.getName(), fieldType.getSimpleName(), field.getModifiers())); 279 | } 280 | } 281 | } 282 | } 283 | catch (Exception e) { 284 | // no need to do anything 285 | continue; 286 | } 287 | catch (NoClassDefFoundError error) { 288 | // no need to do anything 289 | continue; 290 | } 291 | } 292 | } 293 | } 294 | --------------------------------------------------------------------------------