X-Git-Url: http://www2.svjatoslav.eu/gitweb/?a=blobdiff_plain;f=src%2Fmain%2Fjava%2Feu%2Fsvjatoslav%2Finspector%2Fjava%2Fstructure%2FClassGraph.java;h=c31124c17b75fe274d825c3fde63f0e3a09d8c72;hb=7d1259aea992843c47f29c932434a88ea9364f7e;hp=c8de18b239730ca649de8fb6d621ead643fdce98;hpb=0a0fbcb01497d4a860cbbcb60ecefdcee4f89067;p=javainspect.git diff --git a/src/main/java/eu/svjatoslav/inspector/java/structure/ClassGraph.java b/src/main/java/eu/svjatoslav/inspector/java/structure/ClassGraph.java index c8de18b..c31124c 100755 --- a/src/main/java/eu/svjatoslav/inspector/java/structure/ClassGraph.java +++ b/src/main/java/eu/svjatoslav/inspector/java/structure/ClassGraph.java @@ -1,6 +1,6 @@ /* * JavaInspect - Utility to visualize java software - * Copyright (C) 2013-2015, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu + * Copyright (C) 2013-2020, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu * * This program is free software; you can redistribute it and/or * modify it under the terms of version 3 of the GNU Lesser General Public License @@ -9,6 +9,11 @@ package eu.svjatoslav.inspector.java.structure; +import eu.svjatoslav.commons.file.CommonPathResolver; +import eu.svjatoslav.commons.string.WildCardMatcher; +import eu.svjatoslav.inspector.java.methods.Clazz; +import eu.svjatoslav.inspector.java.methods.ProjectScanner; + import java.io.File; import java.io.IOException; import java.io.PrintWriter; @@ -17,204 +22,192 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import eu.svjatoslav.commons.file.CommonPathResolver; -import eu.svjatoslav.commons.string.WildCardMatcher; -import eu.svjatoslav.inspector.java.methods.Clazz; -import eu.svjatoslav.inspector.java.methods.ProjectScanner; +import static eu.svjatoslav.inspector.java.methods.JavaFile.UTF_8; public class ClassGraph { - /** - * Maps class fully qualified names to class descriptors. - */ - private final Map fullyQualifiedNameToClassMap = new HashMap(); - - private final List blacklistClassPatterns = new ArrayList(); - - private final List whitelistClassPatterns = new ArrayList(); - - private String targetDirectory = CommonPathResolver.getDesktopDirectory() - .getAbsolutePath() + "/"; - - private boolean keepDotFile; - - public ClassGraph() { - } - - /** - * @param objects - * objects that shall be added to graph - * - * @return this {@link ClassGraph} - */ - public ClassGraph add(final Object... objects) { - - if (objects != null) - for (final Object object : objects) - addObject(object); - - return this; - } - - private void addObject(final Object object) { - if (object instanceof Class) - getOrCreateClassDescriptor((Class) object); - else - getOrCreateClassDescriptor(object.getClass()); - } - - /** - * @param path - * path to recursively scan for java source code could be - * relative to current project or absolute - */ - public void addProject(final String path) { - final ProjectScanner projectScanner = new ProjectScanner(new File(path)); - for (final Clazz clazz : projectScanner.getAllClasses()) - try { - System.out.println("Class full name: " + clazz.getFullName()); - final Class c = this.getClass().forName(clazz.getFullName()); - addObject(c); - } catch (final Exception exception) { - System.out.println("cannot add class: " - + exception.getMessage()); - } - } - - public void blacklistClassPattern(final String pattern) { - blacklistClassPatterns.add(pattern); - } - - /** - * @param resultFileName - * file name for the generated graph. File extension will be - * added automatically. Existing file with the same name will be - * overwritten. - * - */ - - public void generateGraph(final String resultFileName) { - - final String dotFilePath = targetDirectory + resultFileName + ".dot"; - final String imageFilePath = targetDirectory + resultFileName + ".png"; - - System.out.println("Dot file path:" + dotFilePath); - - try { - // write DOT file to disk - final PrintWriter out = new PrintWriter(dotFilePath); - out.write(getDot()); - out.close(); - - // execute GraphViz to visualize graph - try { - Runtime.getRuntime() - .exec(new String[] { "dot", "-Tpng", dotFilePath, "-o", - imageFilePath }).waitFor(); - } catch (final InterruptedException e) { - } finally { - } - - if (!keepDotFile) - // delete dot file - new File(dotFilePath).delete(); - } catch (final IOException e) { - System.err.println(e); - } - - } - - private String getDot() { - final StringBuffer result = new StringBuffer(); - - result.append("digraph Java {\n"); - result.append("graph [rankdir=LR, overlap = false, concentrate=true];\n"); - - for (final Map.Entry entry : fullyQualifiedNameToClassMap - .entrySet()) - result.append(entry.getValue().getDot()); - - result.append("}\n"); - - final String resultStr = result.toString(); - return resultStr; - } - - /** - * @param clazz - * class that shall be added to graph - * - * @return {@link ClassDescriptor} corresponding to given {@link Class} - */ - protected ClassDescriptor getOrCreateClassDescriptor(final Class clazz) { - - if (clazz == null) - return null; - - final String classFullyQualifiedName = clazz.getName(); - - // reuse existing instance if possible - if (fullyQualifiedNameToClassMap.containsKey(classFullyQualifiedName)) - return fullyQualifiedNameToClassMap.get(classFullyQualifiedName); - - // create new class descriptor - final ClassDescriptor newClassDescriptor = new ClassDescriptor(this); - fullyQualifiedNameToClassMap.put(classFullyQualifiedName, - newClassDescriptor); - - newClassDescriptor.analyzeClass(clazz); - - return newClassDescriptor; - } - - /** - * Hide orphaned class that have no references - * - * @return this {@link ClassGraph} - */ - public ClassGraph hideOrphanedClasses() { - - for (final ClassDescriptor classDescriptor : fullyQualifiedNameToClassMap - .values()) - classDescriptor.hideClassIfNoReferences(); - - return this; - } - - protected boolean isClassShown(final String className) { - for (final String pattern : blacklistClassPatterns) - if (WildCardMatcher.match(className, pattern)) - return false; - - if (!whitelistClassPatterns.isEmpty()) { - for (final String pattern : whitelistClassPatterns) - if (WildCardMatcher.match(className, pattern)) - return true; - return false; - } - - return true; - } - - public ClassGraph setKeepDotFile(final boolean keepDotFile) { - this.keepDotFile = keepDotFile; - - return this; - } - - public ClassGraph setTargetDirectory(String directoryPath) { - if (!directoryPath.endsWith("/")) - directoryPath += "/"; - - targetDirectory = directoryPath; - - return this; - } - - public ClassGraph whitelistClassPattern(final String pattern) { - whitelistClassPatterns.add(pattern); + /** + * Maps class fully qualified names to class descriptors. + */ + private final Map fullyQualifiedNameToClassMap = new HashMap<>(); + + private final List blacklistClassGlobs = new ArrayList<>(); + + private final List whitelistClassGlobs = new ArrayList<>(); + TargetImageType targetImageType = TargetImageType.SVG; + private File targetDirectory = CommonPathResolver.getDesktopDirectory(); + private boolean keepDotFile; + + public ClassGraph() { + } + + /** + * @param objects objects that shall be added to graph + * @return this {@link ClassGraph} + */ + public ClassGraph add(final Object... objects) { + + if (objects != null) + for (final Object object : objects) + addObject(object); + + return this; + } + + private void addObject(final Object object) { + if (object instanceof Class) + getOrCreateClassDescriptor((Class) object); + else + getOrCreateClassDescriptor(object.getClass()); + } + + /** + * @param path path to recursively scan for java source code could be + * relative to current project or absolute + */ + public void addProject(final String path) { + final ProjectScanner projectScanner = new ProjectScanner(new File(path)); + for (final Clazz clazz : projectScanner.getAllClasses()) + try { + System.out.println("Class full name: " + clazz.getFullName()); + final Class c = Class.forName(clazz.getFullName()); + addObject(c); + } catch (final Exception exception) { + System.out.println("cannot add class: " + + exception.getMessage()); + } + } + + public void blacklistClassGlob(final String glob) { + blacklistClassGlobs.add(glob); + } + + public void setTargetImageType(TargetImageType targetImageType) { + this.targetImageType = targetImageType; + } + + /** + * @param resultFileName file name for the generated graph. File extension will be + * added automatically. Existing file with the same name will be + * overwritten. + */ + + public void generateGraph(final String resultFileName) { + + final File dotFile = new File(targetDirectory, resultFileName + ".dot"); + final File imageFile = new File(targetDirectory, resultFileName + "." + targetImageType.fileExtension); + + try { + // write DOT file to disk + final PrintWriter out = new PrintWriter(dotFile, UTF_8); + out.write(getDot()); + out.close(); + + // execute GraphViz to visualize graph + try { + Runtime.getRuntime() + .exec(new String[]{"dot", + "-T" + targetImageType.fileExtension, + dotFile.getAbsolutePath(), + "-o", + imageFile.getAbsolutePath()}).waitFor(); + } catch (final InterruptedException ignored) { + } + + if (!keepDotFile) + // delete dot file + if (!dotFile.delete()) + throw new RuntimeException("Cannot delete file: " + dotFile.getAbsolutePath()); + + } catch (final IOException e) { + throw new RuntimeException("Unable to generate graph: " + e.getMessage(), e); + } + + } + + private String getDot() { + final StringBuilder result = new StringBuilder(); + + result.append("digraph Java {\n"); + result.append("graph [rankdir=LR, overlap = false, concentrate=true];\n"); + + for (final Map.Entry entry : fullyQualifiedNameToClassMap + .entrySet()) + result.append(entry.getValue().getDot()); + + result.append("}\n"); + + return result.toString(); + } + + /** + * @param clazz class that shall be added to graph + * @return {@link ClassDescriptor} corresponding to given {@link Class} + */ + protected ClassDescriptor getOrCreateClassDescriptor(final Class clazz) { + + if (clazz == null) + return null; + + final String classFullyQualifiedName = clazz.getName(); + + // reuse existing instance if possible + if (fullyQualifiedNameToClassMap.containsKey(classFullyQualifiedName)) + return fullyQualifiedNameToClassMap.get(classFullyQualifiedName); + + // create new class descriptor + final ClassDescriptor newClassDescriptor = new ClassDescriptor(this); + fullyQualifiedNameToClassMap.put(classFullyQualifiedName, + newClassDescriptor); + + newClassDescriptor.analyzeClass(clazz); + + return newClassDescriptor; + } + + /** + * Hide orphaned class that have no references + * + * @return this {@link ClassGraph} + */ + public ClassGraph hideOrphanedClasses() { + + for (final ClassDescriptor classDescriptor : fullyQualifiedNameToClassMap + .values()) + classDescriptor.hideClassIfNoReferences(); + + return this; + } + + protected boolean isClassShown(final String className) { + for (final String pattern : blacklistClassGlobs) + if (WildCardMatcher.match(className, pattern)) + return false; + + if (!whitelistClassGlobs.isEmpty()) { + for (final String pattern : whitelistClassGlobs) + if (WildCardMatcher.match(className, pattern)) + return true; + return false; + } - return this; - } + return true; + } + + public ClassGraph setKeepDotFile(final boolean keepDotFile) { + this.keepDotFile = keepDotFile; + + return this; + } + + public ClassGraph setTargetDirectory(File targetDirectory) { + this.targetDirectory = targetDirectory; + return this; + } + + public ClassGraph whitelistClassGlob(final String glob) { + whitelistClassGlobs.add(glob); + return this; + } }