KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > javacore > jmiimpl > javamodel > MethodImpl


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19 package org.netbeans.modules.javacore.jmiimpl.javamodel;
20
21 import java.lang.reflect.Modifier JavaDoc;
22 import java.util.*;
23 import org.netbeans.jmi.javamodel.*;
24 import org.netbeans.lib.java.parser.ASTree;
25 import org.netbeans.mdr.storagemodel.StorableObject;
26 import org.netbeans.modules.javacore.internalapi.JavaModelUtil;
27 import org.netbeans.modules.javacore.parser.ASTProvider;
28 import org.netbeans.modules.javacore.parser.ElementInfo;
29 import org.netbeans.modules.javacore.parser.MethodInfo;
30 import org.netbeans.modules.javacore.parser.TypeRef;
31
32 /**
33  * Implementation of Method object instance interface.
34  *
35  * @author Martin Matula
36  * @author Pavel Flaska
37  */

38 public abstract class MethodImpl extends CallableFeatureImpl implements Method {
39     private static final ElementInfo DEFAULT_INFO = new MethodInfo(null, MethodInfo.METHOD_TYPE, null, 0, null, null, null, null, null);
40
41     private TypeReference typeName;
42
43     /** Creates a new instance of MethodImpl */
44     public MethodImpl(StorableObject s) {
45         super(s);
46     }
47
48     public String JavaDoc toString() {
49         return "method " + getName(); // NOI18N
50
}
51
52     protected ElementInfo getDefaultInfo() {
53         return DEFAULT_INFO;
54     }
55
56     public TypeReference getTypeName() {
57         checkUpToDate();
58         if (!elementsInited) {
59             initASTElements();
60         }
61         return typeName;
62     }
63
64     public void setTypeName(TypeReference typeName) {
65         _setTypeName(typeName, typeReferenceToTypeRef(typeName, 0));
66     }
67     
68     private void _setTypeName(TypeReference typeName, TypeRef typeRef) {
69         if (!disableChanges) {
70             objectChanged(CHANGED_TYPE);
71             changeChild(getTypeName(), typeName);
72             this.typeName = typeName;
73         }
74         setTypeRef(typeRef);
75     }
76     
77     private void fireTypeNameChange(TypeReference typeReference) {
78         Object JavaDoc oldValue = null;
79         Object JavaDoc newValue = null;
80         if (elementsInited && !disableChanges) {
81             oldValue = getTypeName();
82             newValue = typeReference;
83         }
84         fireAttrChange("typeName", oldValue, newValue); // NOI18N
85
}
86     
87     /**
88      * Returns the value of reference type.
89      * @return Value of reference type.
90      */

91     public Type getType() {
92         checkUpToDate();
93         return resolveType(getTypeRef());
94     }
95
96     /**
97      * Sets the value of reference type. See {@link #getType} for description
98      * on the reference.
99      * @param newValue New value to be set.
100      */

101     public void setType(Type newValue) {
102         TypeRef tr = typeToTypeRef(newValue);
103         TypeReference typeReference = (TypeReference) typeRefToTypeReference(tr, 0);
104         fireTypeNameChange(typeReference);
105         _setTypeName(typeReference, tr);
106     }
107
108     protected void initASTElements() {
109         elementsInited = false;
110         super.initASTElements();
111         ElementInfo info = getElementInfo();
112         ASTree tree = info.getTypeAST(this);
113         typeName = (TypeReference) initOrCreate(typeName, tree);
114         elementsInited = true;
115     }
116
117     protected void setData(List annotations, java.lang.String JavaDoc javadocText, JavaDoc javadoc, StatementBlock body, java.lang.String JavaDoc bodyText, List typeArguments, List parameters, List exceptionNames, TypeReference typeName, int dimCount) {
118         super.setData(annotations, javadocText, javadoc, body, bodyText, typeArguments, parameters, exceptionNames);
119         changeChild(null, typeName);
120         this.typeName = typeName;
121         setTypeRef(typeReferenceToTypeRef(typeName, 0));
122     }
123
124     protected void resetASTElements() {
125         if (elementsInited) {
126             if (typeName != null) {
127                 TypeReference temp = typeName;
128                 changeChild(typeName, null);
129                 typeName = null;
130                 temp.refDelete();
131             }
132             super.resetASTElements();
133         }
134     }
135
136     public void replaceChild(Element oldElement, Element newElement) {
137         if (elementsInited) {
138             if (oldElement.equals(typeName)) {
139                 setTypeName((TypeReference) newElement);
140                 return;
141             }
142         }
143         super.replaceChild(oldElement, newElement);
144     }
145
146     public List getChildren() {
147         List list = new ArrayList();
148         list.addAll(getAnnotations());
149         addIfNotNull(list, getTypeName());
150         list.addAll(super.getChildren());
151         return list;
152     }
153
154     public void fixImports(Element scope, Element original) {
155         setTypeName(JavaModelUtil.resolveImportsForType(scope,((Method)original).getType()));
156         setDimCount(0);
157         super.fixImports(scope,original);
158     }
159
160     protected List getInitedChildren() {
161         List list = super.getInitedChildren();
162         if (elementsInited) {
163             addIfNotNull(list, typeName);
164         }
165         return list;
166     }
167
168     // .........................................................................
169
// printing and formatting fuctionality
170
// .........................................................................
171

172     /**
173      * Implementation of abstract method from CallableFeatureImpl. Appends
174      * to buffer return type and method name separated by space.
175      *
176      * @param buf buffer to append to
177      */

178     void generateTypeAndName(StringBuffer JavaDoc buf) {
179         MetadataElement melem = (MetadataElement)getTypeName();
180         if (melem != null) {
181             buf.append(melem.getSourceText());
182         } else {
183             buf.append(getType().getName());
184         }
185         buf.append(' ');
186         buf.append(getName());
187         formatElementPart(CALLABLE_IDENTIFIER, buf);
188     }
189
190     /**
191      * Returns source code representation of this object.
192      *
193      * @return source code representation of the object.
194      */

195     String JavaDoc getRawText() {
196         if (!elementsInited) {
197             initASTElements();
198         }
199         StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
200         generateHeader(buf);
201         int modifiers = getSourceModifiers();
202         boolean parentAbstract = false;
203         if (refImmediateComposite() instanceof JavaClass) {
204             JavaClass jc = (JavaClass) refImmediateComposite();
205             parentAbstract = jc.isInterface();
206         }
207         // for abstract, native methods and methods in interfaces put semicolon only
208
if ((!parentAbstract && (modifiers & Modifier.ABSTRACT) != Modifier.ABSTRACT) &&
209             ((modifiers & Modifier.NATIVE) != Modifier.NATIVE))
210         {
211             generateBody(buf);
212         }
213         else
214             buf.append(';');
215         return buf.toString();
216     }
217     
218     protected void _delete() {
219         if (elementsInited) {
220             deleteChild(typeName);
221         }
222         super._delete();
223     }
224     
225     public void getDiff(List diffList) {
226         MethodInfo astInfo = (MethodInfo) getElementInfo();
227         ASTProvider parser = getParser();
228         ASTree tree = getASTree();
229         ASTree[] children = tree.getSubTrees();
230
231         // javadoc print
232
replaceJavaDoc(diffList);
233         // modifier print
234
ASTree type = children[2];
235         if (isChanged(CHANGED_MODIFIERS) || isChanged(CHANGED_ANNOTATION)) {
236             diffModifiers(diffList, type == null ? children[3] : type, parser);
237         } else if (children[0] != null) {
238             getCollectionDiff(diffList, parser, CHANGED_ANNOTATION, astInfo.annotations, getAnnotations(), parser.getToken(children[0].getLastToken()).getEndOffset(), "\n"); // NOI18N
239
}
240         getTypeParamsDiff(diffList);
241         // type
242
getChildDiff(diffList, parser, type, (MetadataElement) getTypeName(), CHANGED_TYPE);
243         // name
244
ASTree declarator = tree.getSubTrees()[3];
245         if (isChanged(CHANGED_NAME)) {
246             String JavaDoc newName = getName();
247             replaceNode(diffList, parser, declarator.getSubTrees()[0], newName, 0, null);
248         }
249         // parameters
250
String JavaDoc comma = formatElementPart(COMMA);
251         int endOffset = parser.getToken(declarator.getLastToken()).getStartOffset();
252         getCollectionDiff(diffList, parser, CHANGED_PARAMETERS,
253             astInfo.parameters, getParameters(), endOffset, comma);
254         // exceptions
255
int startOffset = parser.getToken(declarator.getLastToken()).getEndOffset();
256         getCollectionDiff(diffList, parser, CHANGED_THROWS, tree.getSubTrees()[4],
257                 getExceptionNames(), startOffset, comma, formatElementPart(THROWS_KEYWORD));
258         // body print
259
createBodyDiffs(diffList);
260     }
261
262     /**
263      */

264     protected ASTree getPartTree(ElementPartKind part) {
265         ASTree[] children = getASTree().getSubTrees();
266         if (ElementPartKindEnum.NAME.equals(part))
267             return children[3].getSubTrees()[0];
268
269         throw new IllegalArgumentException JavaDoc("Invalid part for this element: " + part); // NOI18N
270
}
271
272     /**
273      */

274     protected ASTree getPartStartTree(ElementPartKind part) {
275         if (ElementPartKindEnum.HEADER.equals(part)) {
276             return getASTree();
277         }
278         return super.getPartStartTree(part);
279     }
280
281     public Collection getReferences() {
282         return findDependencies(true, false, false);
283     }
284     
285     public boolean signatureEquals(Method m) {
286         return signatureEquals(this, m);
287     }
288     
289     static boolean signatureEquals(Method m1, Method m2) {
290         if (!m1.getName().equals(m2.getName()))
291             return false;
292         
293         Parameter[] params1 = (Parameter[]) m1.getParameters().toArray(new Parameter[0]);
294         Parameter[] params2 = (Parameter[]) m2.getParameters().toArray(new Parameter[0]);
295         if (params1.length != params2.length)
296             return false;
297         
298         for (int i = 0; i < params2.length; i++) {
299             Type t1 = TypeClassImpl.getRawType(params1[i].getType());
300             Type t2 = TypeClassImpl.getRawType(params2[i].getType());
301             if (!t1.getName().equals(t2.getName())) {
302                 return false;
303             }
304         }
305         return true;
306     }
307     
308     public Collection getOverriddenMethods() {
309         Collection result = new LinkedHashSet(2);
310         
311         ClassDefinition declaringClass = this.getDeclaringClass();
312         
313         List params = new ArrayList();
314         for (Iterator i = this.getParameters().iterator(); i.hasNext(); params.add(((Parameter)i.next()).getType()));
315         
316         Iterator i = declaringClass.getInterfaces().iterator();
317         while (i.hasNext()) {
318             JavaClass jc = (JavaClass) i.next();
319             Method m = jc.getMethod(this.getName(), params, true);
320             if (m!=null) {
321                 if (m instanceof ParameterizedTypeImpl.Wrapper) {
322                     m = (Method) ((ParameterizedTypeImpl.Wrapper) m).getWrappedObject();
323                 }
324                 result.addAll(((MethodImpl) m).getOverriddenMethods());
325                 result.add(m);
326             }
327         }
328
329         ClassDefinition parent = declaringClass.getSuperClass();
330         if (parent != null) {
331             Method m = parent.getMethod(this.getName(), params, true);
332             if (m!=null) {
333                 if (m instanceof ParameterizedTypeImpl.Wrapper) {
334                     m = (Method) ((ParameterizedTypeImpl.Wrapper) m).getWrappedObject();
335                 }
336                 result.addAll(((MethodImpl) m).getOverriddenMethods());
337                 result.add(m);
338             }
339         }
340         return result;
341     }
342     
343     void childChanged(MetadataElement mpi) {
344         super.childChanged(mpi);
345         if (elementsInited) {
346             if (mpi == typeName) {
347                 setTypeName((TypeReference) mpi);
348             }
349         }
350     }
351
352     public Element duplicate(JavaModelPackage targetExtent) {
353         StatementBlock body;
354         String JavaDoc bodyText;
355         
356         if (isChanged(CHANGED_BODY) && this.bodyText != null) {
357             body = null;
358             bodyText = this.bodyText;
359         } else {
360             body = (StatementBlock) duplicateElement(getBody(), targetExtent);
361             bodyText = null;
362         }
363         
364         return targetExtent.getMethod().createMethod(
365                 getName(),
366                 duplicateList(getAnnotations(), targetExtent),
367                 getModifiers(),
368                 null,
369                 (JavaDoc) duplicateElement(getJavadoc(), targetExtent),
370                 body,
371                 bodyText,
372                 duplicateList(getTypeParameters(), targetExtent),
373                 duplicateList(getParameters(), targetExtent),
374                 duplicateList(getExceptionNames(), targetExtent),
375                 (TypeReference) duplicateElement(getTypeName(), targetExtent),
376                 getDimCount()
377             );
378     }
379
380 }
381
Popular Tags