properly render fields of arrays of primitive types
authorSvjatoslav Agejenko <svjatoslav@svjatoslav.eu>
Mon, 2 Feb 2015 22:53:16 +0000 (00:53 +0200)
committerSvjatoslav Agejenko <svjatoslav@svjatoslav.eu>
Mon, 2 Feb 2015 22:53:16 +0000 (00:53 +0200)
src/main/java/eu/svjatoslav/inspector/java/structure/ClassDescriptor.java
src/main/java/eu/svjatoslav/inspector/java/structure/ClassGraph.java
src/main/java/eu/svjatoslav/inspector/java/structure/FieldDescriptor.java
src/main/java/eu/svjatoslav/inspector/java/structure/MethodDescriptor.java

index 2247a77..c5c6a78 100755 (executable)
@@ -1,7 +1,7 @@
 /*
  * JavaInspect - Utility to visualize java software
  * Copyright (C) 2013-2014, 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.
@@ -25,7 +25,7 @@ public class ClassDescriptor implements GraphElement {
 
        private static final int MAX_REFERECNES_COUNT = 10;
 
-       public final String fullyQualifiedName;
+       public final String classFullyQualifiedName;
 
        Map<String, FieldDescriptor> nameToFieldMap = new TreeMap<String, FieldDescriptor>();
 
@@ -65,18 +65,21 @@ public class ClassDescriptor implements GraphElement {
        // counts amount of times this class is extended
        private int extensionsCount = 0;
 
+       private ClassDescriptor arrayComponent;
+
        public ClassDescriptor(final Class<? extends Object> clazz,
-                       final ClassGraph dump) {
-               classGraph = dump;
+                       final ClassGraph classGraph) {
+               this.classGraph = classGraph;
+
+               classFullyQualifiedName = clazz.getName();
 
-               fullyQualifiedName = clazz.getName();
-               dump.nameToClassMap.put(fullyQualifiedName, this);
+               classGraph.registerClass(classFullyQualifiedName, this);
 
                isArray = clazz.isArray();
 
                if (isArray) {
                        final Class<?> componentType = clazz.getComponentType();
-                       dump.addClass(componentType);
+                       arrayComponent = classGraph.addClass(componentType);
                }
 
                // System.out.println("class: " + fullyQualifiedName);
@@ -94,13 +97,13 @@ public class ClassDescriptor implements GraphElement {
                indexMethods(clazz);
 
                for (final Class interfaceClass : clazz.getInterfaces()) {
-                       final ClassDescriptor classDescriptor = dump
+                       final ClassDescriptor classDescriptor = classGraph
                                        .addClass(interfaceClass);
                        classDescriptor.registerImplementation();
                        interfaces.add(classDescriptor);
                }
 
-               superClass = dump.addClass(clazz.getSuperclass());
+               superClass = classGraph.addClass(clazz.getSuperclass());
                if (superClass != null)
                        superClass.registerExtension();
 
@@ -140,7 +143,7 @@ public class ClassDescriptor implements GraphElement {
 
                result.append("\n");
                result.append("    // interfaces implemented by class: "
-                               + fullyQualifiedName + "\n");
+                               + classFullyQualifiedName + "\n");
 
                for (final ClassDescriptor interfaceDescriptor : interfaces) {
                        if (!interfaceDescriptor.isVisible())
@@ -183,7 +186,8 @@ public class ClassDescriptor implements GraphElement {
                        return;
 
                result.append("\n");
-               result.append("    // super class for: " + fullyQualifiedName + "\n");
+               result.append("    // super class for: " + classFullyQualifiedName
+                               + "\n");
 
                result.append("    " + superClass.getGraphId() + " -> " + getGraphId()
                                + "[style=\"tapered\", color=\""
@@ -193,7 +197,7 @@ public class ClassDescriptor implements GraphElement {
 
        public void generateDotHeader(final StringBuffer result) {
                result.append("\n");
-               result.append("// Class: " + fullyQualifiedName + "\n");
+               result.append("// Class: " + classFullyQualifiedName + "\n");
 
                result.append("    " + getGraphId() + "[label=<<TABLE "
                                + getBackgroundColor() + " BORDER=\"" + getBorderWidth()
@@ -245,14 +249,21 @@ public class ClassDescriptor implements GraphElement {
 
        public String getClassName(final boolean differentiateArray) {
                // this is needed for nested classes
-               final String actualClassName = fullyQualifiedName.replace('$', '.');
-
-               final int i = actualClassName.lastIndexOf('.');
+               final String actualClassName = classFullyQualifiedName
+                               .replace('$', '.');
 
-               String result = actualClassName.substring(i + 1);
-
-               if (isArray)
-                       result = result.substring(0, result.length() - 1);
+               String result;
+               if (isArray) {
+                       // for arrays use array component instead of array class name
+                       result = arrayComponent.classFullyQualifiedName;
+                       if (result.contains(".")) {
+                               final int i = result.lastIndexOf('.');
+                               result = result.substring(i + 1);
+                       }
+               } else {
+                       final int i = actualClassName.lastIndexOf('.');
+                       result = actualClassName.substring(i + 1);
+               }
 
                if (differentiateArray)
                        if (isArray)
@@ -324,8 +335,8 @@ public class ClassDescriptor implements GraphElement {
        @Override
        public String getGraphId() {
                final String result = "class_"
-                               + fullyQualifiedName.replace('.', '_').replace(";", "")
-                                               .replace("[L", "").replace('$', '_');
+                               + classFullyQualifiedName.replace('.', '_').replace(";", "")
+                               .replace("[L", "").replace('$', '_');
                return result;
        }
 
@@ -376,17 +387,17 @@ public class ClassDescriptor implements GraphElement {
 
        public String getPackageName() {
 
-               final int i = fullyQualifiedName.lastIndexOf('.');
+               final int i = classFullyQualifiedName.lastIndexOf('.');
 
                if (i == -1)
                        return "";
 
-               return fullyQualifiedName.substring(0, i).replace("[L", "");
+               return classFullyQualifiedName.substring(0, i).replace("[L", "");
        }
 
        public String getParentClassesName() {
-               int i = fullyQualifiedName.lastIndexOf('.');
-               final String fullClassName = fullyQualifiedName.substring(i + 1);
+               int i = classFullyQualifiedName.lastIndexOf('.');
+               final String fullClassName = classFullyQualifiedName.substring(i + 1);
 
                i = fullClassName.lastIndexOf('$');
                if (i == -1)
@@ -456,15 +467,24 @@ public class ClassDescriptor implements GraphElement {
        @Override
        public boolean isVisible() {
 
-               if (Utils.isSystemDataType(fullyQualifiedName))
+               if (Utils.isSystemDataType(classFullyQualifiedName))
                        return false;
 
-               if (Utils.isSystemPackage(fullyQualifiedName))
+               if (Utils.isSystemPackage(classFullyQualifiedName))
                        return false;
 
-               if (!classGraph.getFilter().isClassShown(fullyQualifiedName))
+               if (!classGraph.getFilter().isClassShown(classFullyQualifiedName))
                        return false;
 
+               if (isArray)
+                       if (arrayComponent != null)
+                               if (Utils
+                                               .isSystemDataType(arrayComponent.classFullyQualifiedName))
+                                       // Do not show references to primitive data types in arrays.
+                                       // That is: there is no point to show reference to byte when
+                                       // we have class with byte array field.
+                                       return false;
+
                return isShown;
        }
 
index bf34841..46cbc69 100755 (executable)
@@ -30,7 +30,7 @@ public class ClassGraph {
        /**
         * Maps class fully qualified names to class descriptors.
         */
