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-2000 Sun
 * Microsystems, Inc. All Rights Reserved.
 */

package org.netbeans.modules.java.bridge;

import java.beans.PropertyChangeEvent;
import java.lang.reflect.Modifier;
import java.util.List;

import javax.jmi.reflect.InvalidObjectException;

import org.netbeans.api.mdr.events.*;
import org.netbeans.jmi.javamodel.Constructor;
import org.openide.nodes.Node;
import org.openide.src.*;

import org.openide.ErrorManager;
import org.openide.util.Utilities;

import org.netbeans.jmi.javamodel.Feature;
import org.netbeans.jmi.javamodel.JavaClass;

/** Describes a main elements of java source
 * (variables, methods and classes). Provides support
 * for associating this element with declaring class. Adds `name' and `modifiers' properties
 * implementation for descendant elements as well as some utility methods for type and
 * identifier comparison that can be utilized in change detection.
 *
 * @author Svatopluk Dedic, Petr Hamernik, Jaroslav Tulach
 * @version 0.1
 * @since 24/11/2000
 */
abstract class MemberElementImpl extends ElementImpl {

    /** Implementation of the declaring class. It is just a shorthand for acquiring
     * a cookie from the ClassElement.
     */
    protected ClassElementImpl    declaringClassImpl;        
    
    protected transient Identifier cachedName = null;
    
    static final long serialVersionUID =6388377681336329844L;
    
    // Construction
    ///////////////////////////////////////////////////////////////////////////////////
    
    protected MemberElementImpl(DefaultLangModel model, Feature javaElement) {
        super(model, javaElement);
        try {
            String name = javaElement.getName ();
            if (name != null)
                cachedName = createName (name);
        } catch (InvalidObjectException e) {
        }
    }
    
    // Public operations
    ///////////////////////////////////////////////////////////////////////////////////

    protected void setParent(ElementImpl impl) {
        if (impl instanceof ClassElementImpl) {
            this.declaringClassImpl = (ClassElementImpl)impl;
            try {
                String name = ((Feature) javaElement).getName ();
                if (name != null)
                    cachedName = createName (name);
            } catch (InvalidObjectException e) {
            }
        }
    }
    
    protected boolean parentValid() {
        return declaringClassImpl != null && declaringClassImpl.isValid();
    }

    protected void createFromModel(Element model) throws SourceException {
        MemberElement other = (MemberElement)model;
        setModifiers(other.getModifiers());
        setName(createName(other.getName().getName()));
    }
    
    protected Identifier createName(String n) {
        if (n==null) n="";
        return Identifier.create(n);
    }
    
        /*
    public Node.Cookie getCookie(Class clazz) {
        Node.Cookie ret = super.getCookie(clazz);
        if (ret != null)
            return ret;
        ClassElementImpl climpl = getDeclaringImpl();
        if (climpl != null)
            return climpl.getCookie(clazz);
        return null;
    }
         */

    // Getters
    ///////////////////////////////////////////////////////////////////////////////////

    /** Getter for modifiers for this element.
    * @see java.lang.reflect.Modifier
    * @return constants from java.lang.reflect.Modifier
    */
    public int getModifiers() {
        repository.beginTrans(false);
        try {
            setClassPath();
            return ((Feature) javaElement).getModifiers ();
        } catch (InvalidObjectException e) {
            return 0;
        } finally {
            repository.endTrans(false);
        }
    }

    /** Getter for name of the field.
    * @return the name
    */
    public Identifier getName() {
        repository.beginTrans(false);
        try {
            setClassPath();
            return createName (((Feature) javaElement).getName ());
        } catch (InvalidObjectException e) {            
            return cachedName != null ? cachedName : Identifier.create ("");
        } finally {
            repository.endTrans(false);
        }
    }
    
    /**
     * Extends the basic isValid with a check, whether the ClassElement itself is valid.
     * @return true, if both the element and its decl. class are valid.
     */
    public boolean isValid() {
        if (!super.isValid())
            return false;
        
        ClassElementImpl impl = getDeclaringImpl();
        return impl == null || impl.isValid();
    }
    
    protected void checkWritable() throws SourceException {
        SourceElementImpl source = findSource();
        if (source != null)
            source.checkWritable();
    }
    
