/*
* JavaInspect - Utility to visualize java software
- * Copyright (C) 2013-2014, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
+ * Copyright (C) 2013-2017, 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
import java.lang.reflect.Field;
import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.SortedSet;
-import java.util.TreeMap;
-import java.util.TreeSet;
+import java.util.*;
/**
* Describes single class instance
*/
-public class ClassDescriptor implements GraphElement {
+public class ClassDescriptor implements GraphElement, Comparable<ClassDescriptor> {
+
+ private static final int MAX_REFERECNES_COUNT = 10;
+ private final Map<String, FieldDescriptor> nameToFieldMap = new TreeMap<>();
+ private final SortedSet<MethodDescriptor> methods = new TreeSet<MethodDescriptor>();
+ private final ClassGraph classGraph;
+ boolean isEnum;
+ boolean isInterface;
+ boolean isArray;
+ List<ClassDescriptor> interfaces = new ArrayList<ClassDescriptor>();
+ ClassDescriptor superClass;
+ private String fullyQualifiedName;
+ /**
+ * Incoming arrows will have this color.
+ */
+ private String distinctiveReferenceColor;
+ private String interfaceColor;
+ private String superClassColor;
+ private boolean isShown = true;
+ /**
+ * Amount of field and method references pointing to this class.
+ */
+ private int referencesCount = 0;
+
+ // for interface, counts amount of found implementations
+ private int implementationsCount = 0;
+
+ // counts amount of times this class is extended
+ private int extensionsCount = 0;
+
+ private ClassDescriptor arrayComponent;
+
+ public ClassDescriptor(final ClassGraph classGraph) {
+ this.classGraph = classGraph;
+ }
+
+ protected void analyzeClass(final Class<? extends Object> clazz) {
+
+ fullyQualifiedName = clazz.getName();
+
+ isArray = clazz.isArray();
+
+ if (isArray) {
+ final Class<?> componentType = clazz.getComponentType();
+ arrayComponent = getClassGraph().getOrCreateClassDescriptor(
+ componentType);
+ }
+
+ // System.out.println("class: " + fullyQualifiedName);
+
+ isEnum = clazz.isEnum();
+
+ isInterface = clazz.isInterface();
+
+ if (!isVisible())
+ return;
+
+ try {
+ indexFields(clazz.getDeclaredFields());
+ indexFields(clazz.getFields());
+ } catch (NoClassDefFoundError error){
+ // TODO: better logging of this error
+ System.out.println(error.toString());
+ }
+
+ indexMethods(clazz);
+
+ for (final Class interfaceClass : clazz.getInterfaces()) {
+ final ClassDescriptor interfaceClassDescriptor = getClassGraph()
+ .getOrCreateClassDescriptor(interfaceClass);
+ interfaceClassDescriptor.registerImplementation();
+ interfaces.add(interfaceClassDescriptor);
+ }
+
+ superClass = getClassGraph().getOrCreateClassDescriptor(
+ clazz.getSuperclass());
+ if (superClass != null)
+ superClass.registerExtension();
+
+ }
+
+ protected boolean areReferencesShown() {
+ return referencesCount <= MAX_REFERECNES_COUNT;
+ }
+
+ private void enlistFieldReferences(final StringBuffer result) {
+ if (nameToFieldMap.isEmpty())
+ return;
+
+ result.append("\n");
+ result.append(" // field references to other classes\n");
+ nameToFieldMap.forEach((fieldName, field) -> result.append(field.getDot()));
+ }
+
+ private void enlistFields(final StringBuffer result) {
+ if (nameToFieldMap.isEmpty())
+ return;
+
+ result.append("\n");
+ result.append(" // fields:\n");
+
+ // enlist fields
+ for (final Map.Entry<String, FieldDescriptor> entry : nameToFieldMap
+ .entrySet())
+ result.append(entry.getValue().getEmbeddedDot());
+ }
+
+ private void enlistImplementedInterfaces(final StringBuffer result) {
+ if (interfaces.isEmpty())
+ return;
- private static final int MAX_REFERECNES_COUNT = 10;
+ result.append("\n");
+ result.append(" // interfaces implemented by class: "
+ + fullyQualifiedName + "\n");
- public final String classFullyQualifiedName;
+ for (final ClassDescriptor interfaceDescriptor : interfaces) {
+ if (!interfaceDescriptor.isVisible())
+ continue;
- Map<String, FieldDescriptor> nameToFieldMap = new TreeMap<String, FieldDescriptor>();
+ if (!interfaceDescriptor.areReferencesShown())
+ continue;
- public SortedSet<MethodDescriptor> methods = new TreeSet<MethodDescriptor>();
+ result.append(" " + interfaceDescriptor.getGraphId() + " -> "
+ + getGraphId() + "[style=\"dotted\", color=\""
+ + interfaceDescriptor.getInterfaceColor()
+ + "\", penwidth=10, dir=\"forward\"];\n");
+ }
+ }
- /**
- * Incoming arrows will have this color.
- */
- private String distinctiveReferenceColor;
+ private void enlistMethodReferences(final StringBuffer result) {
+ if (methods.isEmpty())
+ return;
+
+ result.append("\n");
+ result.append(" // method references to other classes\n");
+ for (final MethodDescriptor methodDescriptor : methods)
+ result.append(methodDescriptor.getDot());
+ }
+
+ private void enlistMethods(final StringBuffer result) {
+ if (methods.isEmpty())
+ return;
+
+ result.append("\n");
+ result.append(" // methods:\n");
+
+ // enlist methods
+ for (final MethodDescriptor methodDescriptor : methods)
+ result.append(methodDescriptor.getEmbeddedDot());
+ }
+
+ private void enlistSuperClass(final StringBuffer result) {
+ if (superClass == null)
+ return;
+
+ if (!superClass.isVisible())
+ return;
+
+ if (!superClass.areReferencesShown())
+ return;
+
+ result.append("\n");
+ result.append(" // super class for: " + fullyQualifiedName + "\n");
- private String interfaceColor;
+ result.append(" " + superClass.getGraphId() + " -> " + getGraphId()
+ + "[ color=\"" + superClass.getSuperClassColor()
+ + "\", penwidth=10, dir=\"forward\"];\n");
+ }
- private String superClassColor;
+ private void generateDotHeader(final StringBuffer result) {
+ result.append("\n");
+ result.append("// Class: " + fullyQualifiedName + "\n");
- boolean isEnum;
+ result.append(" " + getGraphId() + "[label=<<TABLE "
+ + getBackgroundColor() + " BORDER=\"" + getBorderWidth()
+ + "\" CELLBORDER=\"1\" CELLSPACING=\"0\">\n");
- boolean isInterface;
+ result.append("\n");
+ result.append(" // class descriptor header\n");
+ result.append(" <TR><TD colspan=\"2\" PORT=\"f0\">"
+ + "<FONT POINT-SIZE=\"8.0\" >" + getPackageName()
+ + "</FONT><br/>");
- boolean isArray;
+ final String parentClassesName = getParentClassesName();
+ if (parentClassesName.length() > 0)
+ result.append("<FONT POINT-SIZE=\"12.0\"><B>" + parentClassesName
+ + "</B></FONT><br/>\n");
- private boolean isShown = true;
+ result.append("<FONT POINT-SIZE=\"25.0\"><B>" + getClassName(false)
+ + "</B></FONT>" + "</TD></TR>\n");
+ }
- private final ClassGraph classGraph;
+ private String getBackgroundColor() {
+ String bgColor = "";
- List<ClassDescriptor> interfaces = new ArrayList<ClassDescriptor>();
+ if (isEnum)
+ bgColor = "bgcolor=\"navajowhite2\"";
- ClassDescriptor superClass;
+ if (isInterface)
+ bgColor = "bgcolor=\"darkslategray1\"";
- /**
- * Amount of field and method references pointing to this class.
- */
- private int referencesCount = 0;
+ return bgColor;
+ }
- // for interface, counts amount of found implementations
- private int implementationsCount = 0;
+ private String getBorderWidth() {
- // counts amount of times this class is extended
- private int extensionsCount = 0;
+ if (!areReferencesShown())
+ return "4";
+ return "1";
+ }
- private ClassDescriptor arrayComponent;
+ protected ClassGraph getClassGraph() {
+ return classGraph;
+ }
- public ClassDescriptor(final Class<? extends Object> clazz,
- final ClassGraph classGraph) {
- this.classGraph = classGraph;
+ protected String getClassName(final boolean differentiateArray) {
+ // this is needed for nested classes
+ final String actualClassName = fullyQualifiedName.replace('$', '.');
- classFullyQualifiedName = clazz.getName();
+ String result;
+ if (isArray) {
+ // for arrays use array component instead of array class name
+ result = arrayComponent.fullyQualifiedName;
+ if (result.contains(".")) {
+ final int i = result.lastIndexOf('.');
+ result = result.substring(i + 1);
+ }
+ } else {
+ final int i = actualClassName.lastIndexOf('.');
+ result = actualClassName.substring(i + 1);
+ }
- classGraph.registerClass(classFullyQualifiedName, this);
+ if (differentiateArray)
+ if (isArray)
+ result += " []";
- isArray = clazz.isArray();
+ // this is needed for nested classes
+ // result = result.replace('$', '.');
+ return result;
+ }
- if (isArray) {
- final Class<?> componentType = clazz.getComponentType();
- arrayComponent = classGraph.addClass(componentType);
- }
+ protected String getColor() {
+ if (distinctiveReferenceColor == null)
+ distinctiveReferenceColor = Utils.getNextDarkColor();
- // System.out.println("class: " + fullyQualifiedName);
+ return distinctiveReferenceColor;
+ }
- isEnum = clazz.isEnum();
+ @Override
+ public String getDot() {
+ if (!isVisible())
+ return "";
- isInterface = clazz.isInterface();
+ if (isArray)
+ return "";
- if (!isVisible())
- return;
+ final StringBuffer result = new StringBuffer();
- indexFields(clazz.getDeclaredFields());
- indexFields(clazz.getFields());
+ generateDotHeader(result);
- indexMethods(clazz);
+ enlistFields(result);
- for (final Class interfaceClass : clazz.getInterfaces()) {
- final ClassDescriptor classDescriptor = classGraph
- .addClass(interfaceClass);
- classDescriptor.registerImplementation();
- interfaces.add(classDescriptor);
- }
+ enlistMethods(result);
- superClass = classGraph.addClass(clazz.getSuperclass());
- if (superClass != null)
- superClass.registerExtension();
+ result.append(" </TABLE>>, shape=\"none\"];\n");
- }
+ enlistFieldReferences(result);
- public boolean areReferencesShown() {
- return referencesCount <= MAX_REFERECNES_COUNT;
- }
+ enlistMethodReferences(result);
- public void enlistFieldReferences(final StringBuffer result) {
- if (nameToFieldMap.isEmpty())
- return;
+ enlistImplementedInterfaces(result);
- result.append("\n");
- result.append(" // field references to other classes\n");
- for (final Map.Entry<String, FieldDescriptor> entry : nameToFieldMap
- .entrySet())
- result.append(entry.getValue().getDot());
- }
+ enlistSuperClass(result);
- public void enlistFields(final StringBuffer result) {
- if (nameToFieldMap.isEmpty())
- return;
+ return result.toString();
+ }
- result.append("\n");
- result.append(" // fields:\n");
+ @Override
+ public String getEmbeddedDot() {
+ return null;
+ }
- // enlist fields
- for (final Map.Entry<String, FieldDescriptor> entry : nameToFieldMap
- .entrySet())
- result.append(entry.getValue().getEmbeddedDot());
- }
+ /**
+ * Returns field with given name (case is ignored). Or <code>null</code> if
+ * field is not found.
+ *
+ * @param fieldToSearch field name (case is ignored)
+ * @return field matching given name
+ */
+ protected FieldDescriptor getFieldIgnoreCase(final String fieldToSearch) {
- public void enlistImplementedInterfaces(final StringBuffer result) {
- if (interfaces.isEmpty())
- return;
+ for (final String fieldName : nameToFieldMap.keySet())
+ if (fieldToSearch.equalsIgnoreCase(fieldName))
+ return nameToFieldMap.get(fieldName);
- result.append("\n");
- result.append(" // interfaces implemented by class: "
- + classFullyQualifiedName + "\n");
+ return null;
+ }
- for (final ClassDescriptor interfaceDescriptor : interfaces) {
- if (!interfaceDescriptor.isVisible())
- continue;
+ protected String getFullyQualifiedName() {
+ return fullyQualifiedName;
+ }
- if (!interfaceDescriptor.areReferencesShown())
- continue;
+ @Override
+ public String getGraphId() {
+ final String result = "class_"
+ + fullyQualifiedName
+ .replace('.', '_')
+ .replace(";", "")
+ .replace("[[", "")
+ .replace("[L", "")
+ .replace("[[L", "") // array of arrays
+ .replace("[[[L", "") // array of arrays of arrays
+ .replace('$', '_');
- result.append(" " + interfaceDescriptor.getGraphId() + " -> "
- + getGraphId() + "[style=\"dotted, tapered\", color=\""
- + interfaceDescriptor.getInterfaceColor()
- + "\", penwidth=20, dir=\"forward\"];\n");
- }
- }
+ return result;
+ }
- public void enlistMethodReferences(final StringBuffer result) {
- if (methods.isEmpty())
- return;
+ private String getInterfaceColor() {
+ if (interfaceColor == null)
+ interfaceColor = Utils.getNextDarkColor();
- result.append("\n");
- result.append(" // method references to other classes\n");
- for (final MethodDescriptor methodDescriptor : methods)
- result.append(methodDescriptor.getDot());
- }
+ return interfaceColor;
+ }
- public void enlistMethods(final StringBuffer result) {
- if (methods.isEmpty())
- return;
+ private FieldDescriptor getOrCreateFieldDescriptor(final Field field) {
- result.append("\n");
- result.append(" // methods:\n");
-
- // enlist methods
- for (final MethodDescriptor methodDescriptor : methods)
- result.append(methodDescriptor.getEmbeddedDot());
- }
-
- public void enlistSuperClass(final StringBuffer result) {
- if (superClass == null)
- return;
-
- if (!superClass.isVisible())
- return;
-
- if (!superClass.areReferencesShown())
- return;
-
- result.append("\n");
- result.append(" // super class for: " + classFullyQualifiedName
- + "\n");
-
- result.append(" " + superClass.getGraphId() + " -> " + getGraphId()
- + "[style=\"tapered\", color=\""
- + superClass.getSuperClassColor()
- + "\", penwidth=10, dir=\"forward\"];\n");
- }
-
- public void generateDotHeader(final StringBuffer result) {
- result.append("\n");
- result.append("// Class: " + classFullyQualifiedName + "\n");
-
- result.append(" " + getGraphId() + "[label=<<TABLE "
- + getBackgroundColor() + " BORDER=\"" + getBorderWidth()
- + "\" CELLBORDER=\"1\" CELLSPACING=\"0\">\n");
+ final String fieldName = field.getName();
- result.append("\n");
- result.append(" // class descriptor header\n");
- result.append(" <TR><TD colspan=\"2\" PORT=\"f0\">"
- + "<FONT POINT-SIZE=\"8.0\" >" + getPackageName()
- + "</FONT><br/>");
+ if (nameToFieldMap.containsKey(fieldName))
+ return nameToFieldMap.get(fieldName);
- final String parentClassesName = getParentClassesName();
- if (parentClassesName.length() > 0)
- result.append("<FONT POINT-SIZE=\"12.0\"><B>" + parentClassesName
- + "</B></FONT><br/>\n");
+ final FieldDescriptor newFieldDescriptor = new FieldDescriptor(this);
+ nameToFieldMap.put(fieldName, newFieldDescriptor);
- result.append("<FONT POINT-SIZE=\"25.0\"><B>" + getClassName(false)
- + "</B></FONT>" + "</TD></TR>\n");
- }
+ newFieldDescriptor.analyzeField(field);
- public List<FieldDescriptor> getAllFields() {
- final List<FieldDescriptor> result = new ArrayList<FieldDescriptor>();
+ return newFieldDescriptor;
+ }
- for (final Map.Entry<String, FieldDescriptor> entry : nameToFieldMap
- .entrySet())
- result.add(entry.getValue());
+ private int getOutgoingReferencesCount() {
+ int result = 0;
- return result;
- }
+ // count method references
+ for (final MethodDescriptor methodDescriptor : methods)
+ result += methodDescriptor.getOutsideVisibleReferencesCount();
- public String getBackgroundColor() {
- String bgColor = "";
+ // count field references
+ for (final FieldDescriptor fieldDescriptor : nameToFieldMap.values())
+ result += fieldDescriptor.getOutsideVisibleReferencesCount();
- if (isEnum)
- bgColor = "bgcolor=\"navajowhite2\"";
+ // count implemented interfaces
+ for (final ClassDescriptor classDescriptor : interfaces)
+ if (classDescriptor.isVisible())
+ result++;
- if (isInterface)
- bgColor = "bgcolor=\"darkslategray1\"";
+ // count superclass
+ if (superClass != null)
+ if (superClass.isVisible())
+ result++;
- return bgColor;
- }
+ return result;
+ }
- public String getBorderWidth() {
+ private String getPackageName() {
- if (!areReferencesShown())
- return "4";
- return "1";
- }
+ final int i = fullyQualifiedName.lastIndexOf('.');
- public String getClassName(final boolean differentiateArray) {
- // this is needed for nested classes
- final String actualClassName = classFullyQualifiedName
- .replace('$', '.');
+ if (i == -1)
+ return "";
- 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);
- }
+ return fullyQualifiedName.substring(0, i).replace("[L", "");
+ }
- if (differentiateArray)
- if (isArray)
- result += " []";
+ private String getParentClassesName() {
+ int i = fullyQualifiedName.lastIndexOf('.');
+ final String fullClassName = fullyQualifiedName.substring(i + 1);
- // this is needed for nested classes
- // result = result.replace('$', '.');
- return result;
- }
+ i = fullClassName.lastIndexOf('$');
+ if (i == -1)
+ return "";
+ final String parentClassesName = fullClassName.substring(0, i);
+ return parentClassesName.replace('$', '.');
+ }
- public String getColor() {
- if (getDistinctiveColor() == null)
- setDistinctiveColor(Utils.getNextDarkColor());
+ private String getSuperClassColor() {
+ if (superClassColor == null)
+ superClassColor = Utils.getNextLightColor();
- return getDistinctiveColor();
- }
+ return superClassColor;
+ }
- public String getDistinctiveColor() {
- return distinctiveReferenceColor;
- }
+ /**
+ * Checks if class has field with given name (case is ignored). Returns
+ * <code>true</code> if such field is found.
+ *
+ * @param fieldToSearch field to search for (case is ignored)
+ * @return <code>true</code> if field is found.
+ */
+ protected boolean hasFieldIgnoreCase(final String fieldToSearch) {
- @Override
- public String getDot() {
- if (!isVisible())
- return "";
+ for (final String fieldName : nameToFieldMap.keySet())
+ if (fieldToSearch.equalsIgnoreCase(fieldName))
+ return true;
- if (isArray)
- return "";
+ return false;
+ }
- final StringBuffer result = new StringBuffer();
+ private void hide() {
+ isShown = false;
+ }
- generateDotHeader(result);
+ protected void hideClassIfNoReferences() {
+ if (!isVisible())
+ return;
- enlistFields(result);
+ final int totalReferencesCount = getOutgoingReferencesCount()
+ + referencesCount + extensionsCount + implementationsCount;
- enlistMethods(result);
+ if (totalReferencesCount == 0) {
+ hide();
+ return;
+ }
- result.append(" </TABLE>>, shape=\"none\"];\n");
+ return;
+ }
- enlistFieldReferences(result);
+ private void indexFields(final Field[] fields) {
+ for (final Field field : fields)
+ getOrCreateFieldDescriptor(field);
+ }
- enlistMethodReferences(result);
+ private void indexMethods(final Class<? extends Object> clazz) {
+ for (final Method method : clazz.getMethods()) {
+ final MethodDescriptor methodDescriptor = new MethodDescriptor(
+ this, method.getName());
- enlistImplementedInterfaces(result);
+ methods.add(methodDescriptor);
- enlistSuperClass(result);
+ methodDescriptor.analyze(method);
+ }
- return result.toString();
- }
+ }
- @Override
- public String getEmbeddedDot() {
- return null;
- }
+ @Override
+ public boolean isVisible() {
- /**
- * Returns field with given name (case is ignored). Or <code>null</code> if
- * field is not found.
- */
- public FieldDescriptor getFieldIgnoreCase(final String fieldToSearch) {
+ if (Utils.isSystemDataType(fullyQualifiedName))
+ return false;
- for (final String fieldName : nameToFieldMap.keySet())
- if (fieldToSearch.equalsIgnoreCase(fieldName))
- return nameToFieldMap.get(fieldName);
+ if (Utils.isSystemPackage(fullyQualifiedName))
+ return false;
- return null;
- }
+ if (!getClassGraph().isClassShown(fullyQualifiedName))
+ return false;
- @Override
- public String getGraphId() {
- final String result = "class_"
- + classFullyQualifiedName.replace('.', '_').replace(";", "")
- .replace("[L", "").replace('$', '_');
- return result;
- }
+ if (isArray)
+ if (arrayComponent != null)
+ if (Utils.isSystemDataType(arrayComponent.fullyQualifiedName))
+ // 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;
- public String getInterfaceColor() {
- if (interfaceColor == null)
- interfaceColor = Utils.getNextLightColor();
-
- return interfaceColor;
- }
+ return isShown;
+ }
- private int getOutgoingReferencesCount() {
- int result = 0;
+ /**
+ * Register event when another class is extending this one.
+ */
+ protected void registerExtension() {
+ extensionsCount++;
+ }
- // count method references
- for (final MethodDescriptor methodDescriptor : methods)
- result += methodDescriptor.getOutsideVisibleReferencesCount();
+ protected void registerImplementation() {
+ implementationsCount++;
+ }
- // count field references
- for (final FieldDescriptor fieldDescriptor : nameToFieldMap.values())
- result += fieldDescriptor.getOutsideVisibleReferencesCount();
+ protected void registerReference() {
+ referencesCount++;
+ }
- // count implemented interfaces
- for (final ClassDescriptor classDescriptor : interfaces)
- if (classDescriptor.isVisible())
- result++;
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof ClassDescriptor)) return false;
- // count superclass
- if (superClass != null)
- if (superClass.isVisible())
- result++;
+ ClassDescriptor that = (ClassDescriptor) o;
- return result;
- }
+ return getFullyQualifiedName().equals(that.getFullyQualifiedName());
- // 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() {
+ @Override
+ public int hashCode() {
+ return getFullyQualifiedName().hashCode();
+ }
- final int i = classFullyQualifiedName.lastIndexOf('.');
-
- if (i == -1)
- return "";
-
- return classFullyQualifiedName.substring(0, i).replace("[L", "");
- }
-
- public String getParentClassesName() {
- int i = classFullyQualifiedName.lastIndexOf('.');
- final String fullClassName = classFullyQualifiedName.substring(i + 1);
-
- i = fullClassName.lastIndexOf('$');
- if (i == -1)
- return "";
- final String parentClassesName = fullClassName.substring(0, i);
- return parentClassesName.replace('$', '.');
- }
-
- public String getSuperClassColor() {
- if (superClassColor == null)
- superClassColor = Utils.getNextLightColor();
-
- return superClassColor;
- }
-
- /**
- * Checks if class has field with given name (case is ignored). Returns
- * <code>true</code> if such field is found.
- */
- public boolean hasFieldIgnoreCase(final String fieldToSearch) {
-
- for (final String fieldName : nameToFieldMap.keySet())
- if (fieldToSearch.equalsIgnoreCase(fieldName))
- return true;
-
- return false;
- }
-
- public void hide() {
- isShown = false;
- }
-
- public void hideClassIfNoReferences() {
- if (!isVisible())
- return;
-
- final int totalReferencesCount = getOutgoingReferencesCount()
- + referencesCount + extensionsCount + implementationsCount;
-
- if (totalReferencesCount == 0) {
- hide();
- return;
- }
-
- return;
- }
-
- 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);
-
- }
- }
-
- private void indexMethods(final Class<? extends Object> clazz) {
- final Method[] methods = clazz.getMethods();
-
- for (final Method method : methods)
- new MethodDescriptor(method, this, classGraph);
-
- }
-
- @Override
- public boolean isVisible() {
-
- if (Utils.isSystemDataType(classFullyQualifiedName))
- return false;
-
- if (Utils.isSystemPackage(classFullyQualifiedName))
- return false;
-
- 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;
- }
-
- /**
- * Register event when another class is extending this one.
- */
- public void registerExtension() {
- extensionsCount++;
- }
-
- public void registerImplementation() {
- implementationsCount++;
- }
-
- public void registerReference() {
- referencesCount++;
- }
-
- public void setDistinctiveColor(final String distinctiveColor) {
- distinctiveReferenceColor = distinctiveColor;
- }
+ @Override
+ public int compareTo(ClassDescriptor o) {
+ return fullyQualifiedName.compareTo(o.fullyQualifiedName);
+ }
}