1
2
3
4
5 package xjavadoc;
6
7 import java.lang.reflect.Modifier;
8 import java.util.ArrayList;
9 import java.util.Iterator;
10 import java.util.List;
11 import java.beans.Introspector;
12
13 /***
14 * Describe what this class does
15 *
16 * @author Aslak Hellesøy
17 * @created 25. februar 2003
18 */
19 final class MethodImpl extends AbstractExecutableMember implements XMethod
20 {
21 public static int instanceCount = 0;
22
23 private String methodNameWithSignatureAndModifiers = null;
24 private String methodNameWithSignatureWithoutModifiers = null;
25
26 private ReturnType _returnType = new ReturnType( this );
27
28 public MethodImpl( AbstractClass containingClass, XTagFactory tagFactory )
29 {
30 super( containingClass, tagFactory );
31
32
33
34 if( containingClass.isInterface() )
35 {
36 addModifier( Modifier.PUBLIC );
37 }
38 instanceCount++;
39 }
40
41 /***
42 * Gets the Constructor attribute of the SourceMethod object
43 *
44 * @return The Constructor value
45 */
46 public final boolean isConstructor()
47 {
48 return false;
49 }
50
51 public final Type getReturnType()
52 {
53 return _returnType;
54 }
55
56 public XProgramElement getSuperElement()
57 {
58 return getSuperElement( true );
59 }
60
61 public List getSuperInterfaceElements()
62 {
63
64 Iterator interfaces = getContainingClass().getInterfaces().iterator();
65
66 List result = new ArrayList();
67
68 while ( interfaces.hasNext() )
69 {
70
71 XClass superinterface = (XClass) interfaces.next();
72
73 XExecutableMember superExecutableMember = superinterface.getMethod( getNameWithSignature( false ) );
74 if( superExecutableMember != null )
75 {
76 result.add( superExecutableMember );
77 }
78
79
80
81 }
82
83 return result;
84 }
85
86 public XMethod getAccessor()
87 {
88 XMethod result = null;
89
90 if( isPropertyMutator() )
91 {
92 Type requiredType = ( Type ) getParameters().iterator().next();
93 String getterNameWithSignature = "get" + getNameWithoutPrefix() + "()";
94 String isserNameWithSignature = "is" + getNameWithoutPrefix() + "()";
95 XMethod getter = getContainingClass().getMethod( getterNameWithSignature, true );
96 XMethod isser = getContainingClass().getMethod( isserNameWithSignature, true );
97
98
99 if( getter == null && isser != null )
100 {
101 result = isser;
102 }
103 else if( getter != null && isser == null )
104 {
105 result = getter;
106 }
107
108 if( !requiredType.equals( result.getReturnType() ) )
109 {
110 result = null;
111 }
112 }
113 return result;
114 }
115
116 public XMethod getMutator()
117 {
118 XMethod result = null;
119
120 if( isPropertyAccessor() )
121 {
122 Type requiredType = getReturnType();
123 String argument = requiredType.getType().getQualifiedName() + requiredType.getDimensionAsString();
124 String setterNameWithSignature = "set" + getNameWithoutPrefix() + "(" + argument + ")";
125
126 result = getContainingClass().getMethod( setterNameWithSignature, true );
127 }
128 return result;
129 }
130
131 public boolean isPropertyAccessor()
132 {
133 boolean signatureOk = false;
134 boolean nameOk = false;
135
136 if( getName().startsWith( "is" ) )
137 {
138 signatureOk = getReturnType().getType().getQualifiedName().equals( "boolean" ) || getReturnType().getType().getQualifiedName().equals( "java.lang.Boolean" );
139 signatureOk = signatureOk && getReturnType().getDimension() == 0;
140 if( getName().length() > 2 )
141 {
142 nameOk = Character.isUpperCase( getName().charAt( 2 ) );
143 }
144 }
145 if( getName().startsWith( "get" ) )
146 {
147 signatureOk = true;
148 if( getName().length() > 3 )
149 {
150 nameOk = Character.isUpperCase( getName().charAt( 3 ) );
151 }
152 }
153
154 boolean noParams = getParameters().size() == 0;
155
156 return signatureOk && nameOk && noParams;
157 }
158
159 public boolean isPropertyMutator()
160 {
161 boolean nameOk = false;
162
163 if( getName().startsWith( "set" ) )
164 {
165 if( getName().length() > 3 )
166 {
167 nameOk = Character.isUpperCase( getName().charAt( 3 ) );
168 }
169 }
170
171 boolean oneParam = getParameters().size() == 1;
172
173 return nameOk && oneParam;
174 }
175
176 public String getPropertyName()
177 {
178 String result = null;
179
180 if( getName().startsWith( "get" ) || getName().startsWith( "set" ) )
181 {
182 result = Introspector.decapitalize( getName().substring( 3 ) );
183 }
184 else if( getName().startsWith( "is" ) )
185 {
186 result = Introspector.decapitalize( getName().substring( 2 ) );
187 }
188 return result;
189 }
190
191 public Type getPropertyType()
192 {
193 Type result = null;
194
195 if( isPropertyMutator() )
196 {
197 XParameter parameter = ( XParameter ) getParameters().iterator().next();
198
199 result = parameter;
200 }
201 else if( isPropertyAccessor() )
202 {
203 result = getReturnType();
204 }
205 return result;
206 }
207
208 public String getNameWithoutPrefix()
209 {
210 for( int i = 0; i < getName().length(); i++ )
211 {
212 if( Character.isUpperCase( getName().charAt( i ) ) )
213 {
214 return getName().substring( i );
215 }
216 }
217 return null;
218 }
219
220 /***
221 * Sets the ReturnType attribute of the SourceMethod object
222 *
223 * @param returnType The new ReturnType value
224 */
225 public final void setReturnType( String returnType )
226 {
227 _returnType.setType( returnType );
228 }
229
230 /***
231 * Sets the ReturnDimension attribute of the SourceMethod object
232 *
233 * @param d The new ReturnDimension value
234 */
235 public final void setReturnDimension( int d )
236 {
237 _returnType.setDimension( d );
238 }
239
240 /***
241 * Two methods are equal if they have the same return type, name and signature,
242 * regardless of the enclosing class and modifiers. Methods are compared for
243 * equality when calling XClass.getMethods(true)
244 *
245 * @param o
246 * @return
247 */
248 public boolean equals( Object o )
249 {
250 MethodImpl other = ( MethodImpl ) o;
251
252 return getMethodNameWithSignatureWithoutModifiers().equals( other.getMethodNameWithSignatureWithoutModifiers() );
253 }
254
255 public int hashCode()
256 {
257 return toString( false ).hashCode();
258 }
259
260 public String toString()
261 {
262 return getMethodNameWithSignatureAndModifiers() + " [" + getContainingClass().getQualifiedName() + "]";
263 }
264
265 protected String buildStringId()
266 {
267 return getMethodNameWithSignatureWithoutModifiers();
268 }
269
270 private String getMethodNameWithSignatureAndModifiers()
271 {
272 if( methodNameWithSignatureAndModifiers == null )
273 {
274 methodNameWithSignatureAndModifiers = toString( true );
275 }
276 return methodNameWithSignatureAndModifiers;
277 }
278
279 private String getMethodNameWithSignatureWithoutModifiers()
280 {
281 if( methodNameWithSignatureWithoutModifiers == null )
282 {
283 methodNameWithSignatureWithoutModifiers = toString( false );
284 }
285 return methodNameWithSignatureWithoutModifiers;
286 }
287
288 /***
289 * Builds a String uniquely describing this method
290 *
291 * @param modifiers
292 * @return a String uniquely describing this method
293 */
294 private String toString( boolean modifiers )
295 {
296 StringBuffer sb;
297
298 if( modifiers )
299 {
300 sb = new StringBuffer( getModifiers() );
301 if( sb.length() > 0 )
302 {
303 sb.append( ' ' );
304 }
305 }
306 else
307 {
308 sb = new StringBuffer();
309 }
310 sb.append( getReturnType().getType().getQualifiedName() );
311 sb.append( getReturnType().getDimensionAsString() );
312 sb.append( ' ' );
313 sb.append( getNameWithSignature( false ) );
314 return sb.toString();
315 }
316
317 }