alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

What this is

This file is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

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.Collection;
import java.util.List;
import javax.jmi.reflect.ConstraintViolationException;
import org.netbeans.jmi.javamodel.*;
import org.netbeans.lib.java.parser.ASTree;
import org.netbeans.lib.java.parser.Token;
import org.netbeans.mdr.storagemodel.StorableObject;
import org.netbeans.modules.javacore.parser.*;
import org.openide.util.Utilities;

/**
 * Represents an attribute of an annotation. Consider annotation
 * 
 * public @interface RequestForEnhancement {
 *     int      id();
 *     String   synopsis();
 *     String   engineer() default "[unassigned]"
 *     String   date();    default "[unimplemented]"
 * }
 * 
 *
 * Such an annotation contains four instances of the Attribute element. They
 * are named id, synopsis, engineer and date. Two elements have not the default
 * value. (Calling of getDefaultValue() method returns null.)
 *
 * @author  Pavel Flaska
 */
public abstract class AttributeImpl extends FeatureImpl implements Attribute {
    
    InitialValue defaultValue;
    String defaultValueText;
    TypeReference typeName;
    
    boolean defaultValueInited;
    protected TypeRef type;
    
    private static final ElementInfo DEFAULT_INFO = new AttributeInfo(null, 0, null, 0, null, null, null);

    /** Creates a new instance of AttributeImpl */
    public AttributeImpl(StorableObject s) {
        super(s);
        defaultValueInited = false;
    }
    
    protected void matchPersistent(ElementInfo info) {
        super.matchPersistent(info);
        AttributeInfo newInfo = (AttributeInfo) info;
        
        if (!isPersisted()) {
            setPersisted(true);
            persist();
            setTypeRef(newInfo.type);
        } else {
            if (!Utilities.compareObjects(newInfo.type, getTypeRef())) {
                setType(resolveType(newInfo.type));
            }
        }
    }
    
    protected void matchElementInfo(ElementInfo info) {
        super.matchElementInfo(info);
        resetChildren();
    }
    
    /**
     * Returns the default value of the annotation attribute.
     * In the following example, the value is represented by "[unassigned]".
     *
     * 
     * String   engineer() default "[unassigned]"
     * 
     * 
     * @return  InitialValue default attribute's value
     */
    public InitialValue getDefaultValue() {
        if (!defaultValueInited) {
            initDefaultValue();
        }
        return defaultValue;
    }
    
    /**
     * Sets the default value of the annotation attribute.
     * {@link #getDefaultValue} for description of annotation attribute.
     *
     * @param  initial value tree representing new default value
     */
    public void setDefaultValue(InitialValue newValue) {
        if (!defaultValueInited) {
            initDefaultValue();
            defaultValueInited = true;
        }
        changeChild(defaultValue, newValue);
        defaultValue = newValue;
        defaultValueText = null;
        objectChanged(CHANGED_INITIAL_VALUE);
    }
    
    /**
     * Returns the default value of the annotation attribute in string
     * representation. In the following example, the value is represented 
     * by "[unassigned]".
     *
     * 
     * String   engineer() default "[unassigned]"
     * 
     * 
     * @return  InitialValue default attribute's value
     */
    public String getDefaultValueText() {
        if (isChanged(CHANGED_INITIAL_VALUE)) {
            if (defaultValue != null) {
                throw new ConstraintViolationException(null, null, 
                    "Cannot ask for default value text after the default value was changed."); // NOI18N
            }
            return defaultValueText;
        } else {
            return extractDefaultValueText();
        }
    }
    
    /**
     * Sets the default value of annotation attribute. 
     * See {@link #getDefaultText} for description of annotation attribute.
     *
     * @param newValue New value to be set.
     */
    public void setDefaultValueText(String newValue) {
        if (!childrenInited) {
            initChildren();
        }
        if (defaultValueInited && defaultValue != null) {
            changeChild(defaultValue, null);
        }
        objectChanged(CHANGED_INITIAL_VALUE);
        defaultValueText = newValue;
        defaultValue = null;
        defaultValueInited = true;
    }
    
    /**
     * Returns the value of type. You will get resolved Type model element.
     * Method can return null value on new attributes created by 
     * createAttribute() method on its class proxy.
     *
     * @return value of type or null if new attribute has not set type
     */
    public Type getType() {
        checkUpToDate();
        return resolveType(getTypeRef());
    }

    /**
     * Sets the value of type. You have to provide resolved model element.
     * The method guarantee the sync values between type and typeName.
     *
     * @param newValue new value to be set to type
     */
    public void setType(Type newValue) {
        TypeRef tr = typeToTypeRef(newValue);
        _setTypeName((TypeReference) typeRefToTypeReference(tr), tr);
    }

    public TypeReference getTypeName() {
        if (!childrenInited) {
            initChildren();
        }
        return typeName;
    }

    public void setTypeName(TypeReference typeName) {
        _setTypeName(typeName, typeReferenceToTypeRef(typeName));
    }

    private void _setTypeName(TypeReference typeName, TypeRef typeRef) {
        objectChanged(CHANGED_TYPE);
        if (childrenInited) {
            changeChild(getTypeName(), typeName);
            this.typeName = typeName;
        }
        setTypeRef(typeRef);
    }