-       Map<String, ClassDescriptor> nameToClassMap = new HashMap<String, ClassDescriptor>();
+       private final Map<String, ClassDescriptor> fullyQualifiedNameToClassMap = new HashMap<String, ClassDescriptor>();
 
        private Filter filter = new Filter();
 
@@ -66,8 +66,8 @@ public class ClassGraph {
 
                final String className = clazz.getName();
 
-               if (nameToClassMap.containsKey(className))
-                       return nameToClassMap.get(className);
+               if (fullyQualifiedNameToClassMap.containsKey(className))
+                       return fullyQualifiedNameToClassMap.get(className);
 
                return new ClassDescriptor(clazz, this);
        }
@@ -161,8 +161,8 @@ public class ClassGraph {
                        // execute GraphViz to visualize graph
                        try {
                                Runtime.getRuntime()
-                               .exec(new String[] { "dot", "-Tpng", dotFilePath, "-o",
-                                               imageFilePath }).waitFor();
+                                               .exec(new String[] { "dot", "-Tpng", dotFilePath, "-o",
+                                                               imageFilePath }).waitFor();
                        } catch (final InterruptedException e) {
                        } finally {
                        }
@@ -184,7 +184,7 @@ public class ClassGraph {
                result.append("digraph Java {\n");
                result.append("graph [rankdir=LR, overlap = false, concentrate=true];\n");
 
-               for (final Map.Entry<String, ClassDescriptor> entry : nameToClassMap
+               for (final Map.Entry<String, ClassDescriptor> entry : fullyQualifiedNameToClassMap
                                .entrySet())
                        result.append(entry.getValue().getDot());
 
@@ -203,11 +203,18 @@ public class ClassGraph {
         */
        public void hideOrphanedClasses() {
 
-               for (final ClassDescriptor classDescriptor : nameToClassMap.values())
+               for (final ClassDescriptor classDescriptor : fullyQualifiedNameToClassMap
+                               .values())
                        classDescriptor.hideClassIfNoReferences();
 
        }
 
+       public void registerClass(final String classFullyQualifiedName,
+                       final ClassDescriptor classDescriptor) {
+               fullyQualifiedNameToClassMap.put(classFullyQualifiedName,
+                               classDescriptor);
+       }
+
        public void setFilter(final Filter filter) {
                this.filter = filter;
        }
index 2162674..84d1ab1 100755 (executable)
@@ -27,12 +27,12 @@ public class FieldDescriptor implements GraphElement {
        List<ClassDescriptor> typeArguments = new ArrayList<ClassDescriptor>();
 
        public FieldDescriptor(final Field field, final ClassDescriptor parent,
-                       final ClassGraph dump) {
+                       final ClassGraph classGraph) {
 
                parentClass = parent;
 
                if (!field.getDeclaringClass().getName()
-                               .equals(parent.fullyQualifiedName))
+                               .equals(parent.classFullyQualifiedName))
                        // if field is inherited, do not index it
                        return;
 
@@ -42,7 +42,7 @@ public class FieldDescriptor implements GraphElement {
                parent.nameToFieldMap.put(field.getName(), this);
 
                name = field.getName();
-               type = dump.addClass(field.getType());
+               type = classGraph.addClass(field.getType());
                type.registerReference();
 
                final Type genericType = field.getGenericType();
@@ -51,7 +51,7 @@ public class FieldDescriptor implements GraphElement {
                        for (final Type t : pt.getActualTypeArguments())
                                if (t instanceof Class) {
                                        final Class cl = (Class) t;
-                                       final ClassDescriptor genericTypeDescriptor = dump
+                                       final ClassDescriptor genericTypeDescriptor = classGraph
                                                        .addClass(cl);
                                        genericTypeDescriptor.registerReference();
                                        typeArguments.add(genericTypeDescriptor);
index 456e728..cff1f8a 100755 (executable)
@@ -22,7 +22,7 @@ public class MethodDescriptor implements GraphElement,
         * This class corresponds to single method within a java class.
         */
 
-       public String name;
+       public String methodName;
        public ClassDescriptor returnType;
        private final ClassDescriptor parentClass;
 
@@ -33,10 +33,10 @@ public class MethodDescriptor implements GraphElement,
 
                parentClass = parent;
 
-               name = method.getName();
+               methodName = method.getName();
 
                if (!method.getDeclaringClass().getName()
-                               .equals(parent.fullyQualifiedName))
+                               .equals(parent.classFullyQualifiedName))
                        // do not index inherited methods
                        return;
 
@@ -62,7 +62,7 @@ public class MethodDescriptor implements GraphElement,
        @Override
        public int compareTo(final MethodDescriptor o) {
 
-               final int nameComparisonResult = name.compareTo(o.name);
+               final int nameComparisonResult = methodName.compareTo(o.methodName);
                if (nameComparisonResult != 0)
                        return nameComparisonResult;
 
@@ -82,7 +82,7 @@ public class MethodDescriptor implements GraphElement,
                        if (classDescriptor.isVisible())
                                if (classDescriptor.areReferencesShown())
                                        result.append("    " + getGraphId() + " -> "
-                                                       + classDescriptor.getGraphId() + "[label=\"" + name
+                                                       + classDescriptor.getGraphId() + "[label=\"" + methodName
                                                        + "\", color=\"" + classDescriptor.getColor()
                                                        + "\", style=\"dotted, bold\"];\n");
 
@@ -92,7 +92,7 @@ public class MethodDescriptor implements GraphElement,
                // main type
                if (returnType.areReferencesShown())
                        result.append("    " + getGraphId() + " -> "
-                                       + returnType.getGraphId() + "[label=\"" + name + "\","
+                                       + returnType.getGraphId() + "[label=\"" + methodName + "\","
                                        + " color=\"" + returnType.getColor()
                                        + "\", style=\"dotted, bold\"];\n");
 
@@ -106,7 +106,7 @@ public class MethodDescriptor implements GraphElement,
 
                final StringBuffer result = new StringBuffer();
 
-               result.append("        // " + name + "\n");
+               result.append("        // " + methodName + "\n");
 
                result.append("        <TR><td ALIGN=\"right\">"
                                + "<FONT POINT-SIZE=\"8.0\">" + returnType.getClassName(true)
@@ -119,11 +119,11 @@ public class MethodDescriptor implements GraphElement,
 
        @Override
        public String getGraphId() {
-               return parentClass.getGraphId() + ":" + name;
+               return parentClass.getGraphId() + ":" + methodName;
        }
 
        public String getMethodLabel() {
-               return name;
+               return methodName;
        }
 
        public int getOutsideVisibleReferencesCount() {
@@ -143,24 +143,24 @@ public class MethodDescriptor implements GraphElement,
        public boolean isVisible() {
 
                // hide common object methods
-               if (Utils.isCommonObjectMethod(name))
+               if (Utils.isCommonObjectMethod(methodName))
                        return false;
 
                // hide common Enumeration methods
-               if (parentClass.isEnum && Utils.isEnumMethod(name))
+               if (parentClass.isEnum && Utils.isEnumMethod(methodName))
                        return false;
 
                // hide get/set methods for the field of the same name
-               if (name.startsWith("get") || name.startsWith("set"))
-                       if (parentClass.hasFieldIgnoreCase(name.substring(3)))
+               if (methodName.startsWith("get") || methodName.startsWith("set"))
+                       if (parentClass.hasFieldIgnoreCase(methodName.substring(3)))
                                return false;
 
                // hide is methods for the boolean field of the same name
-               if (name.startsWith("is")) {
-                       final FieldDescriptor field = parentClass.getFieldIgnoreCase(name
+               if (methodName.startsWith("is")) {
+                       final FieldDescriptor field = parentClass.getFieldIgnoreCase(methodName
                                        .substring(2));
                        if (field != null)
-                               if ("boolean".equals(field.getType().fullyQualifiedName))
+                               if ("boolean".equals(field.getType().classFullyQualifiedName))
                                        return false;
                }