--- a/spi.palette/apichanges.xml +++ a/spi.palette/apichanges.xml @@ -110,6 +110,22 @@ + Introduced PaletteItemRegistration and PaletteItemRegistrations + + + + + +

+ Introduced a new annotation for registering palette items. +

+
+ + + +
+ + Deprecating ModuleInstall --- a/spi.palette/manifest.mf +++ a/spi.palette/manifest.mf @@ -1,5 +1,5 @@ Manifest-Version: 1.0 OpenIDE-Module: org.netbeans.spi.palette/1 OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/palette/resources/Bundle.properties -OpenIDE-Module-Specification-Version: 1.39 +OpenIDE-Module-Specification-Version: 1.40 OpenIDE-Module-Layer: org/netbeans/modules/palette/resources/layer.xml --- a/spi.palette/nbproject/project.xml +++ a/spi.palette/nbproject/project.xml @@ -176,6 +176,11 @@ org.openide.modules + + org.openide.util.lookup + + + --- a/spi.palette/src/org/netbeans/modules/palette/PaletteItemRegistrationProcessor.java +++ a/spi.palette/src/org/netbeans/modules/palette/PaletteItemRegistrationProcessor.java @@ -0,0 +1,165 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2013 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + * + * Portions Copyrighted 2013 Sun Microsystems, Inc. + */ +package org.netbeans.modules.palette; + +import java.util.Set; +import javax.annotation.processing.Processor; +import javax.annotation.processing.RoundEnvironment; +import javax.annotation.processing.SupportedAnnotationTypes; +import javax.annotation.processing.SupportedSourceVersion; +import javax.lang.model.SourceVersion; +import javax.lang.model.element.Element; +import javax.lang.model.element.ElementKind; +import javax.lang.model.element.TypeElement; +import javax.lang.model.type.TypeMirror; +import org.netbeans.spi.palette.PaletteItemRegistration; +import org.netbeans.spi.palette.PaletteItemRegistrations; +import org.openide.filesystems.annotations.LayerBuilder; +import org.openide.filesystems.annotations.LayerGeneratingProcessor; +import org.openide.filesystems.annotations.LayerGenerationException; +import org.openide.text.ActiveEditorDrop; +import org.openide.util.lookup.ServiceProvider; + +/** + * Processor for PaletteItemRegistration. + * + * @author Eric Barboni + */ +@ServiceProvider(service = Processor.class) +@SupportedSourceVersion(SourceVersion.RELEASE_6) +@SupportedAnnotationTypes({"org.netbeans.spi.palette.PaletteItemRegistration", "org.netbeans.spi.palette.PaletteItemRegistrations"}) +public final class PaletteItemRegistrationProcessor extends LayerGeneratingProcessor { + + @Override + protected boolean handleProcess(Set annotations, RoundEnvironment roundEnv) throws LayerGenerationException { + + if (roundEnv.processingOver()) { + return false; + } + + for (Element e : roundEnv.getElementsAnnotatedWith(PaletteItemRegistration.class)) { + PaletteItemRegistration pir = e.getAnnotation(PaletteItemRegistration.class); + if (pir == null) { + continue; + } + process(e, pir); + } + for (Element e : roundEnv.getElementsAnnotatedWith(PaletteItemRegistrations.class)) { + PaletteItemRegistrations dfrr = e.getAnnotation(PaletteItemRegistrations.class); + if (dfrr == null) { + continue; + } + for (PaletteItemRegistration t : dfrr.value()) { + process(e, t); + } + } + return true; + } + + private void process(Element e, PaletteItemRegistration pir) throws LayerGenerationException { + LayerBuilder builder = layer(e); + TypeMirror activeEditorDrop = type(ActiveEditorDrop.class); + + LayerBuilder.File f = builder.file(pir.paletteid() + "/" + pir.category() + "/" + pir.itemid() + ".xml"); + StringBuilder paletteFile = new StringBuilder(); + + paletteFile.append("\n"); + paletteFile.append("\n"); + + if (pir.body().isEmpty()) { + // body empty we need a activeEditorDrop + if (e.getKind() == ElementKind.CLASS && isAssignable(e.asType(), activeEditorDrop)) { + String className = processingEnv.getElementUtils().getBinaryName((TypeElement) e).toString(); + paletteFile.append(" \n"); + } else { + throw new LayerGenerationException("Class annotated with @PaletteItemRegistration has to implements ActiveEditorDrop", e); + } + } else { + // body not empty put info + paletteFile.append(" \n"); + } + +// icon shoud be in classpath + if (!pir.icon16().isEmpty()) { + builder.validateResource(pir.icon16(), e.getEnclosingElement(), pir, "icon16", true); + paletteFile.append("\n"); + } else { + throw new LayerGenerationException("Icon 16 must be set ", e); + } + if (!pir.icon32().isEmpty()) { + builder.validateResource(pir.icon32(), e.getEnclosingElement(), pir, "icon32", true); + paletteFile.append("\n"); + } else { + throw new LayerGenerationException("Icon 32 must be set ", e); + } + + paletteFile.append(""); + paletteFile.append(""); + paletteFile.append(pir.name()); + paletteFile.append(""); + paletteFile.append(" "); + paletteFile.append(""); + + paletteFile.append(""); + + f.contents(paletteFile.toString()); + f.write(); + } + + // XXX come from other processor in openide + private boolean isAssignable(TypeMirror first, TypeMirror snd) { + if (snd == null) { + return false; + } else { + return processingEnv.getTypeUtils().isAssignable(first, snd); + } + } + // XXX come from other processor in openide + private TypeMirror type(Class type) { + final TypeElement e = processingEnv.getElementUtils().getTypeElement(type.getCanonicalName()); + return e == null ? null : e.asType(); + } +} --- a/spi.palette/src/org/netbeans/spi/palette/PaletteItemRegistration.java +++ a/spi.palette/src/org/netbeans/spi/palette/PaletteItemRegistration.java @@ -0,0 +1,108 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2012 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + * + * Portions Copyrighted 2012 Sun Microsystems, Inc. + */ +package org.netbeans.spi.palette; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Register a palette item. + * + * This annotation may be used at two level: + *
    + *
  • at package level body MUST be set;
  • + *
  • at class level on class implementing + * {@link ActiveEditorDrop}.
  • + *
+ * + * @author Eric Barboni + * @since 1.32 + */ +@Retention(RetentionPolicy.SOURCE) +@Target({ElementType.TYPE, ElementType.PACKAGE}) +public @interface PaletteItemRegistration { + + /** + * Palette root name. + */ + String paletteid(); + + /** + * category for palette item. + */ + String category(); + + /** + * itemid for palette item. + */ + String itemid(); + + /** + * body of palette item. + */ + String body() default ""; + + /** + * Path to a 16x16 image file for palette item. + * + */ + String icon16(); + + /** + * Path to a 32x32 image file for palette item. + * + */ + String icon32(); + + /** + * Name for palette item. + */ + String name(); + + /** + * Tooltip text for palette item. + * + */ + String tooltip(); +} --- a/spi.palette/src/org/netbeans/spi/palette/PaletteItemRegistrations.java +++ a/spi.palette/src/org/netbeans/spi/palette/PaletteItemRegistrations.java @@ -0,0 +1,65 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2012 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + * + * Portions Copyrighted 2012 Sun Microsystems, Inc. + */ +package org.netbeans.spi.palette; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * May be uses to allow multiple + * {@link PaletteItemRegistration PaletteItemRegistration} at one place. + * + * @author Eric Barboni + * + * @since 1.32 + */ +@Retention(RetentionPolicy.SOURCE) +@Target({ElementType.PACKAGE}) +public @interface PaletteItemRegistrations { + + /** + * array of Paletteitemregistration. + */ + PaletteItemRegistration[] value(); +} --- a/spi.palette/test/unit/src/org/netbeans/modules/palette/PaletteItemRegistrationProcessorTest.java +++ a/spi.palette/test/unit/src/org/netbeans/modules/palette/PaletteItemRegistrationProcessorTest.java @@ -0,0 +1,170 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2013 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + * + * Portions Copyrighted 2013 Sun Microsystems, Inc. + */ +package org.netbeans.modules.palette; + +import java.awt.GraphicsEnvironment; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import static junit.framework.Assert.assertFalse; +import static junit.framework.Assert.assertTrue; +import org.netbeans.junit.NbTestCase; +import org.openide.util.test.AnnotationProcessorTestUtils; + +/** + * + * @author Didier + */ +public class PaletteItemRegistrationProcessorTest extends NbTestCase { + + static { + System.setProperty("java.awt.headless", "true"); + } + + public PaletteItemRegistrationProcessorTest(String n) { + super(n); + } + + @Override + protected boolean runInEQ() { + return true; + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + } + private static final String VALID_CLASS_ANNOTATION = "@PaletteItemRegistration(paletteid = \"JavaPalette\", category = \"dummycat\", itemid = \"myitem\"," + + "icon16 = \"org/netbeans/modules/palette/resources/unknown16.gif\", " + + "icon32 = \"org/netbeans/modules/palette/resources/unknown32.gif\", tooltip = \"tooltip\", name = \"name\")"; + private static final String VALID_PACKAGE_ANNOTATION = "@PaletteItemRegistration(paletteid = \"JavaPalette\", category = \"dummycat\", itemid = \"myitem\"," + + "icon16 = \"org/netbeans/modules/palette/resources/unknown16.gif\", " + + "icon32 = \"org/netbeans/modules/palette/resources/unknown32.gif\", tooltip = \"tooltip\", name = \"name\" ,body =\"mydummybody\")"; + private static final String INVALID_CLASS_ANNOTATION_1 = "@PaletteItemRegistration(paletteid = \"JavaPalette\", category = \"dummycat\", itemid = \"myitem\"," + + "icon32 = \"org/netbeans/modules/palette/resources/unknown32.gif\", tooltip = \"tooltip\", name = \"name\")"; + private static final String INVALID_CLASS_ANNOTATION_2 = "@PaletteItemRegistration(paletteid = \"JavaPalette\", category = \"dummycat\", itemid = \"myitem\"," + + "icon16 = \"org/netbeans/modules/palette/resources/unknown16.gif\", tooltip = \"tooltip\", name = \"name\")"; + + public void testNoCompliantClassAnnotated() throws IOException { + clearWorkDir(); + assertTrue("Headless run", GraphicsEnvironment.isHeadless()); + AnnotationProcessorTestUtils.makeSource(getWorkDir(), "test.A", + "import org.netbeans.spi.palette.PaletteItemRegistration;\n" + + VALID_CLASS_ANNOTATION + + "public class A {\n" + + " A() {}" + + "}\n"); + ByteArrayOutputStream os = new ByteArrayOutputStream(); + boolean r = AnnotationProcessorTestUtils.runJavac(getWorkDir(), null, getWorkDir(), null, os); + assertFalse("Compilation has to fail:\n" + os, r); + } + + public void testActiveEditorDropAnnotated() throws IOException { + clearWorkDir(); + assertTrue("Headless run", GraphicsEnvironment.isHeadless()); + AnnotationProcessorTestUtils.makeSource(getWorkDir(), "test.B", + "import org.netbeans.spi.palette.PaletteItemRegistration;\n" + + "import org.openide.text.ActiveEditorDrop;\n;import javax.swing.text.JTextComponent;" + + VALID_CLASS_ANNOTATION + + "public class B implements ActiveEditorDrop {\n" + + " public boolean handleTransfer(JTextComponent targetComponent) {return true; }" + + "}\n"); + ByteArrayOutputStream os = new ByteArrayOutputStream(); + boolean r = AnnotationProcessorTestUtils.runJavac(getWorkDir(), null, getWorkDir(), null, os); + assertTrue("Compilation has to be successfull:\n" + os, r); + } + + public void testActiveEditorDropAnnotatedWithMissingIcon16() throws IOException { + clearWorkDir(); + assertTrue("Headless run", GraphicsEnvironment.isHeadless()); + AnnotationProcessorTestUtils.makeSource(getWorkDir(), "test.B", + "import org.netbeans.spi.palette.PaletteItemRegistration;\n" + + "import org.openide.text.ActiveEditorDrop;\n;import javax.swing.text.JTextComponent;" + + INVALID_CLASS_ANNOTATION_1 + + "public class B implements ActiveEditorDrop {\n" + + " public boolean handleTransfer(JTextComponent targetComponent) {return true; }" + + "}\n"); + ByteArrayOutputStream os = new ByteArrayOutputStream(); + boolean r = AnnotationProcessorTestUtils.runJavac(getWorkDir(), null, getWorkDir(), null, os); + assertFalse("Compilation has to fail:\n" + os, r); + } + + public void testActiveEditorDropAnnotatedWithMissingIcon32() throws IOException { + clearWorkDir(); + assertTrue("Headless run", GraphicsEnvironment.isHeadless()); + AnnotationProcessorTestUtils.makeSource(getWorkDir(), "test.B", + "import org.netbeans.spi.palette.PaletteItemRegistration;\n" + + "import org.openide.text.ActiveEditorDrop;\n;import javax.swing.text.JTextComponent;" + + INVALID_CLASS_ANNOTATION_2 + + "public class B implements ActiveEditorDrop {\n" + + " public boolean handleTransfer(JTextComponent targetComponent) {return true; }" + + "}\n"); + ByteArrayOutputStream os = new ByteArrayOutputStream(); + boolean r = AnnotationProcessorTestUtils.runJavac(getWorkDir(), null, getWorkDir(), null, os); + assertFalse("Compilation has to fail:\n" + os, r); + } + + public void testInvalidAnnotatedPackage() throws IOException { + //missing body + clearWorkDir(); + assertTrue("Headless run", GraphicsEnvironment.isHeadless()); + AnnotationProcessorTestUtils.makeSource(getWorkDir(), "testb.package-info", + VALID_CLASS_ANNOTATION + + "\npackage testa\n;" + + "import org.netbeans.spi.palette.PaletteItemRegistration;\n"); + ByteArrayOutputStream os = new ByteArrayOutputStream(); + boolean r = AnnotationProcessorTestUtils.runJavac(getWorkDir(), null, getWorkDir(), null, os); + assertFalse("Compilation has to fail:\n" + os, r); + } + + public void testAnnotatedPackage() throws IOException { + //missing body + clearWorkDir(); + assertTrue("Headless run", GraphicsEnvironment.isHeadless()); + AnnotationProcessorTestUtils.makeSource(getWorkDir(), "testa.package-info", + VALID_PACKAGE_ANNOTATION + + "\npackage testa\n;" + + "import org.netbeans.spi.palette.PaletteItemRegistration;\n"); + ByteArrayOutputStream os = new ByteArrayOutputStream(); + boolean r = AnnotationProcessorTestUtils.runJavac(getWorkDir(), null, getWorkDir(), null, os); + assertTrue("Compilation has to be successfull:\n" + os, r); + } +}