KickJava   Java API By Example, From Geeks To Geeks.

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


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.AbstractSequentialList JavaDoc;
22 import java.util.ArrayList JavaDoc;
23 import java.util.Collections JavaDoc;
24 import java.util.Iterator JavaDoc;
25 import java.util.List JavaDoc;
26 import java.util.ListIterator JavaDoc;
27 import javax.jmi.reflect.ConstraintViolationException;
28 import org.netbeans.jmi.javamodel.*;
29 import org.netbeans.lib.java.parser.ASTree;
30 import org.netbeans.lib.java.parser.Token;
31 import org.netbeans.mdr.handlers.AttrListWrapper;
32 import org.netbeans.mdr.storagemodel.StorableObject;
33 import org.netbeans.mdr.persistence.StorageException;
34 import org.netbeans.modules.javacore.api.JavaModel;
35 import org.netbeans.modules.javacore.parser.ASTProvider;
36 import org.netbeans.modules.javacore.parser.ClassInfo;
37 import org.netbeans.modules.javacore.parser.ElementInfo;
38 import org.netbeans.modules.javacore.parser.EnumInfo;
39 import org.openide.ErrorManager;
40
41 /**
42  * Implementation of the JavaEnum model element.
43  *
44  * @author Martin Matula
45  */

46 public abstract class JavaEnumImpl extends JavaClassImpl implements JavaEnum {
47     static final ElementInfo DEFAULT_INFO = new EnumInfo(null, EnumInfo.ENUM_TYPE, null, 0, null, null, null, null);
48
49     public static final boolean DEBUG = false;
50     
51     public static final String JavaDoc CONSTANTS_ATTR = "constants"; // NOI18N
52

53     private LightAttrList constants = null;
54     private final MergedFeaturesList features = new MergedFeaturesList();
55
56     /** Creates a new instance of JavaEnumImpl */
57     public JavaEnumImpl(StorableObject s) {
58         super(s);
59     }
60
61     /**
62      * Returns the value of attribute isInterface.
63      * @return Value of attribute isInterface.
64      */

65     public boolean isInterface() {
66         return false;
67     }
68
69     /**
70      * Sets the value of isInterface attribute. See {@link #isInterface} for description
71      * on the attribute.
72      * @param newValue New value to be set.
73      */

74     public void setInterface(boolean newValue) {
75         if (newValue) {
76             throw new ConstraintViolationException(null, null, "Cannot set interface modifier to true for enum."); // NOI18N
77
}
78     }
79
80     /**
81      * Returns the value of reference superClass.
82      * @return Value of reference superClass.
83      */

84     public JavaClass getSuperClass() {
85         checkUpToDate();
86         JavaClass enumCls = (JavaClass) JavaModel.getDefaultExtent().getType().resolve("java.lang.Enum"); // NOI18N
87
JavaModelPackage extent = (JavaModelPackage)enumCls.refImmediatePackage();
88         return extent.getParameterizedType().resolveParameterizedType(enumCls, Collections.singletonList(this), null);
89     }
90
91     /**
92      * Sets the value of reference superClass. See {@link #getSuperClass} for
93      * description on the reference.
94      * @param newValue New value to be set.
95      */

96     public void setSuperClass(JavaClass newValue) {
97         if (newValue == null || !((ClassInfo) getElementInfo()).superclass.equals(newValue.getName())) {
98             throw new ConstraintViolationException(null, null, "Cannot set superclass of an enumeration type to: " + newValue == null ? null : newValue.getName()); // NOI18N
99
}
100     }
101
102     public List JavaDoc getPersistentConstants() {
103         AttrListWrapper list = (AttrListWrapper) super_getConstants();
104         list.setAttrName(CONSTANTS_ATTR);
105         return list;
106     }
107
108     private List JavaDoc getNakedConstants() {
109         try {
110             return (List JavaDoc) ((StorableObject) _getDelegate()).getAttribute(CONSTANTS_ATTR);
111         } catch (StorageException e) {
112             throw (GeneralException) ErrorManager.getDefault().annotate(new RuntimeException JavaDoc(e.getMessage()), e);
113         }
114     }
115
116     public List JavaDoc getConstants() {
117         checkUpToDate();
118         if (constants == null) {
119             constants = createChildrenList(CONSTANTS_ATTR, (AttrListWrapper) super_getConstants(), null, CHANGED_CONSTANTS);
120         }
121         return constants;
122     }
123     
124     public List JavaDoc getFeatures() {
125         return features;
126     }
127
128     protected abstract List JavaDoc super_getConstants();
129
130     // ----------------------------------------------------------------------
131
// --- Infrastructural methods ------------------------------------------
132
// ----------------------------------------------------------------------
133

134     protected ElementInfo getDefaultInfo() {
135         return DEFAULT_INFO;
136     }
137     
138     protected void matchPersistent(ElementInfo newInfo) {
139         if (!isPersisted()) {
140             persistChildren(getPersistentList(CONSTANTS_ATTR, super_getConstants()), ((EnumInfo) newInfo).constants);
141         } else {
142             processMembers(getConstants(), ((EnumInfo) newInfo).constants);
143         }
144         
145         super.matchPersistent(newInfo);
146     }
147
148     public String JavaDoc toString() {
149         return "enum " + getName(); // NOI18N
150
}
151
152     protected List JavaDoc getInitedChildren() {
153         List JavaDoc list = super.getInitedChildren();
154         if (childrenInited) {
155             list.addAll(getConstants());
156         }
157         return list;
158     }
159
160     public List JavaDoc getChildren() {
161         List JavaDoc list = new ArrayList JavaDoc();
162         list.addAll(getAnnotations());
163         list.addAll(getInterfaceNames());
164         list.addAll(getConstants());
165         list.addAll(getContents());
166         return list;
167     }
168
169     public void fixImports(Element scope, Element original) {
170         JavaEnum jEnum=(JavaEnum)original;
171         
172         super.fixImports(scope,original);
173         fixImports(scope,getConstants(),jEnum.getConstants());
174     }
175
176     /** This method is called when this element is accessed while bypassing
177      * parent (e.g. using getByMofId()) and thus its ASTInfo needs to be
178      * initialized by its parent.
179      *
180      * Preciselly: This method is invoked from getElementInfo of a child object
181      * if it finds out that ASTInfo was not initialized by its parent (i.e.
182      * this object), yet.
183      * This method should also be called whenever a getter method
184      * for children of this object is called and the children have not
185      * been initialized yet.
186      */

187     protected void initChildren() {
188         // initialization of contents requires writable lock
189
boolean fail = true;
190         _lock(true);
191         try {
192             childrenInited = false;
193             constants = createChildrenList(constants, CONSTANTS_ATTR, (AttrListWrapper) super_getConstants(), ((EnumInfo) getElementInfo()).constants, CHANGED_CONSTANTS);
194             super.initChildren();
195             fail = false;
196         } finally {
197             _unlock(fail);
198         }
199     }
200
201     protected void setData(List JavaDoc annotations, String JavaDoc javadocText, JavaDoc javadoc, List JavaDoc constants, List JavaDoc features, List JavaDoc interfaceNames) {
202         this.constants = createChildrenList(CONSTANTS_ATTR, (AttrListWrapper) super_getConstants(), constants, CHANGED_CONSTANTS);
203         super.setData(annotations, javadocText, javadoc, features, null, interfaceNames, null);
204     }
205
206     // .........................................................................
207
// printing and formatting fuctionality
208
// .........................................................................
209

210     public String JavaDoc getSourceText() {
211         String JavaDoc origElem;
212         if ((origElem = checkChange()) != null)
213             return origElem;
214         StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
215         buf.append('\n');
216         generateNewJavaDoc(buf);
217         buf.append(getIndentation());
218         generateNewModifiers(buf);
219         buf.append("enum "); // NOI18N
220
buf.append(getSimpleName());
221         generateNewImplements(buf);
222         ClassDefinitionImpl.generateNewFeatures(this, buf, isNew());
223         return buf.toString();
224     }
225
226     /**
227      *
228      */

229     public void getDiff(List JavaDoc diffList) {
230         EnumInfo astInfo = (EnumInfo) getElementInfo();
231         ASTProvider parser = getParser();
232         ASTree[] children = getASTree().getSubTrees();
233
234         // javadoc print
235
replaceJavaDoc(diffList);
236         // print modifiers
237
if (isChanged(CHANGED_MODIFIERS | CHANGED_ANNOTATION)) {
238             diffModifiers(diffList, parser.getToken(children[IDENTIFIER].getFirstToken() - 1), parser);
239         } else if (children[0] != null) {
240             getCollectionDiff(diffList, parser, CHANGED_ANNOTATION, astInfo.annotations, getAnnotations(), parser.getToken(children[0].getLastToken()).getEndOffset(), " "); // NOI18N
241
}
242         // print name
243
if (isChanged(CHANGED_NAME)) {
244             replaceNode(diffList, parser, children[IDENTIFIER], getSimpleName(), 0, null);
245         }
246         // interfaces
247
int startOffset = parser.getToken(children[IDENTIFIER].getLastToken()).getEndOffset();
248         String JavaDoc prefix = formatElementPart(IMPLEMENTS_KEYWORD);
249         getCollectionDiff(diffList, parser, CHANGED_IMPLEMENTS, getASTree().getSubTrees()[INTERFACES],
250                 getInterfaceNames(), startOffset, formatElementPart(COMMA), prefix);
251
252         // constants and contents diff
253
int endOffset;
254         int constEndOffset;
255         ASTree body = children[BODY] == null ? null : children[BODY].getSubTrees()[ENUM_BODY_DECLARATIONS];
256         {
257             constEndOffset = endOffset = getContentsEndOffset(parser, getASTree());
258         }
259         if (body != null) {
260             Token bodyDecls = parser.getToken(body.getFirstToken());
261             Token[] pad = bodyDecls.getPadding();
262             constEndOffset = pad.length > 0 ? pad[0].getStartOffset() : bodyDecls.getStartOffset();
263         }
264         getCollectionDiff(diffList, parser, CHANGED_CONSTANTS, astInfo.constants, getConstants(), constEndOffset, ", ", false); // NOI18N
265
if (!getContents().isEmpty() && (body == null)) {
266             diffList.add(new DiffElement(constEndOffset, constEndOffset, ";")); // NOI18N
267
}
268         getCollectionDiff(diffList, parser, CHANGED_FEATURES, astInfo.features, getContents(), endOffset, "\n"); // NOI18N
269
}
270
271     protected ASTree getPartTree(ElementPartKind part) {
272         if (ElementPartKindEnum.NAME.equals(part)) {
273             return getASTree().getSubTrees()[IDENTIFIER];
274         }
275         throw new IllegalArgumentException JavaDoc("Invalid part for this element: " + part); // NOI18N
276
}
277
278     protected ASTree getPartStartTree(ElementPartKind part) {
279         if (ElementPartKindEnum.HEADER.equals(part)) {
280             return getASTree();
281         }
282         return super.getPartStartTree(part);
283     }
284
285     protected ASTree getPartEndTree(ElementPartKind part) {
286         if (ElementPartKindEnum.HEADER.equals(part)) {
287             for (int i = 2; true; i--) {
288                 ASTree result = getASTree().getSubTrees()[i];
289                 if (result != null) {
290                     return result;
291                 }
292             }
293         }
294         return super.getPartEndTree(part);
295     }
296
297     // useful constants
298
private static final int IDENTIFIER = 1;
299     private static final int INTERFACES = 2;
300     private static final int BODY = 3;
301     private static final int ENUM_CONSTANTS = 0;
302     private static final int ENUM_BODY_DECLARATIONS = 1;
303
304     // ---------------------------------------------------------------------
305
// --- Private methods -------------------------------------------------
306
// ---------------------------------------------------------------------
307

308     public void replaceChild(Element oldElement, Element newElement) {
309         if (isPersisted()) {
310             if (replaceObject(getConstants(), oldElement, newElement)) return;
311         }
312         super.replaceChild(oldElement, newElement);
313     }
314
315     protected void _delete() {
316         // --- delete components -------------------------------------------
317
deleteChildren(CONSTANTS_ATTR, (AttrListWrapper) super_getConstants());
318         super._delete();
319     }
320
321     public MultipartId getSuperClassName() {
322         return null;
323     }
324
325     public void setSuperClassName(MultipartId newValue) {
326         if (newValue != null) {
327             throw new ConstraintViolationException(null, null, "Cannot set superclass name of enum."); // NOI18N
328
}
329     }
330     
331     private class MergedFeaturesList extends AbstractSequentialList JavaDoc {
332         private void lock() {
333             lock(false);
334         }
335
336         private void lock(boolean readWrite) {
337             repository().beginTrans(readWrite);
338         }
339
340         private void unlock() {
341             unlock(false);
342         }
343
344         private void unlock(boolean fail) {
345             repository().endTrans(fail);
346         }
347
348         public int size() {
349             lock();
350             try {
351                 return getConstants().size() + JavaEnumImpl.super.getFeatures().size();
352             } finally {
353                 unlock();
354             }
355         }
356         
357         public ListIterator JavaDoc listIterator(int index) {
358             lock();
359             try {
360                 return new It(index);
361             } finally {
362                 unlock();
363             }
364         }
365         
366         private class It implements ListIterator JavaDoc {
367             private final ListIterator JavaDoc constantsIterator;
368             private final ListIterator JavaDoc featuresIterator;
369             private ListIterator JavaDoc currIterator;
370             
371             It(int index) {
372                 List JavaDoc constants = getConstants();
373                 int size = constants.size();
374                 if (index <= size) {
375                     constantsIterator = constants.listIterator(index);
376                     featuresIterator = JavaEnumImpl.super.getFeatures().listIterator();
377                     currIterator = constantsIterator;
378                 } else {
379                     constantsIterator = constants.listIterator(size);
380                     featuresIterator = JavaEnumImpl.super.getFeatures().listIterator(index - size);
381                     currIterator = featuresIterator;
382                 }
383             }
384             
385             public void add(Object JavaDoc o) {
386                 boolean fail = true;
387                 lock(true);
388                 try {
389                     if (o instanceof EnumConstant) {
390                         if (featuresIterator.nextIndex() != 0) {
391                             throw new IllegalStateException JavaDoc();
392                         }
393                         constantsIterator.add(o);
394                         currIterator = constantsIterator;
395                     } else {
396                         if (constantsIterator.nextIndex() != getConstants().size()) {
397                             throw new IllegalStateException JavaDoc();
398                         }
399                         featuresIterator.add(o);
400                         currIterator = featuresIterator;
401                     }
402                     fail = false;
403                 } finally {
404                     unlock(fail);
405                 }
406             }
407             
408             public boolean hasNext() {
409                 lock();
410                 try {
411                     return constantsIterator.hasNext() || featuresIterator.hasNext();
412                 } finally {
413                     unlock();
414                 }
415             }
416             
417             public boolean hasPrevious() {
418                 lock();
419                 try {
420                     return constantsIterator.hasPrevious() || featuresIterator.hasPrevious();
421                 } finally {
422                     unlock();
423                 }
424             }
425             
426             public Object JavaDoc next() {
427                 lock();
428                 try {
429                     if (constantsIterator.hasNext()) {
430                         currIterator = constantsIterator;
431                         return constantsIterator.next();
432                     }
433                     currIterator = featuresIterator;
434                     return featuresIterator.next();
435                 } finally {
436                     unlock();
437                 }
438             }
439             
440             public int nextIndex() {
441                 lock();
442                 try {
443                     return featuresIterator.nextIndex() + constantsIterator.nextIndex();
444                 } finally {
445                     unlock();
446                 }
447             }
448             
449             public Object JavaDoc previous() {
450                 lock();
451                 try {
452                     if (featuresIterator.hasPrevious()) {
453                         currIterator = featuresIterator;
454                         return featuresIterator.previous();
455                     }
456                     currIterator = constantsIterator;
457                     return constantsIterator.previous();
458                 } finally {
459                     unlock();
460                 }
461             }
462             
463             public int previousIndex() {
464                 lock();
465                 try {
466                     return featuresIterator.nextIndex() + constantsIterator.previousIndex();
467                 } finally {
468                     unlock();
469                 }
470             }
471             
472             public void remove() {
473                 boolean fail = true;
474                 lock(true);
475                 try {
476                     currIterator.remove();
477                     fail = false;
478                 } finally {
479                     unlock(fail);
480                 }
481             }
482             
483             public void set(Object JavaDoc o) {
484                 boolean fail = true;
485                 lock(true);
486                 try {
487                     if (o instanceof EnumConstant) {
488                         if (currIterator != constantsIterator) {
489                             throw new IllegalStateException JavaDoc();
490                         }
491                     } else {
492                         if (currIterator == constantsIterator) {
493                             throw new IllegalStateException JavaDoc();
494                         }
495                     }
496                     currIterator.set(o);
497                     fail = false;
498                 } finally {
499                     unlock(fail);
500                 }
501             }
502         }
503     }
504     
505     public Element duplicate(JavaModelPackage targetExtent) {
506         return targetExtent.getJavaEnum().createJavaEnum(
507                 getName(),
508                 duplicateList(getAnnotations(), targetExtent),
509                 getModifiers(),
510                 null,
511                 (JavaDoc) duplicateElement(getJavadoc(), targetExtent),
512                 duplicateList(getContents(), targetExtent),
513                 (MultipartId) duplicateElement(getSuperClassName(), targetExtent),
514                 duplicateList(getInterfaceNames(), targetExtent),
515                 duplicateList(getTypeParameters(), targetExtent),
516                 duplicateList(getConstants(), targetExtent)
517                );
518     }
519 }
520
Popular Tags