KickJava   Java API By Example, From Geeks To Geeks.

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


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.List JavaDoc;
23 import javax.jmi.reflect.ConstraintViolationException;
24 import javax.jmi.reflect.RefFeatured;
25 import org.netbeans.jmi.javamodel.ClassDefinition;
26 import org.netbeans.jmi.javamodel.Element;
27 import org.netbeans.jmi.javamodel.ElementPartKind;
28 import org.netbeans.jmi.javamodel.ElementPartKindEnum;
29 import org.netbeans.jmi.javamodel.EnumConstant;
30 import org.netbeans.jmi.javamodel.InitialValue;
31 import org.netbeans.jmi.javamodel.JavaDoc;
32 import org.netbeans.jmi.javamodel.JavaModelPackage;
33 import org.netbeans.jmi.javamodel.Resource;
34 import org.netbeans.jmi.javamodel.Type;
35 import org.netbeans.jmi.javamodel.TypeReference;
36 import org.netbeans.lib.java.parser.ASTree;
37 import org.netbeans.lib.java.parser.ParserTokens;
38 import org.netbeans.lib.java.parser.Token;
39 import org.netbeans.mdr.storagemodel.StorableObject;
40 import org.netbeans.modules.javacore.ClassIndex;
41 import org.netbeans.modules.javacore.JMManager;
42 import org.netbeans.modules.javacore.internalapi.JavaModelUtil;
43 import org.netbeans.modules.javacore.parser.ASTProvider;
44 import org.netbeans.modules.javacore.parser.ClassInfo;
45 import org.netbeans.modules.javacore.parser.ElementInfo;
46 import org.netbeans.modules.javacore.parser.FeatureInfo;
47
48
49 /** Implements object representing enum constant.
50  *
51  * @author Martin Matula
52  */

