Code refactoring. Simplified API.
[javainspect.git] / src / main / java / eu / svjatoslav / inspector / java / structure / MethodDescriptor.java
1 /*
2  * JavaInspect - Utility to visualize java software
3  * Copyright (C) 2013-2015, 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         boolean isInherited;
32
33         public MethodDescriptor(final ClassDescriptor parent,
34                         final String methodName) {
35                 parentClass = parent;
36                 this.methodName = methodName;
37         }
38
39         public void analyze(final Method method) {
40
41                 if (!method.getDeclaringClass().getName()
42                                 .equals(parentClass.classFullyQualifiedName))
43                         isInherited = true;
44
45                 returnType = parentClass.getClassGraph().getOrCreateClassDescriptor(
46                                 method.getReturnType());
47                 returnType.registerReference();
48
49                 final Type genericType = method.getGenericReturnType();
50                 if (genericType instanceof ParameterizedType) {
51                         final ParameterizedType pt = (ParameterizedType) genericType;
52                         for (final Type t : pt.getActualTypeArguments())
53                                 if (t instanceof Class) {
54                                         final Class cl = (Class) t;
55                                         final ClassDescriptor classDescriptor = parentClass
56                                                         .getClassGraph().getOrCreateClassDescriptor(cl);
57                                         classDescriptor.registerReference();
58                                         argumentTypes.add(classDescriptor);
59                                 }
60
61                 }
62         }
63
64         @Override
65         public int compareTo(final MethodDescriptor o) {
66
67                 final int nameComparisonResult = methodName.compareTo(o.methodName);
68                 if (nameComparisonResult != 0)
69                         return nameComparisonResult;
70
71                 return toString().compareTo(o.toString());
72         }
73
74         @Override
75         public String getDot() {
76
77                 if (!isVisible())
78                         return "";
79
80                 final StringBuffer result = new StringBuffer();
81
82                 // describe associated types
83                 for (final ClassDescriptor classDescriptor : argumentTypes)
84                         if (classDescriptor.isVisible())
85                                 if (classDescriptor.areReferencesShown())
86                                         result.append("    " + getGraphId() + " -> "
87                                                         + classDescriptor.getGraphId() + "[label=\""
88                                                         + methodName + "\", color=\""
89                                                         + classDescriptor.getColor()
90                                                         + "\", style=\"dotted, bold\"];\n");
91
92                 if (!returnType.isVisible())
93                         return result.toString();
94
95                 // main type
96                 if (returnType.areReferencesShown())
97                         result.append("    " + getGraphId() + " -> "
98                                         + returnType.getGraphId() + "[label=\"" + methodName
99                                         + "\"," + " color=\"" + returnType.getColor()
100                                         + "\", style=\"dotted, bold\"];\n");
101
102                 return result.toString();
103         }
104
105         @Override
106         public String getEmbeddedDot() {
107                 if (!isVisible())
108                         return "";
109
110                 final StringBuffer result = new StringBuffer();
111
112                 result.append("        // " + methodName + "\n");
113
114                 result.append("        <TR><td ALIGN=\"right\">"
115                                 + "<FONT POINT-SIZE=\"8.0\">" + returnType.getClassName(true)
116                                 + "</FONT>" + "</td><TD PORT=\"" + getMethodLabel()
117                                 + "\" ALIGN=\"left\"><FONT COLOR =\"red\" POINT-SIZE=\"11.0\">"
118                                 + getMethodLabel() + "</FONT></TD></TR>\n");
119
120                 return result.toString();
121         }
122
123         @Override
124         public String getGraphId() {
125                 return parentClass.getGraphId() + ":" + methodName;
126         }
127
128         public String getMethodLabel() {
129                 return methodName;
130         }
131
132         public int getOutsideVisibleReferencesCount() {
133                 int result = 0;
134
135                 if (returnType.isVisible())
136                         result++;
137
138                 for (final ClassDescriptor classDescriptor : argumentTypes)
139                         if (classDescriptor.isVisible())
140                                 result++;
141
142                 return result;
143         }
144
145         @Override
146         public boolean isVisible() {
147
148                 // hide inherited methods
149                 if (isInherited)
150                         return false;
151
152                 // hide common object methods
153                 if (Utils.isCommonObjectMethod(methodName))
154                         return false;
155
156                 // hide common Enumeration methods
157                 if (parentClass.isEnum && Utils.isEnumMethod(methodName))
158                         return false;
159
160                 // hide get/set methods for the field of the same name
161                 if (methodName.startsWith("get") || methodName.startsWith("set"))
162                         if (parentClass.hasFieldIgnoreCase(methodName.substring(3)))
163                                 return false;
164
165                 // hide is methods for the boolean field of the same name
166                 if (methodName.startsWith("is")) {
167                         final FieldDescriptor field = parentClass
168                                         .getFieldIgnoreCase(methodName.substring(2));
169                         if (field != null)
170                                 if ("boolean".equals(field.getType().classFullyQualifiedName))
171                                         return false;
172                 }
173
174                 return true;
175
176         }
177
178 }