|
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.java.ui.nodes.elements; import java.awt.Component; import java.io.IOException; import java.lang.reflect.Modifier; import java.util.*; import java.beans.PropertyEditor; import org.netbeans.modules.java.ui.nodes.elements.*; import org.netbeans.modules.java.ui.nodes.editors.ModifierEditor; import org.netbeans.modules.java.JavaNode; import org.netbeans.modules.javacore.internalapi.JavaMetamodel; import org.netbeans.jmi.javamodel.*; import org.netbeans.jmi.javamodel.Type; import org.netbeans.api.java.queries.SourceLevelQuery; import org.openide.*; import org.openide.explorer.propertysheet.PropertyPanel; import org.openide.filesystems.FileObject; import org.openide.util.*; import org.openide.util.datatransfer.NewType; import javax.jmi.reflect.JmiException; /** This class defines utilities for editing source using JMI API, * e.g. creation new types for class elements, ... * * @author Petr Hamernik, Jan Pokorsky */ public final class SourceEditSupport { static final byte NT_INITIALIZER = 0; static final byte NT_FIELD = 1; static final byte NT_CONSTRUCTOR = 2; static final byte NT_METHOD = 3; static final byte NT_INNERCLASS = 4; static final byte NT_INNERINTERFACE = 5; static final byte NT_INNERENUM = 6; static final byte NT_ENUMCONSTANT = 7; static final byte NT_CLASS = 8; static final byte NT_INTERFACE = 9; static final byte NT_ENUM = 10; static final byte NT_ANNOTATION_TYPE = 11; static final byte NT_INNERANNOTATION_TYPE = 12; static final byte NT_ANNOTATION_TYPE_METHOD = 13; static final String[] MENU_NAMES = { getString("MENU_CREATE_BLOCK"), getString("MENU_CREATE_VARIABLE"), // NOI18N getString("MENU_CREATE_CONSTRUCTOR"), getString("MENU_CREATE_METHOD"), // NOI18N getString("MENU_CREATE_INNERCLASS"), getString("MENU_CREATE_INNERINTERFACE"), // NOI18N getString("MENU_CREATE_INNERENUM"), getString("MENU_CREATE_CONSTANT"), // NOI18N getString("MENU_CREATE_CLASS"), getString("MENU_CREATE_INTERFACE"), // NOI18N getString("MENU_CREATE_ENUM"), getString("MENU_CREATE_ANN_TYPE"), // NOI18N getString("MENU_CREATE_INNERANN_TYPE"), getString("MENU_CREATE_ANN_TYPE_METHOD"), // NOI18N }; private static String getString(String key) { return NbBundle.getMessage(SourceEditSupport.class, key); } /** * creates class new types * @param element class * @param supportJDK15 support new 1.5 features * @return array of new type operations that are allowed * @see #isJDK15Supported */ public static NewType[] createClassNewTypes(JavaClass element, boolean supportJDK15) { NewType[] ntypes; if (supportJDK15) { ntypes = new NewType[] { new ElementNewType(element, NT_INITIALIZER), new ElementNewType(element, NT_FIELD), new ElementNewType(element, NT_CONSTRUCTOR), new ElementNewType(element, NT_METHOD), new ElementNewType(element, NT_INNERCLASS), new ElementNewType(element, NT_INNERENUM), new ElementNewType(element, NT_INNERINTERFACE), new ElementNewType(element, NT_INNERANNOTATION_TYPE), }; } else { ntypes = new NewType[] { new ElementNewType(element, NT_INITIALIZER), new ElementNewType(element, NT_FIELD), new ElementNewType(element, NT_CONSTRUCTOR), new ElementNewType(element, NT_METHOD), new ElementNewType(element, NT_INNERCLASS), new ElementNewType(element, NT_INNERINTERFACE), }; } return ntypes; } /** * creates interface new types * @param element interface * @param supportJDK15 support new 1.5 features * @return array of new type operations that are allowed * @see #isJDK15Supported */ public static NewType[] createInterfaceNewTypes(JavaClass element, boolean supportJDK15) { NewType[] ntypes; if (supportJDK15) { ntypes = new NewType[] { new ElementNewType(element, NT_FIELD), new ElementNewType(element, NT_METHOD), new ElementNewType(element, NT_INNERCLASS), new ElementNewType(element, NT_INNERENUM), new ElementNewType(element, NT_INNERINTERFACE), new ElementNewType(element, NT_INNERANNOTATION_TYPE), }; } else { ntypes = new NewType[] { new ElementNewType(element, NT_FIELD), new ElementNewType(element, NT_METHOD), new ElementNewType(element, NT_INNERCLASS), new ElementNewType(element, NT_INNERINTERFACE), }; } return ntypes; } /** * creates enum new types * @param element enum * @return array of new type operations that are allowed */ public static NewType[] createEnumNewTypes(JavaEnum element) { return new NewType[] { new ElementNewType(element, NT_ENUMCONSTANT), new ElementNewType(element, NT_INITIALIZER), new ElementNewType(element, NT_FIELD), new ElementNewType(element, NT_CONSTRUCTOR), new ElementNewType(element, NT_METHOD), new ElementNewType(element, NT_INNERCLASS), new ElementNewType(element, NT_INNERENUM), new ElementNewType(element, NT_INNERINTERFACE), new ElementNewType(element, NT_INNERANNOTATION_TYPE), }; } /** * creates annotation type new types * @param element annotation type * @return array of new type operations that are allowed */ public static NewType[] createInterfaceNewTypes(AnnotationType element) { return new NewType[] { new ElementNewType(element, NT_FIELD), new ElementNewType(element, NT_ANNOTATION_TYPE_METHOD), new ElementNewType(element, NT_INNERCLASS), new ElementNewType(element, NT_INNERENUM), new ElementNewType(element, NT_INNERINTERFACE), new ElementNewType(element, NT_INNERANNOTATION_TYPE), }; } /** * creates java node new types * @param node node * @return array of new type operations that are allowed */ public static NewType[] createJavaNodeNewTypes(JavaNode node) { NewType[] ntypes; if (isJDK15Supported(node.getDataObject().getPrimaryFile())) { ntypes = new NewType[] { new ElementNewType(node, NT_CLASS), new ElementNewType(node, NT_ENUM), new ElementNewType(node, NT_INTERFACE), new ElementNewType(node, NT_ANNOTATION_TYPE), }; } else { ntypes = new NewType[] { new ElementNewType(node, NT_CLASS), new ElementNewType(node, NT_INTERFACE), }; } return ntypes; } public static boolean isJDK15Supported(FileObject source) { String version = SourceLevelQuery.getSourceLevel(source); return version != null && version.startsWith("1.5"); // NOI18N } /** New types for JavaClass */ static final class ElementNewType extends NewType { /** Class element where to create new element */ private final JavaClass element; /** Resource where to create new element */ private final JavaNode node; /** The kind of element to create */ byte kind; private static final String NEW_FIELD_NAME = "newField"; // NOI18N private static final String NEW_METHOD_NAME = "newMethod"; // NOI18N private static final String NEW_ANN_TYPE_METHOD_NAME = "newMethod"; // NOI18N private static final String NEW_INNERCLASS_NAME = "InnerClass"; // NOI18N private static final String NEW_INNERINTERFACE_NAME = "InnerInterface"; // NOI18N private static final String NEW_INNERENUM_NAME = "InnerEnum"; // NOI18N private static final String NEW_INNERANN_TYPE_NAME = "InnerNewAnnotationType"; // NOI18N private static final String NEW_CLASS_NAME = "NewClass"; // NOI18N private static final String NEW_INTERFACE_NAME = "NewInterface"; // NOI18N private static final String NEW_ENUM_NAME = "NewEnum"; // NOI18N private static final String NEW_ANN_TYPE_NAME = "NewAnnotationType"; // NOI18N /** Creates new type * @param element Where to create new element. * @param kind The kind of the element to create */ public ElementNewType(JavaClass element, byte kind) { this.element = element; this.node = null; this.kind = kind; } /** Creates new type * @param node resource where to create new element. * @param kind The kind of the element to create */ public ElementNewType(JavaNode node, byte kind) { this.element = null; this.node = node; this.kind = kind; } /** Get the name of the new type. * @return localized name. */ public String getName() { return MENU_NAMES[kind]; } /** Help context */ public org.openide.util.HelpCtx getHelpCtx() { return new org.openide.util.HelpCtx (SourceEditSupport.class.getName () + ".newElement" + kind); // NOI18N } /** Creates new element */ public void create () throws IOException { boolean fail = true; try { JavaMetamodel.getDefaultRepository().beginTrans(true); try { createImpl(); fail = false; } finally { JavaMetamodel.getDefaultRepository().endTrans(fail); } } catch (JmiException ex) { IOException ioe = new IOException(); ioe.initCause(ex); throw ioe; } } /** * * @throws JmiException */ private void createImpl() throws JmiException { JavaModelPackage jmodel = getModel(); switch (kind) { case NT_INITIALIZER: createInitializer(jmodel); break; case NT_FIELD: createField(jmodel); break; case NT_CONSTRUCTOR: createConstructor(jmodel); break; case NT_METHOD: createMethod(jmodel); break; case NT_INNERCLASS: createInnerClass(jmodel); break; case NT_INNERINTERFACE: createInnerInterface(jmodel); break; case NT_INNERENUM: createInnerEnum(jmodel); break; case NT_ENUMCONSTANT: createConstant(jmodel); break; case NT_CLASS: createClass(jmodel); break; case NT_INTERFACE: createInterface(jmodel); break; case NT_ENUM: createEnum(jmodel); break; case NT_ANNOTATION_TYPE: createAnnotationType(jmodel); break; case NT_INNERANNOTATION_TYPE: createInnerAnnotationType(jmodel); break; case NT_ANNOTATION_TYPE_METHOD: createAnnotationTypeMethod(jmodel); break; default: assert true: "Unknown new type: " + kind; // NOI18N } } private void createInnerInterface(JavaModelPackage jmodel) throws JmiException { // Adding inner interface String name = NEW_INNERINTERFACE_NAME; for (int index = 1; element.getInnerClass(name, true) != null; index++) { name = NEW_INNERINTERFACE_NAME + '_' + index; } JavaClass e = jmodel.getJavaClass().createJavaClass( name, null, Modifier.PUBLIC, null, null, null, null, null, null ); e.setInterface(true); ClassCustomizer cust = new ClassCustomizer(element, e); if (openCustomizer(cust, "TIT_NewInnerInterface") && cust.isOK()) { // NOI18N addFeature(e); } } private void createInnerClass(JavaModelPackage jmodel) throws JmiException { // Adding inner class String name = NEW_INNERCLASS_NAME; for (int index = 1; element.getInnerClass(name, true) != null; index++) { name = NEW_INNERCLASS_NAME + '_' + index; } JavaClass e = jmodel.getJavaClass().createJavaClass( name, null, Modifier.PUBLIC | Modifier.FINAL, null, null, null, null, null, null ); e.setInterface(false); ClassCustomizer cust = new ClassCustomizer(element, e); if (openCustomizer(cust, "TIT_NewInnerClass") && cust.isOK()) { // NOI18N addFeature(e); } } private void createInterface(JavaModelPackage jmodel) throws JmiException { // Adding inner interface String name = NEW_INTERFACE_NAME; Resource resource = getResource(); for (int index = 1; findTopLevelClass(resource, name) != null; index++) { name = NEW_INTERFACE_NAME + '_' + index; } JavaClass e = jmodel.getJavaClass().createJavaClass( name, null, 0, null, null, null, null, null, null ); e.setInterface(true); ClassCustomizer cust = new ClassCustomizer(resource, e); if (openCustomizer(cust, "TIT_NewInterface") && cust.isOK()) { // NOI18N resource.getClassifiers().add(e); } } private void createClass(JavaModelPackage jmodel) throws JmiException { // Adding inner class String name = NEW_CLASS_NAME; Resource resource = getResource(); for (int index = 1; findTopLevelClass(resource, name) != null; index++) { name = NEW_CLASS_NAME + '_' + index; } JavaClass e = jmodel.getJavaClass().createJavaClass( name, null, Modifier.FINAL, null, null, null, null, null, null ); e.setInterface(false); ClassCustomizer cust = new ClassCustomizer(resource, e); if (openCustomizer(cust, "TIT_NewClass") && cust.isOK()) { // NOI18N resource.getClassifiers().add(e); } } private void createMethod(JavaModelPackage jmodel) throws JmiException { // Adding method Method e = jmodel.getMethod().createMethod(); Type voidType = jmodel.getType().resolve(PrimitiveTypeKindEnum.VOID.toString()); e.setType(voidType); String name = NEW_METHOD_NAME; for (int index = 1; element.getMethod(name, Collections.EMPTY_LIST, true) != null; index++) { name = NEW_METHOD_NAME + '_' + index; } e.setName(name); e.setModifiers(Modifier.PUBLIC); MethodCustomizer cust = new MethodCustomizer(element, e); if (openCustomizer(cust, "TIT_NewMethod") && cust.isOK()) { // NOI18N addFeature(e); } } private void createConstructor(JavaModelPackage jmodel) throws JmiException { // Adding constructor Constructor e = jmodel.getConstructor().createConstructor(); if (!(this.element instanceof JavaEnum)) e.setModifiers(Modifier.PUBLIC); MethodCustomizer cust = new MethodCustomizer(element, e); if (openCustomizer(cust, "TIT_NewConstructor") && cust.isOK()) { // NOI18N addFeature(e); } } private void createField(JavaModelPackage jmodel) throws JmiException { // Adding field Field e = jmodel.getField().createField(); Type type = jmodel.getType().resolve("int"); // NOI18N e.setType(type); String name = NEW_FIELD_NAME; for (int index = 1; element.getField(name, true) != null; index++) { name = NEW_FIELD_NAME + '_' + index; } e.setName(name); boolean outerIsClass = !element.isInterface(); e.setModifiers(outerIsClass? Modifier.PRIVATE : Modifier.PUBLIC | Modifier.STATIC); FieldCustomizer cust = new FieldCustomizer(element, e); if (openCustomizer(cust, "TIT_NewField") && cust.isOK()) { // NOI18N addFeature(e); } } private void createInitializer(JavaModelPackage jmodel) throws JmiException { // Adding initializer Initializer e = jmodel.getInitializer().createInitializer(); e.setModifiers(Modifier.STATIC); addFeature(e); } private void createInnerEnum(JavaModelPackage jmodel) throws JmiException { // Adding inner enum String name = NEW_INNERENUM_NAME; for (int index = 1; element.getInnerClass(name, true) != null; index++) { name = NEW_INNERENUM_NAME + '_' + index; } JavaEnum e = jmodel.getJavaEnum().createJavaEnum( name, null, Modifier.PUBLIC, null, null, null, null, null, null, null ); EnumCustomizer cust = new EnumCustomizer(element, e); if (openCustomizer(cust, "TIT_NewInnerEnum") && cust.isOK()) { // NOI18N addFeature(e); } } private void createEnum(JavaModelPackage jmodel) throws JmiException { // Adding enum String name = NEW_ENUM_NAME; Resource resource = getResource(); for (int index = 1; findTopLevelClass(resource, name) != null; index++) { name = NEW_ENUM_NAME + '_' + index; } JavaEnum e = jmodel.getJavaEnum().createJavaEnum( name, null, 0, null, null, null, null, null, null, null ); EnumCustomizer cust = new EnumCustomizer(resource, e); if (openCustomizer(cust, "TIT_NewEnum") && cust.isOK()) { // NOI18N resource.getClassifiers().add(e); } } private void createConstant(JavaModelPackage jmodel) throws JmiException { JavaEnum en = (JavaEnum) this.element; EnumConstant e = jmodel.getEnumConstant().createEnumConstant(); final String ENUM_NAME = en.getSimpleName(); String name = ENUM_NAME; for (int index = 1; findConstant(en, name) != null; index++) { name = ENUM_NAME + '_' + index; } e.setName(name); EnumConstantCustomizer cust = new EnumConstantCustomizer(en, e); if (openCustomizer(cust, "TIT_NewConstant") && cust.isOK()) { // NOI18N en.getConstants().add(e); } return; } private void createInnerAnnotationType(JavaModelPackage jmodel) throws JmiException { // Adding inner annotation type String name = NEW_INNERANN_TYPE_NAME; for (int index = 1; element.getInnerClass(name, true) != null; index++) { name = NEW_INNERANN_TYPE_NAME + '_' + index; } AnnotationType at = jmodel.getAnnotationType().createAnnotationType( name, null, Modifier.PUBLIC, null, null, null, null, null, null ); AnnotationTypeCustomizer cust = new AnnotationTypeCustomizer(element, at); if (openCustomizer(cust, "TIT_NewInnerAnnType") && cust.isOK()) { // NOI18N addFeature(at); } } private void createAnnotationType(JavaModelPackage jmodel) throws JmiException { // Adding enum String name = NEW_ANN_TYPE_NAME; Resource resource = getResource(); for (int index = 1; findTopLevelClass(resource, name) != null; index++) { name = NEW_ANN_TYPE_NAME + '_' + index; } AnnotationType at = jmodel.getAnnotationType().createAnnotationType( name, null, Modifier.PUBLIC, null, null, null, null, null, null ); AnnotationTypeCustomizer cust = new AnnotationTypeCustomizer(resource, at); if (openCustomizer(cust, "TIT_NewAnnType") && cust.isOK()) { // NOI18N resource.getClassifiers().add(at); } } private void createAnnotationTypeMethod(JavaModelPackage jmodel) throws JmiException { // Adding annotation type method AnnotationType at = (AnnotationType) this.element; String name = NEW_ANN_TYPE_METHOD_NAME; for (int index = 1; findAttribute(at, name) != null; index++) { name = NEW_ANN_TYPE_METHOD_NAME + '_' + index; } Type type = jmodel.getType().resolve("java.lang.String"); // NOI18N Attribute attr = jmodel.getAttribute().createAttribute(name, null, 0, null, null, null, null, null); attr.setType(type); AnnotationTypeMethodCustomizer cust = new AnnotationTypeMethodCustomizer(at, attr); if (openCustomizer(cust, "TIT_NewAnnTypeMethod") && cust.isOK()) { // NOI18N addFeature(attr); } } /* This method prevents features to be inserted into gurded blocks. * It is a temporal solution - we need to fix the problem in javacore. */ private void addFeature(Feature feature) { List features = new ArrayList(element.getFeatures()); // [PENDING] workaround for buggy FeaturesListIterator ListIterator iter = features.listIterator(features.size()); ClassMember f = iter.hasPrevious() ? (ClassMember)iter.previous() : null; JavaMetamodel manager = JavaMetamodel.getManager(); if (f == null || !manager.isElementGuarded(f)) { element.getFeatures().add(feature); return; } do { f = (ClassMember)iter.previous(); } while (f != null && manager.isElementGuarded(f)); iter = element.getFeatures().listIterator(); if (f != null) { for (; iter.next() != f; ); } iter.add(feature); } private Resource getResource() { return JavaMetamodel.getManager().getResource(node.getDataObject().getPrimaryFile()); } private JavaModelPackage getModel() { if (this.element != null) { return JavaMetamodel.getManager().getJavaExtent(this.element); } else { return JavaMetamodel.getManager().getJavaExtent(getResource()); } } } /** * finds attribute (annotation type method) in a annotation type * @param at annotation type to query * @param name name to find * @return the attribute or |
... 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.