KickJava   Java API By Example, From Geeks To Geeks.

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


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.util.ArrayList JavaDoc;
22 import java.util.Iterator JavaDoc;
23 import org.netbeans.jmi.javamodel.*;
24 import org.netbeans.lib.java.parser.ASTree;
25 import org.netbeans.lib.java.parser.Token;
26 import org.netbeans.mdr.handlers.AttrListWrapper;
27 import org.netbeans.mdr.storagemodel.StorableObject;
28 import org.netbeans.modules.javacore.internalapi.JavaModelUtil;
29 import org.netbeans.modules.javacore.parser.ASTProvider;
30 import org.netbeans.modules.javacore.parser.ElementInfo;
31 import org.netbeans.modules.javacore.parser.ParameterInfo;
32 import org.netbeans.modules.javacore.parser.TypeRef;
33 import org.openide.util.Utilities;
34 import java.util.List JavaDoc;
35 import org.netbeans.modules.javacore.parser.ArrayRef;
36
37 /**
38  * Implementation of Parameter object instance interface.
39  *
40  * @author Vladimir Hudec
41  * @author Pavel Flaska
42  */

43 public abstract class ParameterImpl extends SemiPersistentElement implements Parameter {
44     private static final ElementInfo DEFAULT_INFO = new ParameterInfo(null, ParameterInfo.PARAMETER_TYPE, null, false, null, false, null);
45     
46     private TypeReference typeName = null;
47     private int dimCount = 0;
48     private LightAttrList annotations = null;
49     private boolean internalSetDim = false;
50     
51     protected ParameterImpl(StorableObject s) {
52         super(s);
53     }
54     
55     /** Should be overriden by elements that have persistent attributes.
56      * They should implement this method to compare values in newly passed AST info with
57      * values of the persistent attributes and if the values do not match, they should be
58      * updated and proper events should be fired.
59      */

60     protected void matchPersistent(ElementInfo info) {
61         super.matchPersistent(info);
62         ParameterInfo pinfo = (ParameterInfo) info;
63         
64         if (pinfo.isFinal != isFinal()) {
65             setFinal(pinfo.isFinal);
66         }
67         if (pinfo.isVarArg != isVarArg()) {
68             setVarArg(pinfo.isVarArg);
69         }
70         
71         if (!isPersisted()) {
72             setPersisted(true);
73             persist();
74             setTypeRef(pinfo.type);
75             persistChildren(getPersistentList("annotations", super_getAnnotations()), pinfo.annotations);
76         } else {
77             if (!Utilities.compareObjects(pinfo.type, getTypeRef())) {
78                 setType(resolveType(pinfo.type));
79             }
80             processMembers(getAnnotations(), pinfo.annotations);
81         }
82     }
83     
84     protected ElementInfo getDefaultInfo() {
85         return DEFAULT_INFO;
86     }
87     
88     protected void resetChildren() {
89         super.resetChildren();
90         if (typeName != null) {
91             TypeReference temp = typeName;
92             changeChild(typeName, null);
93             typeName = null;
94             temp.refDelete();
95         }
96         if (annotations != null) {
97             annotations.setInnerList(getPersistentList("annotations", super_getAnnotations())); // NOI18N
98
}
99         childrenInited = false;
100     }
101     
102     /**
103      * Returns the value of reference type.
104      * @return Value of reference type.
105      */

106     public Type getType() {
107         checkUpToDate();
108         return resolveType(getTypeRef());
109     }
110
111     private void fireTypeNameChange(TypeReference typeReference) {
112         Object JavaDoc oldValue = null;
113         Object JavaDoc newValue = null;
114         if (childrenInited && !disableChanges) {
115             oldValue = getTypeName();
116             newValue = typeReference;
117         }
118         fireAttrChange("typeName", oldValue, newValue); // NOI18N
119
}
120     
121     /**
122      * Sets the value of reference type. See {@link #getType} for description
123      * on the reference.
124      * @param newValue New value to be set.
125      */

126     public void setType(Type newValue) {
127         TypeRef tr = typeToTypeRef(newValue);
128         TypeReference typeReference = null;
129         if (!disableChanges) {
130             updateDimCount(tr);
131             typeReference = (TypeReference) typeRefToTypeReference(tr, getDimCount());
132         }
133         fireTypeNameChange(typeReference);
134         _setTypeName(typeReference, tr);
135     }
136     
137     private void updateDimCount(TypeRef tr) {
138         int dimCount = getDimCount();
139         if (tr instanceof ArrayRef) {
140             if (((ArrayRef) tr).dimCount < dimCount) {
141                 _setDimCount(((ArrayRef) tr).dimCount);
142             }
143         } else if (dimCount > 0) {
144             _setDimCount(0);
145         }
146     }
147     
148     private void _setDimCount(int dimCount) {
149         internalSetDim = true;
150         try {
151             setDimCount(dimCount);
152         } finally {
153             internalSetDim = false;
154         }
155     }
156     
157     public TypeReference getTypeName() {
158         checkUpToDate();
159         if (!childrenInited) {
160             initChildren();
161         }
162         return typeName;
163     }
164
165     public void setTypeName(TypeReference typeName) {
166         _setTypeName(typeName, typeReferenceToTypeRef(typeName, getDimCount()));
167     }
168     
169     private void _setTypeName(TypeReference typeName, TypeRef typeRef) {
170         if (!disableChanges) {
171             objectChanged(CHANGED_TYPE);
172             changeChild(getTypeName(), typeName);
173             this.typeName = typeName;
174         }
175         setTypeRef(typeRef);
176     }
177     
178     /**
179      * Set the value of isFinal attribute. See {@link #isFinal} for description
180      * on the attribute.
181      *
182      * @param newValue New value to be set.
183      */

184     public void setFinal(boolean newValue) {
185         objectChanged(CHANGED_IS_FINAL);
186         super_setFinal(newValue);
187     }
188     
189     public List JavaDoc/*<org.netbeans.jmi.javamodel.Annotation>*/ getAnnotations() {
190         checkUpToDate();
191         if (annotations == null) {
192             annotations = createChildrenList("annotations", (AttrListWrapper) super_getAnnotations(), null, CHANGED_ANNOTATION);
193         }
194         return annotations;
195     }
196
197     protected abstract void super_setFinal(boolean newValue);
198
199     /**
200      * Set the value of isVarArg attribute. See {@link #isVarArg} for description
201      * on the attribute.
202      *
203      * @param newValue New value to be set.
204      */

205     public void setVarArg(boolean newValue) {
206         objectChanged(CHANGED_IS_VARARG);
207         super_setVarArg(newValue);
208     }
209     
210     protected abstract void super_setVarArg(boolean newValue);
211     
212     protected ASTree getPartTree(ElementPartKind part) {
213         if (ElementPartKindEnum.NAME.equals(part)) {
214             return getASTree().getSubTrees()[VARIABLE_DECLARATOR_ID].getSubTrees()[0];
215         }
216         throw new IllegalArgumentException JavaDoc("Invalid part for this element: " + part); // NOI18N
217
}
218     
219     public String JavaDoc getSourceText() {
220         String JavaDoc origElem;
221         if ((origElem = checkChange()) != null)
222             return origElem;
223         
224         StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
225         for (Iterator JavaDoc annIt = getAnnotations().iterator(); annIt.hasNext(); ) {
226             AnnotationImpl ann = (AnnotationImpl) annIt.next();
227             buf.append(ann.getSourceText()).append(' ');
228         }
229         if (isFinal())
230             buf.append("final "); // NOI18N
231
buf.append(((MetadataElement) getTypeName()).getSourceText());
232          if (isVarArg())
233             buf.append("..."); // NOI18N
234
buf.append(' ');
235         buf.append(getName());
236         appendDims(buf, getDimCount());
237         return buf.toString();
238     }
239     
240     protected void diffModifiers(List JavaDoc diffList, ASTree nextNode, ASTProvider parser) {
241         String JavaDoc text = "";
242         for (Iterator JavaDoc annIt = getAnnotations().iterator(); annIt.hasNext(); ) {
243             AnnotationImpl ann = (AnnotationImpl) annIt.next();
244             text += ann.getSourceText();
245             if (annIt.hasNext()) {
246                 text += ' ';
247             }
248         }
249         if (isFinal()) {
250             if (text.length() > 0) {
251                 text += ' ';
252             }
253             text += "final"; // NOI18N
254
}
255         int nextToken = nextNode.getFirstToken();
256         int startOffset, endOffset;
257         int startToken;
258         endOffset = parser.getToken(nextToken).getStartOffset();
259         ASTree modifiers = getASTree().getSubTrees()[FINAL_OPT];
260         if (modifiers != null) {
261             startToken = modifiers.getFirstToken();
262             startOffset = parser.getToken(startToken).getStartOffset();
263             if (text.length() > 0) {
264                 int endToken = modifiers.getLastToken();
265                 endOffset = parser.getToken(endToken).getEndOffset();
266             }
267         } else {
268             startOffset = endOffset;
269             text += ' ';
270         }
271         diffList.add(new DiffElement(startOffset, endOffset, text));
272     }
273     
274     public void getDiff(List JavaDoc diffList) {
275         // parameter exist
276
ASTProvider parser = getParser();
277         ASTree[] children = getASTree().getSubTrees();
278         if (isChanged(CHANGED_IS_FINAL) || isChanged(CHANGED_ANNOTATION)) {
279             diffModifiers(diffList, children[TYPE], parser);
280         } else if (children[FINAL_OPT] != null) {
281             ParameterInfo astInfo = (ParameterInfo) getElementInfo();
282             getCollectionDiff(diffList, parser, CHANGED_ANNOTATION, astInfo.annotations, getAnnotations(), parser.getToken(children[FINAL_OPT].getLastToken()).getEndOffset(), " "); // NOI18N
283
}
284         // type print
285
getChildDiff(diffList, parser, children[TYPE], (MetadataElement) getTypeName(), CHANGED_TYPE);
286         if (isChanged(CHANGED_IS_VARARG)) {
287             replaceNode(diffList, parser, children[VARARG_OPT], isVarArg() ? "..." : "", parser.getToken(children[TYPE].getLastToken()).getEndOffset(), ""); // NOI18N
288
}
289         // name print
290
ASTree[] varDeclaratorIdChildren = children[VARIABLE_DECLARATOR_ID].getSubTrees();
291         if (isChanged(CHANGED_NAME)) {
292             Token identifier = (Token) varDeclaratorIdChildren[0]; // identifier
293
int startOffset = identifier.getStartOffset();
294             int endOffset = identifier.getEndOffset();
295             diffList.add(new DiffElement(startOffset, endOffset, getName()));
296         }
297         if (isChanged(CHANGED_DIM_COUNT)) {
298             replaceNode(diffList, parser, varDeclaratorIdChildren[1], appendDims(new StringBuffer JavaDoc(), getDimCount()).toString(), getEndOffset(getParser(), varDeclaratorIdChildren[0]), "");
299         }
300     }
301     
302     private static final int FINAL_OPT = 0;
303     private static final int TYPE = 1;
304     private static final int VARARG_OPT = 2;
305     private static final int VARIABLE_DECLARATOR_ID = 3;
306
307     public void replaceChild(Element oldElement, Element newElement) {
308         if (childrenInited) {
309             if (oldElement.equals(typeName)) {
310                 setTypeName((TypeReference) newElement);
311                 return;
312             }
313             if (replaceObject(annotations, oldElement, newElement)) return;
314         }
315         super.replaceChild(oldElement, newElement);
316     }
317
318     public int getDimCount() {
319         if (isChanged(CHANGED_DIM_COUNT)) {
320             return dimCount;
321         } else {
322             ASTree tree = getASTree();
323             if (tree != null) {
324                 ASTree dims = tree.getSubTrees()[VARIABLE_DECLARATOR_ID].getSubTrees()[1];
325                 if (dims != null) {
326                     return (dims.getLastToken() - dims.getFirstToken() + 1) / 2;
327                 }
328             }
329             return 0;
330         }
331     }
332     
333     public void setDimCount(int dimCount) {
334         objectChanged(CHANGED_DIM_COUNT);
335         this.dimCount = dimCount;
336         if (!internalSetDim) {
337             // TODO: fire type change event
338
setTypeRef(typeReferenceToTypeRef(getTypeName(), dimCount));
339         }
340     }
341     
342     public List JavaDoc getChildren() {
343         List JavaDoc list = new ArrayList JavaDoc(1);
344         list.addAll(getAnnotations());
345         addIfNotNull(list, getTypeName());
346         return list;
347     }
348     
349     protected void initChildren() {
350         childrenInited = false;
351         ParameterInfo info = (ParameterInfo) getElementInfo();
352         ASTree tree = info.getTypeAST(this);
353         typeName = (TypeReference) initOrCreate(typeName, tree);
354         annotations = createChildrenList(annotations, "annotations", (AttrListWrapper)super_getAnnotations(),// NOI18N
355
((ParameterInfo) getElementInfo()).annotations, CHANGED_ANNOTATION);
356         childrenInited = true;
357     }
358     
359     protected void setData(List JavaDoc annotations, TypeReference typeName, int dimCount) {
360         changeChild(null, typeName);
361         this.typeName = typeName;
362         this.annotations = createChildrenList("annotations", (AttrListWrapper)super_getAnnotations(), annotations, CHANGED_ANNOTATION); // NOI18N
363
this.dimCount = dimCount;
364         setTypeRef(typeReferenceToTypeRef(typeName, dimCount));
365         childrenInited = true;
366     }
367     
368     protected void setTypeRef(TypeRef type) {
369         _getDelegate().setSlot1(type);
370     }
371     
372     public TypeRef getTypeRef() {
373         return (TypeRef) _getDelegate().getSlot1();
374     }
375     
376     public boolean isPersisted() {
377         return _getDelegate().getSlot2() != null;
378     }
379     
380     public void setPersisted(boolean persisted) {
381         _getDelegate().setSlot2(persisted ? "" : null);
382     }
383     
384     void childChanged(MetadataElement mpi) {
385         super.childChanged(mpi);
386         if (childrenInited) {
387             if (mpi == typeName) {
388                 setTypeName((TypeReference) mpi);
389             }
390         }
391     }
392     
393     public Element duplicate(JavaModelPackage targetExtent) {
394         return targetExtent.getParameter().createParameter(
395                 getName(),
396                 duplicateList(getAnnotations(), targetExtent),
397                 isFinal(),
398                 (TypeReference) duplicateElement(getTypeName(), targetExtent),
399                 getDimCount(),
400                 isVarArg()
401             );
402     }
403
404     public void fixImports(Element scope, Element original) {
405         Parameter par=(Parameter)original;
406
407         fixImports(scope,getAnnotations(),par.getAnnotations());
408         setTypeName(JavaModelUtil.resolveImportsForType(scope,par.getType()));
409         setDimCount(0);
410     }
411
412     protected abstract List JavaDoc super_getAnnotations();
413     
414     protected void _delete() {
415         // --- delete components -------------------------------------------
416
// delete all annotations (if initialized)
417
deleteChildren("annotations", (AttrListWrapper) super_getAnnotations());
418         if (childrenInited) {
419             deleteChild(typeName);
420         }
421         // --- delete links -----------------------------------------------
422
// no links to delete
423
// [TODO] should Throws association be notified?
424
// --- call super -------------------------------------------------
425
super._delete();
426     }
427 }
428
Popular Tags