+ private final ClassDescriptor parentClassDescriptior;
+ private final List<ClassDescriptor> typeArguments = new ArrayList<ClassDescriptor>();
+ private String name;
+ private ClassDescriptor type;
+ private boolean isInherited;
+
+ public FieldDescriptor(final ClassDescriptor parent) {
+ parentClassDescriptior = parent;
+ }
+
+ public void analyzeField(final Field field) {
+
+ if (!field.getDeclaringClass().getName()
+ .equals(parentClassDescriptior.getFullyQualifiedName()))
+ isInherited = true;
+
+ name = field.getName();
+ type = parentClassDescriptior.getClassGraph().getOrCreateClassDescriptor(
+ field.getType());
+ type.registerReference();
+
+ final Type fieldGenericType = field.getGenericType();
+ if (fieldGenericType instanceof ParameterizedType) {
+ final ParameterizedType fieldParameterizedGenericType = (ParameterizedType) fieldGenericType;
+ for (final Type type : fieldParameterizedGenericType.getActualTypeArguments())
+ if (type instanceof Class) {
+ final Class aClass = (Class) type;
+ final ClassDescriptor genericTypeDescriptor = parentClassDescriptior
+ .getClassGraph().getOrCreateClassDescriptor(aClass);
+ genericTypeDescriptor.registerReference();
+ typeArguments.add(genericTypeDescriptor);
+ }
+
+ }
+ }
+
+ @Override
+ public String getDot() {
+
+ if (!isVisible())
+ return "";
+
+ final StringBuffer result = new StringBuffer();
+
+ // describe associated types
+ for (final ClassDescriptor classDescriptor : typeArguments)
+ if (classDescriptor.isVisible())
+ if (classDescriptor.areReferencesShown())
+ result.append(" " + getGraphId() + " -> "
+ + classDescriptor.getGraphId() + "[label=\"" + name
+ + "\", color=\"" + classDescriptor.getColor()
+ + "\", style=\"bold\"];\n");
+
+ if (type == null) return result.toString();
+ if (!type.isVisible())
+ return result.toString();
+
+ // main type
+ boolean showLink = type.areReferencesShown();
+
+ if (type == parentClassDescriptior)
+ showLink = false;
+
+ if (parentClassDescriptior.isEnum)
+ showLink = false;
+
+ if (showLink)
+ result.append(" " + getGraphId() + " -> " + type.getGraphId()
+ + "[label=\"" + name + "\"," + " color=\""
+ + type.getColor() + "\", style=\"bold\"];\n");
+
+ return result.toString();
+ }
+
+ @Override
+ public String getEmbeddedDot() {
+
+ if (!isVisible())
+ return "";
+
+ final StringBuffer result = new StringBuffer();
+
+ result.append(" // " + name + "\n");
+ if (parentClassDescriptior.isEnum && (type == parentClassDescriptior)) {
+ result.append(" <TR><TD colspan=\"2\" PORT=\"" + name);
+ result.append("\" ALIGN=\"left\"><FONT POINT-SIZE=\"11.0\">");
+ result.append(name + "</FONT></TD></TR>\n");
+ } else {
+ result.append(" <TR><td ALIGN=\"right\">");
+ result.append("<FONT POINT-SIZE=\"8.0\">");
+ result.append(describeType() + "</FONT>");
+ result.append("</td><TD PORT=\"" + name);
+ result.append("\" ALIGN=\"left\"><FONT POINT-SIZE=\"11.0\">");
+ result.append(name + "</FONT></TD></TR>\n");
+ }
+ return result.toString();
+ }
+
+ private String describeType() {
+ if (type == null) return "-null-";
+ return type.getClassName(true);
+ }
+
+ @Override
+ public String getGraphId() {
+ return parentClassDescriptior.getGraphId() + ":" + name;
+ }
+
+ protected int getOutsideVisibleReferencesCount() {
+
+ if (!isVisible())
+ return 0;
+
+ if (type != null)
+ if (type.isVisible())
+ return 1;
+
+ return 0;
+ }
+
+ protected ClassDescriptor getType() {
+ return type;
+ }
+
+ @Override
+ public boolean isVisible() {
+ if (isInherited)
+ return false;
+
+ if (name.contains("$"))
+ return false;