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.java.ui.nodes.elements;

import java.beans.*;
import java.lang.reflect.InvocationTargetException;
import java.util.*;

import org.openide.nodes.*;
import org.openide.util.datatransfer.*;
import org.openide.src.ElementProperties;
import org.openide.loaders.DataObject;
import org.netbeans.jmi.javamodel.JavaClass;
import org.netbeans.jmi.javamodel.MultipartId;
import org.netbeans.jmi.javamodel.JavaModelPackage;
import org.netbeans.modules.javacore.internalapi.JavaMetamodel;
import org.netbeans.modules.java.ui.nodes.editors.IdentifierArrayEditor;
import org.netbeans.api.mdr.events.AttributeEvent;

import javax.jmi.reflect.JmiException;


/** Node representing a Java class.
 * @see org.netbeans.jmi.javamodel.JavaClass
 *
 * @author Petr Hamernik, Jan Pokorsky
 * 
 */
public final class ClassNode extends ElementNode {

    /** Return value of getIconAffectingProperties method. */
    private static final String[] ICON_AFFECTING_PROPERTIES = new String[] {
                PROP_MODIFIERS
            };

    private static final Map mapClassAttributeName;
    private static final Map mapInterfaceAttributeName;
    
    static {
        mapInterfaceAttributeName = new HashMap();
        mapInterfaceAttributeName.put(PROP_MODIFIERS, PROP_MODIFIERS);
        mapInterfaceAttributeName.put(ElementProperties.PROP_NAME, ElementProperties.PROP_NAME);
        mapInterfaceAttributeName.put("interfaceNames", PROP_INTERFACES); // NOI18N
        
        mapClassAttributeName = new HashMap(mapInterfaceAttributeName);
        mapClassAttributeName.put("superClassName", PROP_SUPERCLASS); // NOI18N
    }
    
    /**
     * cached flag to not access jmi unnecessary
     */ 
    private boolean isInterface;
    
    /** is {@link org.openide.nodes.Sheet} initialized */
    private boolean isSheetCreated = false;
    
    private DataObject sourceDO;
    
    /** Create a new class node.
    * @param element class element to represent
    * @param children node children
    * @param writeable true to be writable
    */
    public ClassNode(JavaClass element, Children children, boolean writeable) {
        super(element, children, writeable, SourceOptions.PROP_CLASS_FORMAT);
        init(element);
    }

    private void init(JavaClass element) {
        isInterface = element.isInterface();
        setElementFormat0(getElementFormat(isInterface));
        superSetName(element.getSimpleName());
        setIconBase(resolveIconBase());
        sourceDO = JavaMetamodel.getManager().getDataObject(element.getResource());
    }

    private JavaClass getJavaClass() {
        return (JavaClass) this.element;
    }
    
    /* Resolve the current icon base.
    * @return icon base string.
    */
    protected String resolveIconBase() {
        return isInterface? INTERFACE : CLASS;
    }

    /* This method is used for resolving the names of the properties,
    * which could affect the icon (such as "modifiers").
    * @return the appropriate array.
    */
    protected String[] getIconAffectingProperties() {
        return ICON_AFFECTING_PROPERTIES;
    }

    protected ElementFormat getElementFormatProperty() {
        return getElementFormat(isInterface);
    }

    /* This method resolve the appropriate hint format for the type
    * of the element. It defines the short description.
    */
    protected ElementFormat getHintElementFormat() {
        return this.isInterface ?
               getSourceOptions().getInterfaceElementLongFormat() :
               getSourceOptions().getClassElementLongFormat();
    }
    
    private static ElementFormat getElementFormat(boolean isInterface) {
        return isInterface ?
               getSourceOptions().getInterfaceElementFormat() :
               getSourceOptions().getClassElementFormat();
    }

    protected Map getAttributeNameMap() {
        return isInterface? mapInterfaceAttributeName: mapClassAttributeName;
    }

    protected ChangeDescriptor handleAttributeChange(AttributeEvent ae) {
        ChangeDescriptor cd = super.handleAttributeChange(ae);
        final Object src = ae.getSource();
        if (src != element || !((JavaClass) src).isValid()) {
            return cd;
        }
        String attrName = ae.getAttributeName();
        JavaClass jc = getJavaClass();
        if (PROP_MODIFIERS.equals(attrName) && jc.isInterface() != this.isInterface) {
            this.isInterface = !this.isInterface;
            this.elementFormat = getElementFormat(this.isInterface);
            cd.iconBase = resolveIconBase();
            cd.displayName = getElementFormat().format(jc);
            cd.shortDescription = getShortDescription();
            if (isSheetCreated) {
                cd.sheet = new Sheet();
            }
        }
        return cd;
    }

    protected void processChange(ElementNode.ChangeDescriptor desc) {
        if (desc.sheet != null) {
            Sheet.Set ps = getSheet().get(Sheet.PROPERTIES);
            configureSheetSet(ps, this.isInterface);
            desc.sheet = null; // do not process again in ElementNode
        }
        super.processChange(desc);
    }

    /* Creates property set for this node */
    protected Sheet createSheet () {
        // do not change properties order without reviewing of recomputeSheet()
        Sheet sheet = Sheet.createDefault();
        Sheet.Set ps = sheet.get(Sheet.PROPERTIES);
        configureSheetSet(ps, this.isInterface);
        this.isSheetCreated = true;
        return sheet;
    }
    
