From: Svjatoslav Agejenko Date: Tue, 3 Mar 2015 16:11:40 +0000 (+0200) Subject: Code refactoring. Simplified API. X-Git-Tag: javainspect-1.5~16 X-Git-Url: http://www2.svjatoslav.eu/gitweb/?p=javainspect.git;a=commitdiff_plain;h=94b2a818903a8ec1579dce828b47076c53f435ab Code refactoring. Simplified API. --- diff --git a/src/main/java/eu/svjatoslav/inspector/java/structure/ClassDescriptor.java b/src/main/java/eu/svjatoslav/inspector/java/structure/ClassDescriptor.java index 5283007..2b775cb 100755 --- a/src/main/java/eu/svjatoslav/inspector/java/structure/ClassDescriptor.java +++ b/src/main/java/eu/svjatoslav/inspector/java/structure/ClassDescriptor.java @@ -25,11 +25,11 @@ public class ClassDescriptor implements GraphElement { private static final int MAX_REFERECNES_COUNT = 10; - public final String classFullyQualifiedName; + public String classFullyQualifiedName; - Map nameToFieldMap = new TreeMap(); + private final Map nameToFieldMap = new TreeMap(); - public SortedSet methods = new TreeSet(); + private final SortedSet methods = new TreeSet(); /** * Incoming arrows will have this color. @@ -67,19 +67,20 @@ public class ClassDescriptor implements GraphElement { private ClassDescriptor arrayComponent; - public ClassDescriptor(final Class clazz, - final ClassGraph classGraph) { + public ClassDescriptor(final ClassGraph classGraph) { this.classGraph = classGraph; + } - classFullyQualifiedName = clazz.getName(); + public void analyzeClass(final Class clazz) { - classGraph.registerClass(classFullyQualifiedName, this); + classFullyQualifiedName = clazz.getName(); isArray = clazz.isArray(); if (isArray) { final Class componentType = clazz.getComponentType(); - arrayComponent = classGraph.addClass(componentType); + arrayComponent = getClassGraph().getOrCreateClassDescriptor( + componentType); } // System.out.println("class: " + fullyQualifiedName); @@ -97,17 +98,18 @@ public class ClassDescriptor implements GraphElement { indexMethods(clazz); for (final Class interfaceClass : clazz.getInterfaces()) { - final ClassDescriptor classDescriptor = classGraph - .addClass(interfaceClass); - classDescriptor.registerImplementation(); - interfaces.add(classDescriptor); + final ClassDescriptor interfaceClassDescriptor = getClassGraph() + .getOrCreateClassDescriptor(interfaceClass); + interfaceClassDescriptor.registerImplementation(); + interfaces.add(interfaceClassDescriptor); } - superClass = classGraph.addClass(clazz.getSuperclass()); + superClass = getClassGraph().getOrCreateClassDescriptor( + clazz.getSuperclass()); if (superClass != null) superClass.registerExtension(); - } + }; public boolean areReferencesShown() { return referencesCount <= MAX_REFERECNES_COUNT; @@ -252,6 +254,10 @@ public class ClassDescriptor implements GraphElement { return "1"; } + public ClassGraph getClassGraph() { + return classGraph; + } + public String getClassName(final boolean differentiateArray) { // this is needed for nested classes final String actualClassName = classFullyQualifiedName @@ -341,7 +347,7 @@ public class ClassDescriptor implements GraphElement { public String getGraphId() { final String result = "class_" + classFullyQualifiedName.replace('.', '_').replace(";", "") - .replace("[L", "").replace('$', '_'); + .replace("[L", "").replace('$', '_'); return result; } @@ -352,6 +358,35 @@ public class ClassDescriptor implements GraphElement { return interfaceColor; } + // public String getReadableName() { + // + // // do not print full class name for well known system classes + // final String packageName = getPackageName(); + // + // if (packageName.equals("java.util")) + // return getClassName(); + // + // if (packageName.equals("java.lang")) + // return getClassName(); + // + // return fullyQualifiedName; + // } + + private FieldDescriptor getOrCreateFieldDescriptor(final Field field) { + + final String fieldName = field.getName(); + + if (nameToFieldMap.containsKey(fieldName)) + return nameToFieldMap.get(fieldName); + + final FieldDescriptor newFieldDescriptor = new FieldDescriptor(this); + nameToFieldMap.put(fieldName, newFieldDescriptor); + + newFieldDescriptor.analyzeField(field); + + return newFieldDescriptor; + } + private int getOutgoingReferencesCount() { int result = 0; @@ -376,20 +411,6 @@ public class ClassDescriptor implements GraphElement { return result; } - // public String getReadableName() { - // - // // do not print full class name for well known system classes - // final String packageName = getPackageName(); - // - // if (packageName.equals("java.util")) - // return getClassName(); - // - // if (packageName.equals("java.lang")) - // return getClassName(); - // - // return fullyQualifiedName; - // } - public String getPackageName() { final int i = classFullyQualifiedName.lastIndexOf('.'); @@ -451,21 +472,19 @@ public class ClassDescriptor implements GraphElement { } public void indexFields(final Field[] fields) { - for (final Field field : fields) { - if (nameToFieldMap.containsKey(field.getName())) - continue; - - final FieldDescriptor fieldDescriptor = new FieldDescriptor(field, - this, classGraph); - - } + for (final Field field : fields) + getOrCreateFieldDescriptor(field); } private void indexMethods(final Class clazz) { - final Method[] methods = clazz.getMethods(); + for (final Method method : clazz.getMethods()) { + final MethodDescriptor methodDescriptor = new MethodDescriptor( + this, method.getName()); - for (final Method method : methods) - new MethodDescriptor(method, this, classGraph); + methods.add(methodDescriptor); + + methodDescriptor.analyze(method); + } } @@ -478,7 +497,7 @@ public class ClassDescriptor implements GraphElement { if (Utils.isSystemPackage(classFullyQualifiedName)) return false; - if (!classGraph.getFilter().isClassShown(classFullyQualifiedName)) + if (!getClassGraph().getFilter().isClassShown(classFullyQualifiedName)) return false; if (isArray) 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 a2ce8a2..27eff03 100755 --- a/src/main/java/eu/svjatoslav/inspector/java/structure/ClassGraph.java +++ b/src/main/java/eu/svjatoslav/inspector/java/structure/ClassGraph.java @@ -21,63 +21,34 @@ import eu.svjatoslav.inspector.java.methods.ProjectScanner; public class ClassGraph { - public static void render(final String graphName, final Class... classes) { - final ClassGraph classGraph = new ClassGraph(classes); - - classGraph.generateGraph(graphName); - } - /** * Maps class fully qualified names to class descriptors. */ private final Map fullyQualifiedNameToClassMap = new HashMap(); - private Filter filter = new Filter(); + private final Filter filter = new Filter(); public ClassGraph() { } - /** - * @param classes - * classes that shall be added to graph - */ - public ClassGraph(final Class... classes) { - for (final Class clazz : classes) - addClass(clazz); - } - /** * @param objects * objects that shall be added to graph */ - public ClassGraph(final Object... objects) { - for (final Object object : objects) - addClass(object.getClass()); - } - - /** - * @param clazz - * class that shall be added to graph - */ - public ClassDescriptor addClass(final Class clazz) { - - if (clazz == null) - return null; - - final String className = clazz.getName(); + public ClassGraph add(final Object... objects) { - if (fullyQualifiedNameToClassMap.containsKey(className)) - return fullyQualifiedNameToClassMap.get(className); + if (objects != null) + for (final Object object : objects) + addObject(object); - return new ClassDescriptor(clazz, this); + return this; } - /** - * @param object - * object that shall be added to graph - */ - public ClassDescriptor addObject(final Object object) { - return addClass(object.getClass()); + private void addObject(final Object object) { + if (object instanceof Class) + getOrCreateClassDescriptor((Class) object); + else + getOrCreateClassDescriptor(object.getClass()); } /** @@ -91,7 +62,7 @@ public class ClassGraph { try { System.out.println("Class full name: " + clazz.getFullName()); final Class c = this.getClass().forName(clazz.getFullName()); - addClass(c); + addObject(c); } catch (final Exception exception) { System.out.println("cannot add class: " + exception.getMessage()); @@ -198,6 +169,31 @@ public class ClassGraph { return filter; } + /** + * @param clazz + * class that shall be added to graph + */ + 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 */ @@ -209,14 +205,4 @@ public class ClassGraph { } - public void registerClass(final String classFullyQualifiedName, - final ClassDescriptor classDescriptor) { - fullyQualifiedNameToClassMap.put(classFullyQualifiedName, - classDescriptor); - } - - public void setFilter(final Filter filter) { - this.filter = filter; - } - } diff --git a/src/main/java/eu/svjatoslav/inspector/java/structure/FieldDescriptor.java b/src/main/java/eu/svjatoslav/inspector/java/structure/FieldDescriptor.java index 902d415..d0a607b 100755 --- a/src/main/java/eu/svjatoslav/inspector/java/structure/FieldDescriptor.java +++ b/src/main/java/eu/svjatoslav/inspector/java/structure/FieldDescriptor.java @@ -1,7 +1,7 @@ /* * JavaInspect - Utility to visualize java software * Copyright (C) 2013-2015, 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 * or later as published by the Free Software Foundation. @@ -23,26 +23,27 @@ public class FieldDescriptor implements GraphElement { public String name; private ClassDescriptor type; - private ClassDescriptor parentClass; + private final ClassDescriptor parentClass; List typeArguments = new ArrayList(); - public FieldDescriptor(final Field field, final ClassDescriptor parent, - final ClassGraph classGraph) { + public boolean isInherited; + public FieldDescriptor(final ClassDescriptor parent) { parentClass = parent; + } + + public void analyzeField(final Field field) { if (!field.getDeclaringClass().getName() - .equals(parent.classFullyQualifiedName)) - // if field is inherited, do not index it - return; + .equals(parentClass.classFullyQualifiedName)) + isInherited = true; // if (field.getType().isArray()) // System.out.println("field name: " + field.getName()); - parent.nameToFieldMap.put(field.getName(), this); - name = field.getName(); - type = classGraph.addClass(field.getType()); + type = parentClass.getClassGraph().getOrCreateClassDescriptor( + field.getType()); type.registerReference(); final Type genericType = field.getGenericType(); @@ -51,8 +52,8 @@ public class FieldDescriptor implements GraphElement { for (final Type t : pt.getActualTypeArguments()) if (t instanceof Class) { final Class cl = (Class) t; - final ClassDescriptor genericTypeDescriptor = classGraph - .addClass(cl); + final ClassDescriptor genericTypeDescriptor = parentClass + .getClassGraph().getOrCreateClassDescriptor(cl); genericTypeDescriptor.registerReference(); typeArguments.add(genericTypeDescriptor); } @@ -144,6 +145,9 @@ public class FieldDescriptor implements GraphElement { @Override public boolean isVisible() { + if (isInherited) + return false; + if (name.contains("$")) return false; diff --git a/src/main/java/eu/svjatoslav/inspector/java/structure/MethodDescriptor.java b/src/main/java/eu/svjatoslav/inspector/java/structure/MethodDescriptor.java index 2e5d61f..8eca361 100755 --- a/src/main/java/eu/svjatoslav/inspector/java/structure/MethodDescriptor.java +++ b/src/main/java/eu/svjatoslav/inspector/java/structure/MethodDescriptor.java @@ -1,7 +1,7 @@ /* * JavaInspect - Utility to visualize java software * Copyright (C) 2013-2015, 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 * or later as published by the Free Software Foundation. @@ -28,21 +28,22 @@ public class MethodDescriptor implements GraphElement, List argumentTypes = new ArrayList(); - public MethodDescriptor(final Method method, final ClassDescriptor parent, - final ClassGraph dump) { + boolean isInherited; + public MethodDescriptor(final ClassDescriptor parent, + final String methodName) { parentClass = parent; + this.methodName = methodName; + } - methodName = method.getName(); + public void analyze(final Method method) { if (!method.getDeclaringClass().getName() - .equals(parent.classFullyQualifiedName)) - // do not index inherited methods - return; - - parent.methods.add(this); + .equals(parentClass.classFullyQualifiedName)) + isInherited = true; - returnType = dump.addClass(method.getReturnType()); + returnType = parentClass.getClassGraph().getOrCreateClassDescriptor( + method.getReturnType()); returnType.registerReference(); final Type genericType = method.getGenericReturnType(); @@ -51,7 +52,8 @@ public class MethodDescriptor implements GraphElement, for (final Type t : pt.getActualTypeArguments()) if (t instanceof Class) { final Class cl = (Class) t; - final ClassDescriptor classDescriptor = dump.addClass(cl); + final ClassDescriptor classDescriptor = parentClass + .getClassGraph().getOrCreateClassDescriptor(cl); classDescriptor.registerReference(); argumentTypes.add(classDescriptor); } @@ -82,8 +84,9 @@ public class MethodDescriptor implements GraphElement, if (classDescriptor.isVisible()) if (classDescriptor.areReferencesShown()) result.append(" " + getGraphId() + " -> " - + classDescriptor.getGraphId() + "[label=\"" + methodName - + "\", color=\"" + classDescriptor.getColor() + + classDescriptor.getGraphId() + "[label=\"" + + methodName + "\", color=\"" + + classDescriptor.getColor() + "\", style=\"dotted, bold\"];\n"); if (!returnType.isVisible()) @@ -92,8 +95,8 @@ public class MethodDescriptor implements GraphElement, // main type if (returnType.areReferencesShown()) result.append(" " + getGraphId() + " -> " - + returnType.getGraphId() + "[label=\"" + methodName + "\"," - + " color=\"" + returnType.getColor() + + returnType.getGraphId() + "[label=\"" + methodName + + "\"," + " color=\"" + returnType.getColor() + "\", style=\"dotted, bold\"];\n"); return result.toString(); @@ -142,6 +145,10 @@ public class MethodDescriptor implements GraphElement, @Override public boolean isVisible() { + // hide inherited methods + if (isInherited) + return false; + // hide common object methods if (Utils.isCommonObjectMethod(methodName)) return false; @@ -157,8 +164,8 @@ public class MethodDescriptor implements GraphElement, // hide is methods for the boolean field of the same name if (methodName.startsWith("is")) { - final FieldDescriptor field = parentClass.getFieldIgnoreCase(methodName - .substring(2)); + final FieldDescriptor field = parentClass + .getFieldIgnoreCase(methodName.substring(2)); if (field != null) if ("boolean".equals(field.getType().classFullyQualifiedName)) return false; diff --git a/src/test/java/eu/svjatoslav/inspector/java/structure/example/RenderDemoClasses.java b/src/test/java/eu/svjatoslav/inspector/java/structure/example/RenderDemoClasses.java index b5a24a8..50f9c7e 100755 --- a/src/test/java/eu/svjatoslav/inspector/java/structure/example/RenderDemoClasses.java +++ b/src/test/java/eu/svjatoslav/inspector/java/structure/example/RenderDemoClasses.java @@ -16,12 +16,9 @@ import eu.svjatoslav.inspector.java.structure.example.structure.SampleClass2; public class RenderDemoClasses { public static void main(final String[] args) { - final ClassGraph graph = new ClassGraph(); - graph.addClass(SampleClass.class); - graph.addClass(SampleClass2.class); - - graph.generateGraph("example", false); + new ClassGraph().add(SampleClass.class, SampleClass2.class) + .generateGraph("example", false); } } diff --git a/src/test/java/eu/svjatoslav/inspector/java/structure/example/RenderJavaInspect.java b/src/test/java/eu/svjatoslav/inspector/java/structure/example/RenderJavaInspect.java index 93dead5..7d9eb80 100755 --- a/src/test/java/eu/svjatoslav/inspector/java/structure/example/RenderJavaInspect.java +++ b/src/test/java/eu/svjatoslav/inspector/java/structure/example/RenderJavaInspect.java @@ -1,7 +1,7 @@ /* * JavaInspect - Utility to visualize java software * Copyright (C) 2013-2015, 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 * or later as published by the Free Software Foundation. @@ -49,10 +49,10 @@ public class RenderJavaInspect { // as in the following example. // Add some object to the graph. - graph.addObject(graph); + graph.add(graph); // Add some class to the graph. - graph.addClass(Utils.class); + graph.add(Utils.class); // Produce bitmap image titled "JavaInspect.png" to the user Desktop // directory and keep intermediary GraphViz DOT file for reference.