    public Collection getValues() {
        throw new UnsupportedOperationException("getValues()"); // NOI18N
    }
    
    /**
     * Returns the source representation of the attribute element. If the
     * element is not changed, it cuts the representation from the original
     * source text. Otherwise it creates it.
     *
     * @return  source text representation of the instance
     */
    public String getSourceText() {
        String origElem;
        if ((origElem = checkChange()) != null)
            return origElem;
        
        StringBuffer buf = new StringBuffer(27);
        generateNewJavaDoc(buf);
        buf.append(getIndentation());
        buf.append(((MetadataElement) getTypeName()).getSourceText());
        buf.append(' ').append(getName());
        buf.append(formatElementPart(MetadataElement.PAR_OPEN_BRACKET));
        buf.append(formatElementPart(MetadataElement.PAR_CLOSE_BRACKET));
        if (defaultValue != null) {
            buf.append(" default "); // todo (#pf): use formatter! // NOI18N
            buf.append(((MetadataElement) defaultValue).getSourceText());
        }
        buf.append(';');
        
        return buf.toString();
    }
    
    /**
     * Returns a list of changes which have been done on element.
     *
     * @param  diff diff elements representing changes (list to add to)
     */
    public void getDiff(List diff) {
        ASTree tree = getASTree();
        ASTProvider parser = getParser();

       // javadoc print
        replaceJavaDoc(diff);
        // type
        getChildDiff(diff, getParser(), tree.getSubTrees()[1], (MetadataElement) getTypeName(), CHANGED_TYPE);
        // name
        if (isChanged(CHANGED_NAME)) {
            Token identifier = (Token) tree.getSubTrees()[2];
            int startOffset = identifier.getStartOffset();
            int endOffset = identifier.getEndOffset();
            diff.add(new DiffElement(startOffset, endOffset, getName()));
        }
        if (isChanged(CHANGED_INITIAL_VALUE)) {
            String newText = defaultValue == null ? defaultValueText :
                ((MetadataElement) getDefaultValue()).getSourceText();
            ASTree initValT = tree.getSubTrees()[3];
            // there was an default value in original source
            int startOffset, endOffset;
            if (initValT != null) {
                // changing old default value
                startOffset = parser.getToken(initValT.getFirstToken()).getStartOffset();
                endOffset = parser.getToken(initValT.getLastToken()).getEndOffset();
            } else {
                // adding new default value
                startOffset = parser.getToken(tree.getLastToken()).getStartOffset();
                newText = " default " + newText; // NOI18N
                endOffset = startOffset;
            }
            diff.add(new DiffElement(startOffset, endOffset, newText == null ? "" : newText));
            
        }
    }
    
    ////////////////////////////////////////////////////////////////////////////
    protected ElementInfo getDefaultInfo() {
        return DEFAULT_INFO;
    }
    
    protected void setData(List annotations,
                           String javadocText,
                           JavaDoc javadoc,
                           TypeReference typeName,
                           InitialValue defaultValue,
                           String defaultValueText) 
    {
        super.setData(annotations, javadocText, javadoc);
        if (defaultValueText == null) {
            changeChild(null, defaultValue);
            this.defaultValue = defaultValue;
        } else {
            if (defaultValue != null) {
                throw new ConstraintViolationException(null, null, "Cannot set both defaultValue and defaultValueText."); // NOI18N
            }
            this.defaultValueText = defaultValueText;
        }
        defaultValueInited = true;
        changeChild(null, typeName);
        this.typeName = typeName;
    }

    protected void initChildren() {
        childrenInited = false;
        AttributeInfo info = (AttributeInfo) getElementInfo();
        ASTree tree = info.getTypeAST(this);
        typeName = (TypeReference) initOrCreate(typeName, tree);
        //info.setSemanticInfo(this);
        childrenInited = true;
    }
    
    protected void resetChildren() {
        if (defaultValue != null) {
            InitialValue temp = defaultValue;
            defaultValue = null;
            changeChild(temp, null);
            temp.refDelete();
        }
        if (typeName != null) {
            TypeReference temp = typeName;
            typeName = null;
            changeChild(temp, null);
            temp.refDelete();
        }
        defaultValueInited = false;
        childrenInited = false;
    }
    
    ////////////////////////////////////////////////////////////////////////////
    // PRIVATE MEMBERS
    ////////////////////////////////////////////////////////////////////////////
    private void initDefaultValue() {
        defaultValueInited = false;
        if (!childrenInited) {
            initChildren();
        }
        AttributeInfo defaultValInfo = (AttributeInfo) getElementInfo();
        if (defaultValInfo != null) {
            defaultValInfo.doAttribution(this);
            defaultValue = (InitialValue) initOrCreate(defaultValue, extractDefaultValue());
        }
        defaultValueInited = true;
    }
    
    private ASTree extractDefaultValue() {
        return getASTree().getSubTrees()[3];
    }

    private String extractDefaultValueText() {
        ASTProvider parser = getParser();
        if (parser == null)
            return null;
        ASTree attributeDefaultValue = extractDefaultValue();
        if (attributeDefaultValue == null)
            return null;
        return parser.getText(attributeDefaultValue);
    }
    
}
... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

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.