    /**
     * Extracts and retrieves local classes for the element.
     * @return array of elements representing local classes.
     */
    public ClassElement[] getLocalClasses() {
        // TODO: implement fetching1 of local classes based on data extracting via
        // model and parsing support.
        return new ClassElement[] {};
    }
    
    // Setters/changers
    ///////////////////////////////////////////////////////////////////////////////////
    /**
     * Overriden in subsclasses so that it check model constraints on modifier value.
     * The default implementation does nothing.
     */
    protected void checkModifierConstraints(int newMods) throws SourceException {
    }

    /** Overload to impose constraint over the member's name. The default implementation
     * does nothing.
     */
    protected void checkNameConstraints(Identifier name) throws SourceException {
    }

    /**
     * Resolves, or tries to resolve the type.
     */
    protected final Type resolveType(Type t) {
        if (!isConstrained())
            return t;
        
        if (t.isPrimitive())
            return t;
        return getModelImpl().resolveType(getParent(), t);
    }
    
    protected final Identifier resolveIdent(Identifier i) {
        if (i == null || !isConstrained())
            return i;
        return getModelImpl().resolveIdent(getParent(), i);
    }
    
    protected final Identifier[] resolveIdentifiers(Identifier[] ids) {
        if (!isConstrained())
            return ids;
        
        Identifier[] newIds = null;
        for (int i = 0; i < ids.length; i++) {
            Identifier n = resolveIdent(ids[i]);
            if (n == ids[i])
                continue;
            if (newIds == null) {
                newIds = new Identifier[ids.length];
                System.arraycopy(ids, 0, newIds, 0, ids.length);
            }
            newIds[i] = n;
        }
        if (newIds == null)
            return ids;
        return newIds;
    }
    
    protected Element getParent() {
        return getDeclaringClass();
    }
    
    /** Setter for modifiers for this element.
    * @see java.lang.reflect.Modifier
    * @param mod constants from java.lang.reflect.Modifier
    */
    public void setModifiers(int mod) throws SourceException {
        checkWritable();
        checkDocument();
        repository.beginTrans (true);
        boolean failed = true;
        try {
            setClassPath();
            int old = getModifiers ();
            if (old == mod) {
                failed = false;
                checkIsValid ();
                return;
            }
            if (isConstrained())
                checkModifierConstraints(mod);
            PropertyChangeEvent evt = new PropertyChangeEvent(getElement(), PROP_MODIFIERS, new Integer(old), new Integer(mod));
            checkVetoablePropertyChange(evt);
            
            ((Feature) javaElement).setModifiers (mod);
            failed = false;
        } catch (InvalidObjectException e) {
            throwIsInvalid ();
        } finally {
            repository.endTrans (failed);
        }
    }
    
    protected void doSetName(Identifier id) throws SourceException {
        
        String s = id.getName();
        PropertyChangeEvent evt;
        Identifier old = getName ();
        if (isConstrained())
            checkNameConstraints(id);
        /*
        if (old != null &&
            old.getSourceName() == id.getSourceName()) {
            checkIsValid ();
            return;
        }
         */
        evt = new PropertyChangeEvent(getElement(), PROP_NAME, old, id);
        checkVetoablePropertyChange(evt);
        
        
        if (javaElement instanceof Constructor) {
            try {
                javaElement.refImmediatePackage();
            } catch (InvalidObjectException e) {
                throwIsInvalid();
            }
        } else {
            String name=id.getName();
            
            if (javaElement instanceof JavaClass) {                
                ((JavaClass) javaElement).setSimpleName(name);
            } else {
                ((Feature) javaElement).setName (name);
            }
        }
    }