53 public abstract class EnumConstantImpl extends FeatureImpl implements EnumConstant {
54     private static final ElementInfo DEFAULT_INFO = new FeatureInfo(null, FeatureInfo.ENUM_CONSTANT_TYPE, null, 0, null);
55
56     RefFeatured parent; // used for hard-referencing parent
57

58     // attribute values
59
ClassDefinition body;
60     InitialValue initialValue;
61     String JavaDoc initialValueText;
62     
63     private boolean initValueInited = false;
64
65
66     /** Creates a new instance of EnumConstantImpl */
67     public EnumConstantImpl(StorableObject s) {
68         super(s);
69     }
70
71     protected ElementInfo getDefaultInfo() {
72         return DEFAULT_INFO;
73     }
74     
75     public void setModifiers(int modifiers) {
76         throw new ConstraintViolationException(null, null, "Cannot set modifiers of enum constant."); // NOI18N
77
}
78     
79     public int getModifiers() {
80         return Modifier.FINAL | Modifier.PUBLIC | Modifier.STATIC;
81     }
82     
83     public boolean isFinal() {
84         return true;
85     }
86     
87     public void setFinal(boolean isFinal) {
88         setModifiers(0);
89     }
90
91     /**
92      * Returns the value of reference type.
93      * @return Value of reference type.
94      */

95     public Type getType() {
96         return (Type) refImmediateComposite();
97     }
98
99     /**
100      * Sets the value of reference type. See {@link #getType} for description
101      * on the reference.
102      * @param newValue New value to be set.
103      */

104     public void setType(Type newValue) {
105         throw new ConstraintViolationException(null, null, "Cannot change enum constant type."); // NOI18N
106
}
107
108     /**
109      * Find referenced resources using ClassIndex.findResourcesForIdentifier().
110      * Modifiers are considered to reduce number of resources
111      */

112     Resource[] findReferencedResources() {
113         return ClassIndex.findResourcesForIdentifier(getName());
114     }
115     
116     protected List JavaDoc getInitedChildren() {
117         List JavaDoc list = super.getInitedChildren();
118         if (childrenInited) {
119             if (initValueInited) {
120                 if (!isChanged(CHANGED_INITIAL_VALUE) || initialValueText == null) {
121                     addIfNotNull(list, initialValue);
122                 }
123                 addIfNotNull(list, body);
124             }
125         }
126         return list;
127     }
128
129     public List JavaDoc getChildren() {
130         List JavaDoc list = super.getChildren();
131         if (isChanged(CHANGED_INITIAL_VALUE) && initialValueText != null) {
132             throw new IllegalStateException JavaDoc("Cannot get children when the initial value text has been changed."); // NOI18N
133
}
134         addIfNotNull(list, getInitialValue());
135         addIfNotNull(list, getBody());
136         return list;
137     }
138
139     protected void initChildren() {
140         childrenInited = false;
141         super.initChildren();
142         childrenInited = true;
143         if (initValueInited) {
144             JMManager.getTransactionMutex().addBFeatureToInitQueue(this);
145         }
146     }
147     
148     public void initInitValue() {
149         initValueInited = false;
150         if (!childrenInited) {
151             initChildren();
152         }
153         FeatureInfo initValInfo = (FeatureInfo) getElementInfo();
154         if (initValInfo != null) {
155             initValInfo.doAttribution(this);
156             ASTree tree = getASTree();
157             if (tree != null) {
158                 ASTree[] parts = tree.getSubTrees();
159                 initialValue = (InitialValue) initOrCreate(initialValue, parts[PARAMETERS]);
160                 if (parts[2] == null) {
161                     body = null;
162                 } else {
163                     ClassInfo constantInfo = (ClassInfo) getParser().getSemanticInfo(parts[CLASS_DEFINITION], this);
164                     // do we have already body of constant?
165
if (body != null) {
166                         // body was removed, remove it from model
167
if (constantInfo == null) {
168                             changeChild(body, null);
169                             body.refDelete();
170                             body = null;
171                         } else {
172                             // replace old constant body with the new one
173
((ClassDefinitionImpl) body).setElementInfo(constantInfo);
174                         }
175                     } else if (constantInfo != null) {
176                         // create new body - ClassDefinition
177
SemiPersistentElement s = (SemiPersistentElement) JavaModelUtil.getDeclaringFeature(this);
178                         body = (ClassDefinition) s.createElement(constantInfo);
179                         changeChild(null, body);
180                     }
181                 }
182             }
183         }
184         initValueInited = true;
185     }
186
187     private static final int NAME = 0;
188     private static final int PARAMETERS = 1;
189     private static final int CLASS_DEFINITION = 2;
190
191     protected void matchModifiers(ElementInfo info) {
192         // do not match modifiers
193
}
194     
195     /** The method has to make sure that the AST infos of children are also updated.
196      */

197     protected void matchElementInfo(ElementInfo newInfo) {
198         super.matchElementInfo(newInfo);
199         resetInitValue();
200     }
201     
202     protected void resetChildren() {
203         super.resetChildren();
204         resetInitValue();
205         childrenInited = false;
206     }
207
208     private void resetInitValue() {
209         if (initialValue != null) {
210             InitialValue temp = initialValue;
211             initialValue = null;
212             changeChild(temp, null);
213             temp.refDelete();
214         }
215
216         if (body != null) {
217             ClassDefinition temp = body;
218             body = null;
219             changeChild(temp, null);
220             temp.refDelete();
221         }
222         initValueInited = false;
223     }
224
225     public void replaceChild(Element oldElement, Element newElement) {
226         if (initValueInited) {
227             if (oldElement.equals(initialValue)) {
228                 setInitialValue((InitialValue) newElement);
229                 return;
230             }
231             if (oldElement.equals(body)) {
232                 setBody((ClassDefinition) newElement);
233                 return;
234             }
235         }
236         super.replaceChild(oldElement, newElement);
237     }
238
239     protected void setData(List JavaDoc annotations, String JavaDoc javadocText, JavaDoc javadoc, InitialValue initialValue, String JavaDoc initialValueText, ClassDefinition body) {
240         super.setData(annotations, javadocText, javadoc);
241         if (initialValueText == null) {
242             changeChild(null, initialValue);
243             this.initialValue = initialValue;
244         } else {
245             if (initialValue != null) {
246                 throw new ConstraintViolationException(null, null, "Cannot set both initialValue and initialValueText."); // NOI18N
247
}
248             this.initialValueText = initialValueText;
249         }
250         changeChild(null, body);
251         this.body = body;
252         initValueInited = true;
253         childrenInited = true;
254     }
255
256     String JavaDoc getRawText() {
257         // we have element which is new or changed and moved.
258
StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
259         generateNewJavaDoc(buf);
260         buf.append(getName());
261         if (initialValueText != null) {
262             buf.append('(').append(initialValueText).append(')');
263         } else if (initialValue != null) {
264             buf.append('(').append(((MetadataElement) initialValue).getSourceText()).append(')');
265         }
266         if (body != null) {
267             buf.append(' ').append(((MetadataElement) body).getSourceText());
268         }
269         return buf.toString();
270     }
271
272     public void getDiff(List JavaDoc diffList) {
273         // element was present in the original source code
274
ASTProvider parser = getParser();
275         ASTree tree = getASTree();
276         ASTree[] children = tree.getSubTrees();
277
278         // javadoc print
279
replaceJavaDoc(diffList);
280         if (isChanged(CHANGED_NAME)) {
281             replaceNode(diffList, parser, children[NAME], getName(), 0, null);
282         }
283         if (isChanged(CHANGED_INITIAL_VALUE)) {
284             int startOffset = 0, endOffset = 0;
285             String JavaDoc text = initialValue == null ? initialValueText :
286                 ((MetadataElement) getInitialValue()).getSourceText();
287             Token lpar = parser.getToken(children[0].getLastToken() + 1);
288             // there was an initial value in original source code.
289
if (lpar.getType() == ParserTokens.L_PAR) {
290                 startOffset = lpar.getStartOffset();
291                 Token endToken = parser.getToken(children[1] != null ? children[1].getLastToken() + 1 : children[0].getLastToken() + 2);
292                 endOffset = endToken.getEndOffset();
293             }
294             // there was no initial value in original source
295
else {
296                 startOffset = parser.getToken(children[0].getLastToken()).getEndOffset();
297                 // we are inserting new text, offsets contain the same value
298
endOffset = startOffset;
299             }
300             diffList.add(new DiffElement(startOffset, endOffset, text == null ? "" : "(" + text + ")")); // NOI18N
301
} else if (initialValue != null && ((MetadataElement) initialValue).isChanged()) {
302             ((MetadataElement) initialValue).getDiff(diffList);
303         }
304         int startToken = children[PARAMETERS] == null ? children[0].getLastToken() : children[PARAMETERS].getLastToken() + 1;
305         getChildDiff(diffList, parser, children[CLASS_DEFINITION], (MetadataElement) getBody(), CHANGED_ENUM_CONST_BODY, parser.getToken(startToken).getEndOffset(), " "); // NOI18N
306
}
307
308     public void setBody(ClassDefinition newValue) {
309         if (!initValueInited) {
310             initInitValue();
311         }
312         objectChanged(CHANGED_ENUM_CONST_BODY);
313         changeChild(body, newValue);
314         body = newValue;
315     }
316
317     public ClassDefinition getBody() {
318         checkUpToDate();
319         if (!initValueInited) {
320             initInitValue();
321         }
322         return body;
323     }
324
325     public InitialValue getInitialValue() {
326         checkUpToDate();
327         if (isChanged(CHANGED_INITIAL_VALUE) && initialValueText != null) {
328             throw new ConstraintViolationException(null, null, "Cannot ask for initial value after the initial value text was changed."); // NOI18N
329
}
330         if (!initValueInited) {
331             initInitValue();
332         }
333         return initialValue;
334     }
335
336     public void setInitialValue(InitialValue newValue) {
337         if (!initValueInited) {
338             initInitValue();
339         }
340         changeChild(initialValue, newValue);
341         initialValue = newValue;
342         initialValueText = null;
343         objectChanged(CHANGED_INITIAL_VALUE);
344     }
345     
346     public java.lang.String JavaDoc getInitialValueText(){
347         checkUpToDate();
348         if (isChanged(CHANGED_INITIAL_VALUE)) {
349             if (initialValue != null) {
350                 throw new ConstraintViolationException(null, null, "Cannot ask for initial value text after the initial value was changed."); // NOI18N
351
}
352             return initialValueText;
353         } else {
354             return extractInitialValueText();
355         }
356     }
357
358     public void setInitialValueText(java.lang.String JavaDoc newValue){
359         if (!initValueInited) {
360             initInitValue();
361         }
362         if (initialValue != null) {
363             changeChild(initialValue, null);
364         }
365         objectChanged(CHANGED_INITIAL_VALUE);
366         initialValueText = newValue;
367         initialValue = null;
368     }
369
370     private String JavaDoc extractInitialValueText() {
371         ASTProvider parser = getParser();
372         if (parser == null)
373             return null;
374         ASTree initValue = getASTree().getSubTrees()[PARAMETERS];
375         if (initValue == null)
376             return null;
377         return parser.getText(initValue);
378     }
379
380     public int getDimCount() {
381         return 0;
382     }
383
384     public void setDimCount(int dimCount) {
385         throw new ConstraintViolationException(null, null, "Cannot change enum constant dimCount."); // NOI18N
386
}
387
388     public TypeReference getTypeName() {
389         return null;
390     }
391
392     public void setTypeName(TypeReference typeName) {
393         throw new ConstraintViolationException(null, null, "Cannot change enum constant type name."); // NOI18N
394
}
395     
396     public Element duplicate(JavaModelPackage targetExtent) {
397         InitialValue initVal;
398         String JavaDoc initValText;
399         
400         if (isChanged(CHANGED_INITIAL_VALUE) && this.initialValueText != null) {
401             initVal = null;
402             initValText = this.initialValueText;
403         } else {
404             initVal = (InitialValue) duplicateElement(getInitialValue(), targetExtent);
405             initValText = null;
406         }
407         
408         return targetExtent.getEnumConstant().createEnumConstant(
409                 getName(),
410                 duplicateList(getAnnotations(), targetExtent),
411                 getModifiers(),
412                 null,
413                 (JavaDoc) duplicateElement(getJavadoc(), targetExtent),
414                 isFinal(),
415                 (TypeReference) duplicateElement(getTypeName(), targetExtent),
416                 getDimCount(),
417                 initVal,
418                 initValText,
419                 (ClassDefinition) duplicateElement(getBody(), targetExtent)
420                );
421     }
422
423     protected void _delete() {
424         if (initValueInited) {
425             deleteChild(initialValue);
426             deleteChild(body);
427         }
428         super._delete();
429     }
430     
431     protected ASTree getPartTree(ElementPartKind part) {
432         if (ElementPartKindEnum.NAME.equals(part)) {
433             return getASTree().getSubTrees()[0];
434         }
435         return super.getPartTree(part);
436     }
437     
438 }
439
Popular Tags