|
What this is
Other links
The source code/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is NetBeans. The Initial Developer of the Original * Code is Sun Microsystems, Inc. Portions Copyright 1997-2004 Sun * Microsystems, Inc. All Rights Reserved. */ package org.netbeans.modules.javacore.jmiimpl.javamodel; import java.util.AbstractSequentialList; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.ListIterator; import javax.jmi.reflect.ConstraintViolationException; import javax.jmi.reflect.RefObject; import org.netbeans.jmi.javamodel.*; import org.netbeans.lib.java.parser.ASTree; import org.netbeans.lib.java.parser.ParserTokens; import org.netbeans.lib.java.parser.Token; import org.netbeans.mdr.handlers.AttrListWrapper; import org.netbeans.mdr.storagemodel.StorableObject; import org.netbeans.mdr.persistence.StorageException; import org.netbeans.modules.javacore.parser.ASTProvider; import org.netbeans.modules.javacore.parser.ClassInfo; import org.netbeans.modules.javacore.parser.ElementInfo; import org.netbeans.modules.javacore.parser.EnumInfo; import org.openide.ErrorManager; /** * Implementation of the JavaEnum model element. * * @author Martin Matula */ public abstract class JavaEnumImpl extends JavaClassImpl implements JavaEnum { static final ElementInfo DEFAULT_INFO = new EnumInfo(null, EnumInfo.ENUM_TYPE, null, 0, null, null, null, null); public static final boolean DEBUG = false; public static final String CONSTANTS_ATTR = "constants"; private LightAttrList constants = null; private final MergedFeaturesList features = new MergedFeaturesList(); /** Creates a new instance of JavaEnumImpl */ public JavaEnumImpl(StorableObject s) { super(s); } /** * Returns the value of attribute isInterface. * @return Value of attribute isInterface. */ public boolean isInterface() { return false; } /** * Sets the value of isInterface attribute. See {@link #isInterface} for description * on the attribute. * @param newValue New value to be set. */ public void setInterface(boolean newValue) { if (newValue) { throw new ConstraintViolationException(null, null, "Cannot set interface modifier to true for enum."); // NOI18N } } /** * Returns the value of reference superClass. * @return Value of reference superClass. */ public JavaClass getSuperClass() { JavaModelPackage extent = (JavaModelPackage) refImmediatePackage(); JavaClass enumCls = (JavaClass) extent.getType().resolve("java.lang.Enum"); // NOI18N return extent.getParameterizedType().resolveParameterizedType(enumCls, Collections.singletonList(this), null); } /** * Sets the value of reference superClass. See {@link #getSuperClass} for * description on the reference. * @param newValue New value to be set. */ public void setSuperClass(JavaClass newValue) { if (newValue == null || !((ClassInfo) getElementInfo()).superclass.equals(newValue.getName())) { throw new ConstraintViolationException(null, null, "Cannot set superclass of an enumeration type to: " + newValue == null ? null : newValue.getName()); // NOI18N } } public List getPersistentConstants() { AttrListWrapper list = (AttrListWrapper) super_getConstants(); list.setAttrName(CONSTANTS_ATTR); return list; } private List getNakedConstants() { try { return (List) ((StorableObject) _getDelegate()).getAttribute(CONSTANTS_ATTR); } catch (StorageException e) { throw (GeneralException) ErrorManager.getDefault().annotate(new RuntimeException(e.getMessage()), e); } } public List getConstants() { if (constants == null) { checkUpToDate(); constants = createChildrenList(CONSTANTS_ATTR, (AttrListWrapper) super_getConstants(), null, CHANGED_CONSTANTS); } return constants; } public List getFeatures() { return features; } protected abstract List super_getConstants(); // ---------------------------------------------------------------------- // --- Infrastructural methods ------------------------------------------ // ---------------------------------------------------------------------- protected ElementInfo getDefaultInfo() { return DEFAULT_INFO; } protected void matchPersistent(ElementInfo newInfo) { if (!isPersisted()) { persistChildren(super_getConstants(), ((EnumInfo) newInfo).constants); } else { processMembers(getConstants(), ((EnumInfo) newInfo).constants); } super.matchPersistent(newInfo); } public String toString() { return "enum " + getName(); // NOI18N } protected List getInitedChildren() { List list = super.getInitedChildren(); if (childrenInited) list.addAll(getConstants()); return list; } public List getChildren() { List list = new ArrayList(); list.addAll(getInterfaceNames()); list.addAll(getConstants()); list.addAll(getContents()); return list; } /** This method is called when this element is accessed while bypassing * parent (e.g. using getByMofId()) and thus its ASTInfo needs to be * initialized by its parent. * * Preciselly: This method is invoked from getElementInfo of a child object * if it finds out that ASTInfo was not initialized by its parent (i.e. * this object), yet. * This method should also be called whenever a getter method * for children of this object is called and the children have not * been initialized yet. */ protected void initChildren() { // initialization of contents requires writable lock boolean fail = true; _lock(true); try { childrenInited = false; constants = createChildrenList(constants, CONSTANTS_ATTR, (AttrListWrapper) super_getConstants(), ((EnumInfo) getElementInfo()).constants, CHANGED_CONSTANTS); super.initChildren(); fail = false; } finally { _unlock(fail); } } protected void setData(List annotations, String javadocText, JavaDoc javadoc, List constants, List features, List interfaceNames) { this.constants = createChildrenList(CONSTANTS_ATTR, (AttrListWrapper) super_getConstants(), constants, CHANGED_CONSTANTS); super.setData(annotations, javadocText, javadoc, features, null, interfaceNames, null); } // ......................................................................... // printing and formatting fuctionality // ......................................................................... public String getSourceText() { String origElem; if ((origElem = checkChange()) != null) return origElem; StringBuffer buf = new StringBuffer(); buf.append('\n'); generateNewJavaDoc(buf); buf.append(getIndentation()); generateNewModifiers(buf); buf.append("enum "); // NOI18N buf.append(getSimpleName()); generateNewImplements(buf); formatElementPart(CLASS_OPEN_CURLY, buf); if (!getConstants().isEmpty()) buf.append(getInnerIndentation(2)); for (Iterator it = getConstants().iterator(); it.hasNext();) { MetadataElement constant = (MetadataElement) it.next(); buf.append(constant.getSourceText()); if (it.hasNext()) formatElementPart(COMMA, buf); } if (!getContents().isEmpty()) { // there isn't any feature, do not put semicolon at the end // of constant declaration. buf.append(";\n\n"); // NOI18N } else { if (!getConstants().isEmpty()) { buf.append('\n'); } } ClassDefinitionImpl.generateNewFeatures(this, buf, false); formatElementPart(CLASS_CLOSE_CURLY, buf); return buf.toString(); } /** * */ public void getDiff(List diffList) { EnumInfo astInfo = (EnumInfo) getElementInfo(); ASTProvider parser = getParser(); ASTree[] children = getASTree().getSubTrees(); // javadoc print replaceJavaDoc(diffList); // print modifiers if (isChanged(CHANGED_MODIFIERS)) { diffModifiers(diffList, parser.getToken(children[IDENTIFIER].getFirstToken() - 1), parser); } // print name if (isChanged(CHANGED_NAME)) { replaceNode(diffList, parser, children[IDENTIFIER], getSimpleName(), 0, null); } // interfaces int startOffset = parser.getToken(children[IDENTIFIER].getLastToken()).getEndOffset(); String prefix = formatElementPart(IMPLEMENTS_KEYWORD); getCollectionDiff(diffList, parser, CHANGED_IMPLEMENTS, getASTree().getSubTrees()[INTERFACES], getInterfaceNames(), startOffset, formatElementPart(COMMA), prefix); // constants and contents diff int endOffset; int constEndOffset; ASTree body = children[BODY].getSubTrees()[ENUM_BODY_DECLARATIONS]; { Token closeBrace = parser.getToken(getASTree().getLastToken()); Token[] pad = closeBrace.getPadding(); constEndOffset = endOffset = pad.length > 0 ? pad[0].getStartOffset() : closeBrace.getStartOffset(); } if (body != null) { Token bodyDecls = parser.getToken(body.getFirstToken()); Token[] pad = bodyDecls.getPadding(); constEndOffset = pad.length > 0 ? pad[0].getStartOffset() : bodyDecls.getStartOffset(); } getCollectionDiff(diffList, parser, CHANGED_CONSTANTS, astInfo.constants, getConstants(), constEndOffset, ", ", false); // NOI18N ASTree constants = children[BODY].getSubTrees()[ENUM_CONSTANTS]; if (!getContents().isEmpty() && (body == null)) { diffList.add(new DiffElement(constEndOffset, constEndOffset, ";")); // NOI18N } getCollectionDiff(diffList, parser, CHANGED_FEATURES, astInfo.features, getContents(), endOffset, "\n"); // NOI18N } protected ASTree getPartTree(ElementPartKind part) { if (ElementPartKindEnum.NAME.equals(part)) { return getASTree().getSubTrees()[IDENTIFIER]; } throw new IllegalArgumentException("Invalid part for this element: " + part); // NOI18N } protected ASTree getPartStartTree(ElementPartKind part) { if (ElementPartKindEnum.HEADER.equals(part)) { return getASTree(); } return super.getPartStartTree(part); } protected ASTree getPartEndTree(ElementPartKind part) { if (ElementPartKindEnum.HEADER.equals(part)) { for (int i = 2; true; i--) { ASTree result = getASTree().getSubTrees()[i]; if (result != null) { return result; } } } return super.getPartEndTree(part); } // useful constants private static final int IDENTIFIER = 1; private static final int INTERFACES = 2; private static final int BODY = 3; private static final int ENUM_CONSTANTS = 0; private static final int ENUM_BODY_DECLARATIONS = 1; // --------------------------------------------------------------------- // --- Private methods ------------------------------------------------- // --------------------------------------------------------------------- public void replaceChild(Element oldElement, Element newElement) { if (isPersisted()) { if (replaceObject(getConstants(), oldElement, newElement)) return; } super.replaceChild(oldElement, newElement); } protected void _delete() { // --- delete components ------------------------------------------- deleteChildren(CONSTANTS_ATTR, (AttrListWrapper) super_getConstants()); super._delete(); } public MultipartId getSuperClassName() { return null; } public void setSuperClassName(MultipartId newValue) { if (newValue != null) { throw new ConstraintViolationException(null, null, "Cannot set superclass name of enum."); // NOI18N } } private class MergedFeaturesList extends AbstractSequentialList { private void lock() { lock(false); } private void lock(boolean readWrite) { repository().beginTrans(readWrite); } private void unlock() { unlock(false); } private void unlock(boolean fail) { repository().endTrans(fail); } public int size() { lock(); try { return getConstants().size() + JavaEnumImpl.super.getFeatures().size(); } finally { unlock(); } } public ListIterator listIterator(int index) { lock(); try { return new It(index); } finally { unlock(); } } private class It implements ListIterator { private final ListIterator constantsIterator; private final ListIterator featuresIterator; private ListIterator currIterator; It(int index) { List constants = getConstants(); int size = constants.size(); if (index <= size) { constantsIterator = constants.listIterator(index); featuresIterator = JavaEnumImpl.super.getFeatures().listIterator(); currIterator = constantsIterator; } else { constantsIterator = constants.listIterator(size); featuresIterator = JavaEnumImpl.super.getFeatures().listIterator(index - size); currIterator = featuresIterator; } } public void add(Object o) { boolean fail = true; lock(true); try { if (o instanceof EnumConstant) { if (featuresIterator.nextIndex() != 0) { throw new IllegalStateException(); } constantsIterator.add(o); currIterator = constantsIterator; } else { if (constantsIterator.nextIndex() != getConstants().size()) { throw new IllegalStateException(); } featuresIterator.add(o); currIterator = featuresIterator; } fail = false; } finally { unlock(fail); } } public boolean hasNext() { lock(); try { return constantsIterator.hasNext() || featuresIterator.hasNext(); } finally { unlock(); } } public boolean hasPrevious() { lock(); try { return constantsIterator.hasPrevious() || featuresIterator.hasPrevious(); } finally { unlock(); } } public Object next() { lock(); try { if (constantsIterator.hasNext()) { currIterator = constantsIterator; return constantsIterator.next(); } currIterator = featuresIterator; return featuresIterator.next(); } finally { unlock(); } } public int nextIndex() { lock(); try { return featuresIterator.nextIndex() + constantsIterator.nextIndex(); } finally { unlock(); } } public Object previous() { lock(); try { if (featuresIterator.hasPrevious()) { currIterator = featuresIterator; return featuresIterator.previous(); } currIterator = constantsIterator; return constantsIterator.previous(); } finally { unlock(); } } public int previousIndex() { lock(); try { return featuresIterator.nextIndex() + constantsIterator.previousIndex(); } finally { unlock(); } } public void remove() { boolean fail = true; lock(true); try { currIterator.remove(); fail = false; } finally { unlock(fail); } } public void set(Object o) { boolean fail = true; lock(true); try { if (o instanceof EnumConstant) { if (currIterator != constantsIterator) { throw new IllegalStateException(); } } else { if (currIterator == constantsIterator) { throw new IllegalStateException(); } } currIterator.set(o); fail = false; } finally { unlock(fail); } } } } } |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.