reduced method visibility
[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 /**
19  * This class corresponds to single method within a java class.
20  */
21 public class MethodDescriptor implements GraphElement,
22                 Comparable<MethodDescriptor> {
23
24         private final String methodName;
25         private ClassDescriptor returnType;
26         private final ClassDescriptor parentClass;
27         private final List<ClassDescriptor> argumentTypes = new ArrayList<ClassDescriptor>();
28         private boolean isInherited;
29
30         public MethodDescriptor(final ClassDescriptor parent,
31                         final String methodName) {
32                 parentClass = parent;
33                 this.methodName = methodName;
34         }
35
36         public void analyze(final Method method) {
37
38                 if (!method.getDeclaringClass().getName()
39                                 .equals(parentClass.getFullyQualifiedName()))
40                         isInherited = true;
41
42                 returnType = parentClass.getClassGraph().getOrCreateClassDescriptor(
43                                 method.getReturnType());
44                 returnType.registerReference();
45
46                 final Type genericType = method.getGenericReturnType();
47                 if (genericType instanceof ParameterizedType) {
48                         final ParameterizedType pt = (ParameterizedType) genericType;
49                         for (final Type t : pt.getActualTypeArguments())
50                                 if (t instanceof Class) {
51                                         final Class cl = (Class) t;
52                                         final ClassDescriptor classDescriptor = parentClass
53                                                         .getClassGraph().getOrCreateClassDescriptor(cl);
54                                         classDescriptor.registerReference();
55                                         argumentTypes.add(classDescriptor);
56                                 }
57
58                 }
59         }
60
61         @Override
62         public int compareTo(final MethodDescriptor o) {
63
64                 final int nameComparisonResult = methodName.compareTo(o.methodName);
65                 if (nameComparisonResult != 0)
66                         return nameComparisonResult;
67
68                 return toString().compareTo(o.toString());
69         }
70
71         @Override
72         public String getDot() {
73
74                 if (!isVisible())
75                         return "";
76
77                 final StringBuffer result = new StringBuffer();
78
79                 // describe associated types
80                 for (final ClassDescriptor classDescriptor : argumentTypes)
81                         if (classDescriptor.isVisible())
82                                 if (classDescriptor.areReferencesShown())
83                                         result.append("    " + getGraphId() + " -> "
84                                                         + classDescriptor.getGraphId() + "[label=\""
85                                                         + methodName + "\", color=\""
86                                                         + 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         private String getMethodLabel() {
126                 return methodName;
127         }
128
129         protected 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 inherited methods
146                 if (isInherited)
147                         return false;
148
149                 // hide common object methods
150                 if (Utils.isCommonObjectMethod(methodName))
151                         return false;
152
153                 // hide common Enumeration methods
154                 if (parentClass.isEnum && Utils.isEnumMethod(methodName))
155                         return false;
156
157                 // hide get/set methods for the field of the same name
158                 if (methodName.startsWith("get") || methodName.startsWith("set"))
159                         if (parentClass.hasFieldIgnoreCase(methodName.substring(3)))
160                                 return false;
161
162                 // hide is methods for the boolean field of the same name
163                 if (methodName.startsWith("is")) {
164                         final FieldDescriptor field = parentClass
165                                         .getFieldIgnoreCase(methodName.substring(2));
166                         if (field != null)
167                                 if ("boolean".equals(field.getType().getFullyQualifiedName()))
168                                         return false;
169                 }
170
171                 return true;
172
173         }
174
175 }