    /**
     * Implementation of name change for an Element. The implementation will:
    *
  • check for model constraints on the name *
  • check vetoable listener acknowledges of the change *
  • ask the Binding for performing the change *
  • fire the PropertyChangedEvent. * @param id new name to use with the element. */ public void setName(Identifier id) throws SourceException { checkWritable(); checkDocument(); boolean failed = true; repository.beginTrans (true); try { setClassPath(); doSetName(id); failed = false; } catch (InvalidObjectException e) { throwIsInvalid (); } finally { repository.endTrans (failed); } } public void fireNameChange (String oldValue, String newValue) { Identifier oldName = null, newName = null; if (oldValue == null) oldValue = ""; if (newValue == null) newValue = ""; try { oldName = createName (oldValue); } catch (InvalidObjectException e) { oldName = Identifier.create (""); } try { newName = createName (newValue); } catch (InvalidObjectException e) { newName = Identifier.create (""); } cachedName = newName; PropertyChangeEvent evt = new PropertyChangeEvent(getElement(), PROP_NAME, oldName, newName); if (!oldName.equals(newName)) // [PENDING] fireOwnPropertyChange(evt); MemberElement old = (MemberElement) cloneSelf (); // MemberElement.Impl oldImpl = (MemberElement.Impl) old.getCookie (MemberElement.Impl.class); try { old.setName (oldName); } catch (SourceException e) { e.printStackTrace (); } notifyConnectionChange (old); } public void fireModifiersChange (Integer oldValue, Integer newValue) { PropertyChangeEvent evt = new PropertyChangeEvent(getElement(), PROP_MODIFIERS, oldValue, newValue); fireOwnPropertyChange(evt); MemberElement old = (MemberElement) cloneSelf (); try { old.setModifiers (oldValue.intValue ()); } catch (SourceException e) { e.printStackTrace (); } notifyConnectionChange (old); } // Utility methods /////////////////////////////////////////////////////////////////////////////////// /** Compares source names of the identifiers; it does not pay attention to full names specified in the identifier object. */ protected static boolean compareSourceIdentifiers(Identifier oldId, Identifier newId) { if (oldId == newId) return true; if (oldId == null || newId == null) return false; if (!oldId.getSourceName().equals(newId.getSourceName())) { return false; } int oldRes = oldId.getResolutionStatus(); int newRes = newId.getResolutionStatus(); boolean result; result = (oldRes == newRes || newRes == Identifier.NOT_YET_RESOLVED) && oldId.getFullName().equals(newId.getFullName()); return result; } /** Compares types not paying attention to fully qualified names of class types. */ protected static boolean compareSourceTypes(Type oldType, Type newType) { if (oldType == newType) { return true; } // no type was ever present ;-) if ((oldType == null) || (newType == null)) return false; // if one of the types is a primitive one, they must be the same instance to match. if (oldType.isPrimitive() || newType.isPrimitive()) { return false; } if (oldType.isArray()) { if (!newType.isArray()) { return false; } return compareSourceTypes(oldType.getElementType(), newType.getElementType()); } else if (newType.isArray()) { return false; } if (!oldType.isClass() || !newType.isClass()) { throw new InternalError("Unexpected type combination."); // NOI18N } return compareSourceIdentifiers(oldType.getTypeIdentifier(), newType.getTypeIdentifier()); } /** * Members source finder delegates to the class' one. */ protected SourceElementImpl findSource() { if (this.declaringClassImpl != null) return this.declaringClassImpl.findSource(); else return null; } /** * Returns the implementation of the declaring class. */ protected ClassElementImpl getDeclaringImpl() { return this.declaringClassImpl; } /** Returns the abstract layer for the declaring class implementation. */ protected ClassElement getDeclaringClass() { if (declaringClassImpl == null) return null; return (ClassElement)declaringClassImpl.getElement(); } /** * Access method to the Element's isValid, may be used by subclasses for overriding * isValid semantics. */ protected boolean isElementValid() { return super.isValid(); } void updateJavadoc() { try { String javadocText=((Feature)javaElement).getJavadocText(); if (!Utilities.compareObjects(javadocText, javadoc.getRawText())) { try { javadoc.changeJavaDocText(javadocText, true); } catch (SourceException ex) { ErrorManager.getDefault().notify(ex); } } } catch (InvalidObjectException e) { } } // .......................................................................... static class MemberElementListener extends ElementImpl.ElementListener { MemberElementListener (MemberElementImpl impl) { super (impl); } public void doChange (MDRChangeEvent event) { super.doChange (event); if ((source == javaElement) && (event instanceof AttributeEvent)) { AttributeEvent attrEvent = (AttributeEvent) event; String attrName = attrEvent.getAttributeName (); if (attrName.equals ("name")) { // NOI18N ((MemberElementImpl) impl).fireNameChange ( (String) attrEvent.getOldElement (), (String) attrEvent.getNewElement () ); } else if (attrName.equals ("modifiers")) { // NOI18N ((MemberElementImpl) impl).fireModifiersChange ( (Integer) attrEvent.getOldElement (), (Integer) attrEvent.getNewElement () ); } } } } }
... 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.