    private void configureSheetSet(Sheet.Set ps, boolean isInterface) {
        ps.put(createModifiersProperty(writeable));
        ps.put(createNameProperty(getJavaClass()));
        ps.put(createTypeParametersProperty());
        if (isInterface) {
            ps.remove(PROP_SUPERCLASS);
        } else {
            ps.put(createSuperclassProperty(writeable));
        }
        ps.put(createInterfacesProperty(writeable));
    }

    /** Create a node property for the superclass of this class.
    * @param canW if false, property will be read-only
    * @return the property
    */
    protected Node.Property createSuperclassProperty(boolean canW) {
        return new ElementNode.ElementProp(PROP_SUPERCLASS, String.class, canW) {
                   /** Gets the value */
                   public Object getValue () {
                       MultipartId mid = getJavaClass().getSuperClassName();
                       return mid == null ? "" : IdentifierArrayEditor.multipartIdToName(mid); // NOI18N
                   }

                   /** Sets the value */
                   public void setValue(final Object val) throws IllegalArgumentException,
                           IllegalAccessException, InvocationTargetException {
                       super.setValue(val);
                       if (!(val instanceof String))
                           throw new IllegalArgumentException();
                       String str = ((String) val).trim();
                       if (str != null && !"".equals(str)) {
                           boolean fail = true;
                           try {
                               JavaMetamodel.getDefaultRepository().beginTrans(true);
                               try {
                                   JavaModelPackage model = JavaMetamodel.getManager().getJavaExtent(getJavaClass());
                                   MultipartId mid = model.getMultipartId().createMultipartId(str, null, null);
                                   getJavaClass().setSuperClassName(mid);
                                   fail = false;
                               } finally {
                                   JavaMetamodel.getDefaultRepository().endTrans(fail);
                               }
                           } catch (JmiException ex) {
                               IllegalArgumentException iaex = new IllegalArgumentException();
                               iaex.initCause(ex);
                               throw ex;
                           }
//                           Type t = Type.parse(str);
//                           if (!t.isClass())
//                               throw new IllegalArgumentException();
                       }

                   }
               };
    }

    /** Create a node property for the implemented interfaces of this class.
    * (Or, extended interfaces if this is itself an interface.)
    * @param canW if false, property will be read-only
    * @return the property
    */
    protected Node.Property createInterfacesProperty(boolean canW) {
        Node.Property prop = createInterfacesProperty(getJavaClass(), canW); 

        if (isInterface) {
            prop.setDisplayName(getString("PROP_superInterfaces")); // NOI18N
            prop.setShortDescription(getString("HINT_superInterfaces")); // NOI18N
        }
        prop.setValue("changeImmediate" /* PropertyEnv.PROP_CHANGE_IMMEDIATE */, Boolean.FALSE); // NOI18N
        setModel(getJavaClass(), prop);
        
        return prop;
    }
    
    Node.Property createTypeParametersProperty() {
        Node.Property np = createTypeParametersProperty(PROP_TYPE_PARAMETERS, getJavaClass(), false);
        np.setValue("changeImmediate" /* PropertyEnv.PROP_CHANGE_IMMEDIATE */, Boolean.FALSE); // NOI18N
        return np;
    }

    public NewType[] getNewTypes() {
        if (writeable) {
            boolean jdk15 = sourceDO != null?
                    SourceEditSupport.isJDK15Supported(sourceDO.getPrimaryFile()):
                    false;
            if (isInterface) {
                return SourceEditSupport.createInterfaceNewTypes(this.getJavaClass(), jdk15);
            } else {
                return SourceEditSupport.createClassNewTypes(this.getJavaClass(), jdk15);
            }
        } else {
            return super.getNewTypes();
        }
    }
    
    /** Create a node property for the implemented interfaces of this class.
     * (Or, extended interfaces if this is itself an interface.)
     * @param element element implementing or extending interfaces
     * @param canW false to force property to be read-only
     * @return the property
     */
    public static Node.Property createInterfacesProperty(JavaClass element, boolean canW) {
        Node.Property prop = new InterfacesProperty(element, canW);
        setModel(element, prop);
        return prop;
    }
    
    private static final class InterfacesProperty extends ElementNode.ElementProp {
        
        private final JavaClass element;
        
        public InterfacesProperty(JavaClass element, boolean canW) {
            super(PROP_INTERFACES, MultipartId[].class, canW);
            this.element = element;
        }

        protected PropertyEditor createPropertyEditor() {
            return new IdentifierArrayEditor();
        }

        public Object getValue () {
            return element.getInterfaceNames().toArray(new MultipartId[0]);
        }

        public void setValue(final Object val) throws IllegalArgumentException,
                IllegalAccessException, InvocationTargetException {
            super.setValue(val);
            if (!(val instanceof MultipartId[]))
                throw new IllegalArgumentException();
                                   
            boolean fail = true;
            try {
                JavaMetamodel.getDefaultRepository().beginTrans(true);
                try {
                    List l = element.getInterfaceNames();
                    l.clear();
                    l.addAll(Arrays.asList((MultipartId[]) val));
                    fail = false;
                } finally {
                    JavaMetamodel.getDefaultRepository().endTrans(fail);
                }
            } catch (JmiException ex) {
                IllegalArgumentException iaex = new IllegalArgumentException();
                iaex.initCause(ex);
                throw ex;
            }
        }
    }
}
... 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.