properly render fields of arrays of primitive types
[javainspect.git] / src / main / java / eu / svjatoslav / inspector / java / structure / MethodDescriptor.java
1 /*
2  * JavaInspect - Utility to visualize java software
3  * Copyright (C) 2013-2014, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
4  * 
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of version 3 of the GNU Lesser General Public License
7  * or later as published by the Free Software Foundation.
8  */
9
10 package eu.svjatoslav.inspector.java.structure;
11
12 import java.lang.reflect.Method;
13 import java.lang.reflect.ParameterizedType;
14 import java.lang.reflect.Type;
15 import java.util.ArrayList;
16 import java.util.List;
17
18 public class MethodDescriptor implements GraphElement,
19                 Comparable<MethodDescriptor> {
20
21         /**
22          * This class corresponds to single method within a java class.
23          */
24
25         public String methodName;
26         public ClassDescriptor returnType;
27         private final ClassDescriptor parentClass;
28
29         List<ClassDescriptor> argumentTypes = new ArrayList<ClassDescriptor>();
30
31         public MethodDescriptor(final Method method, final ClassDescriptor parent,
32                         final ClassGraph dump) {
33
34                 parentClass = parent;
35
36                 methodName = method.getName();
37
38                 if (!method.getDeclaringClass().getName()
39                                 .equals(parent.classFullyQualifiedName))
40                         // do not index inherited methods
41                         return;
42
43                 parent.methods.add(this);
44
45                 returnType = dump.addClass(method.getReturnType());
46                 returnType.registerReference();
47
48                 final Type genericType = method.getGenericReturnType();
49                 if (genericType instanceof ParameterizedType) {
50                         final ParameterizedType pt = (ParameterizedType) genericType;
51                         for (final Type t : pt.getActualTypeArguments())
52                                 if (t instanceof Class) {
53                                         final Class cl = (Class) t;
54                                         final ClassDescriptor classDescriptor = dump.addClass(cl);
55                                         classDescriptor.registerReference();
56                                         argumentTypes.add(classDescriptor);
57                                 }
58
59                 }
60         }
61
62         @Override
63         public int compareTo(final MethodDescriptor o) {
64
65                 final int nameComparisonResult = methodName.compareTo(o.methodName);
66                 if (nameComparisonResult != 0)
67                         return nameComparisonResult;
68
69                 return toString().compareTo(o.toString());
70         }
71
72         @Override
73         public String getDot() {
74
75                 if (!isVisible())
76                         return "";
77
78                 final StringBuffer result = new StringBuffer();
79
80                 // describe associated types
81                 for (final ClassDescriptor classDescriptor : argumentTypes)
82                         if (classDescriptor.isVisible())
83                                 if (classDescriptor.areReferencesShown())
84                                         result.append("    " + getGraphId() + " -> "
85                                                         + classDescriptor.getGraphId() + "[label=\"" + methodName
86                                                         + "\", color=\"" + classDescriptor.getColor()
87                                                         + "\", style=\"dotted, bold\"];\n");
88
89                 if (!returnType.isVisible())
90                         return result.toString();
91
92                 // main type
93                 if (returnType.areReferencesShown())
94                         result.append("    " + getGraphId() + " -> "
95                                         + returnType.getGraphId() + "[label=\"" + methodName + "\","
96                                         + " color=\"" + returnType.getColor()
97                                         + "\", style=\"dotted, bold\"];\n");
98
99                 return result.toString();
100         }
101
102         @Override
103         public String getEmbeddedDot() {
104                 if (!isVisible())
105                         return "";
106
107                 final StringBuffer result = new StringBuffer();
108
109                 result.append("        // " + methodName + "\n");
110
111                 result.append("        <TR><td ALIGN=\"right\">"
112                                 + "<FONT POINT-SIZE=\"8.0\">" + returnType.getClassName(true)
113                                 + "</FONT>" + "</td><TD PORT=\"" + getMethodLabel()
114                                 + "\" ALIGN=\"left\"><FONT COLOR =\"red\" POINT-SIZE=\"11.0\">"
115                                 + getMethodLabel() + "</FONT></TD></TR>\n");
116
117                 return result.toString();
118         }
119
120         @Override
121         public String getGraphId() {
122                 return parentClass.getGraphId() + ":" + methodName;
123         }
124
125         public String getMethodLabel() {
126                 return methodName;
127         }
128
129         public int getOutsideVisibleReferencesCount() {
130                 int result = 0;
131
132                 if (returnType.isVisible())
133                         result++;
134
135                 for (final ClassDescriptor classDescriptor : argumentTypes)
136                         if (classDescriptor.isVisible())
137                                 result++;
138
139                 return result;
140         }
141
142         @Override
143         public boolean isVisible() {
144
145                 // hide common object methods
146                 if (Utils.isCommonObjectMethod(methodName))
147                         return false;
148
149                 // hide common Enumeration methods
150                 if (parentClass.isEnum && Utils.isEnumMethod(methodName))
151                         return false;
152
153                 // hide get/set methods for the field of the same name
154                 if (methodName.startsWith("get") || methodName.startsWith("set"))
155                         if (parentClass.hasFieldIgnoreCase(methodName.substring(3)))
156                                 return false;
157
158                 // hide is methods for the boolean field of the same name
159                 if (methodName.startsWith("is")) {
160                         final FieldDescriptor field = parentClass.getFieldIgnoreCase(methodName
161                                         .substring(2));
162                         if (field != null)
163                                 if ("boolean".equals(field.getType().classFullyQualifiedName))
164                                         return false;
165                 }
166
167                 return true;
168
169         }
170
171 }