# HG changeset patch # Parent b012743f2aafc19652361552ff442f67a2c0f08b diff --git a/openide.loaders/apichanges.xml b/openide.loaders/apichanges.xml --- a/openide.loaders/apichanges.xml +++ b/openide.loaders/apichanges.xml @@ -111,7 +111,7 @@ - Introduced DataObject.Registration + Introduced DataObject.Registration and DataObject.Registrations @@ -123,6 +123,7 @@ + diff --git a/openide.loaders/src/org/netbeans/modules/openide/loaders/DataObjectFactoryProcessor.java b/openide.loaders/src/org/netbeans/modules/openide/loaders/DataObjectFactoryProcessor.java --- a/openide.loaders/src/org/netbeans/modules/openide/loaders/DataObjectFactoryProcessor.java +++ b/openide.loaders/src/org/netbeans/modules/openide/loaders/DataObjectFactoryProcessor.java @@ -68,116 +68,121 @@ */ @ServiceProvider(service = Processor.class) @SupportedSourceVersion(SourceVersion.RELEASE_6) -@SupportedAnnotationTypes("org.openide.loaders.DataObject.Registration") +@SupportedAnnotationTypes({"org.openide.loaders.DataObject.Registration", "org.openide.loaders.DataObject.Registrations"}) public class DataObjectFactoryProcessor extends LayerGeneratingProcessor { + @Override protected boolean handleProcess(Set annotations, RoundEnvironment roundEnv) throws LayerGenerationException { if (roundEnv.processingOver()) { return false; } - TypeMirror dataObjectType = type(DataObject.class); - TypeMirror fileObjectType = type(FileObject.class); - TypeMirror multiFileLoaderType = type(MultiFileLoader.class); - TypeMirror dataObjectFactoryType = type(DataObject.Factory.class); - for (Element e : roundEnv.getElementsAnnotatedWith(DataObject.Registration.class)) { DataObject.Registration dfr = e.getAnnotation(DataObject.Registration.class); if (dfr == null) { continue; } - LayerBuilder builder = layer(e); - //need class name to generate id and factory dataObjectClass parameter - String className = processingEnv.getElementUtils().getBinaryName((TypeElement)e).toString(); - String factoryId = className.replace(".", "-"); - - boolean useFactory = true; - - // test if enclosing element is of DataObject type; - - if (isAssignable(e.asType(), dataObjectType)) { - //attempt to use default factory - List ee = new LinkedList(); - // should be a public constructor with FileObject and MultiFileLoader as param - for (ExecutableElement element : ElementFilter.constructorsIn(e.getEnclosedElements())) { - - if ((element.getKind() == ElementKind.CONSTRUCTOR) && (element.getModifiers().contains(Modifier.PUBLIC))) { // found a public constructor ; - if ((element.getParameters().size() == 2) // parameters of constructor ok - && (isAssignable(element.getParameters().get(0).asType(), fileObjectType)) - && (isAssignable(element.getParameters().get(1).asType(), multiFileLoaderType))) { - ee.add(element); - } - } - } - // nothing is found - if (ee.isEmpty()) { - throw new LayerGenerationException("DataObject subclass with @DataObject.Registration needs a public constructor with FileObject and MultiFileLoader parameters", e, processingEnv, dfr); // NOI18N - } else { - useFactory = true; - } - - } else if (isAssignable(e.asType(), dataObjectFactoryType)) { - List ee = new LinkedList(); - for (ExecutableElement element : ElementFilter.constructorsIn(e.getEnclosedElements())) { - if ((element.getKind() == ElementKind.CONSTRUCTOR) && (element.getModifiers().contains(Modifier.PUBLIC))) { // found a public constructor ; - if ((element.getParameters().isEmpty())) {// parameters of constructor ok - ee.add(element); - } - } - } - if (ee.isEmpty()) { - throw new LayerGenerationException("DataObject.Factory subclass with @DataObject.Registration needs a public default constructor", e, processingEnv, dfr); // NOI18N - } else { - useFactory = false; - factoryId = className.replace(".class", "").replace(".", "-"); - } - } else { - throw new LayerGenerationException("Usage @DataObject.Registration only on DataObject.Factory subclass or DataObject subclass", e, processingEnv, dfr); // NOI18N + process(e, dfr); + } + for (Element e : roundEnv.getElementsAnnotatedWith(DataObject.Registrations.class)) { + DataObject.Registrations dfrr = e.getAnnotation(DataObject.Registrations.class); + if (dfrr == null) { + continue; } - - // check if mimeType annotation is set - if (dfr.mimeType().length == 0) { - throw new LayerGenerationException("@DataObject.Factory.Registration mimeTypes() cannot be null", e, processingEnv, dfr, "mimeTypes"); + for (DataObject.Registration t : dfrr.value()) { + process(e, t); } - // verify if all mimeType are valid - for (String aMimeType : dfr.mimeType()) { - if (aMimeType.isEmpty()) { - throw new LayerGenerationException("@DataObject.Factory.Registration mimeTypes() cannot have a empty mimeType", e, processingEnv, dfr, "mimeTypes"); - } - } - - - for (String aMimeType : dfr.mimeType()) { - LayerBuilder.File f = builder.file("Loaders/" + aMimeType + "/Factories/" + factoryId + ".instance"); - - // iconBase is optional but if set then shoud be in classpath - if (dfr.iconBase().length() > 0) { - builder.validateResource(dfr.iconBase(), e.getEnclosingElement(), dfr, "icon", true); - f.stringvalue("iconBase", dfr.iconBase()); - } - // position LayerBuilder - f.position(dfr.position()); - - if (!dfr.displayName().isEmpty()) { - f.bundlevalue("displayName", dfr.displayName(), dfr, "displayName"); - } - - if (useFactory) { - f.methodvalue("instanceCreate", "org.openide.loaders.DataLoaderPool", "factory"); - f.stringvalue("dataObjectClass", className); - // if factory mimetype is needed otherwise not - f.stringvalue("mimeType", aMimeType); - - } - f.write(); - } - } - return true; } - // reuse from Action Processor + // + private void process(Element e, DataObject.Registration dfr) throws LayerGenerationException { + TypeMirror dataObjectType = type(DataObject.class); + TypeMirror fileObjectType = type(FileObject.class); + TypeMirror multiFileLoaderType = type(MultiFileLoader.class); + TypeMirror dataObjectFactoryType = type(DataObject.Factory.class); + LayerBuilder builder = layer(e); + //need class name to generate id and factory dataObjectClass parameter + String className = processingEnv.getElementUtils().getBinaryName((TypeElement) e).toString(); + String factoryId = className.replace(".", "-"); + + boolean useFactory = true; + + // test if enclosing element is of DataObject type; + + if (isAssignable(e.asType(), dataObjectType)) { + //attempt to use default factory + List ee = new LinkedList(); + // should be a public constructor with FileObject and MultiFileLoader as param + for (ExecutableElement element : ElementFilter.constructorsIn(e.getEnclosedElements())) { + + if ((element.getKind() == ElementKind.CONSTRUCTOR) && (element.getModifiers().contains(Modifier.PUBLIC))) { // found a public constructor ; + if ((element.getParameters().size() == 2) // parameters of constructor ok + && (isAssignable(element.getParameters().get(0).asType(), fileObjectType)) + && (isAssignable(element.getParameters().get(1).asType(), multiFileLoaderType))) { + ee.add(element); + } + } + } + // nothing is found + if (ee.isEmpty()) { + throw new LayerGenerationException("DataObject subclass with @DataObject.Registration needs a public constructor with FileObject and MultiFileLoader parameters", e, processingEnv, dfr); // NOI18N + } else { + useFactory = true; + } + + } else if (isAssignable(e.asType(), dataObjectFactoryType)) { + List ee = new LinkedList(); + for (ExecutableElement element : ElementFilter.constructorsIn(e.getEnclosedElements())) { + if ((element.getKind() == ElementKind.CONSTRUCTOR) && (element.getModifiers().contains(Modifier.PUBLIC))) { // found a public constructor ; + if ((element.getParameters().isEmpty())) {// parameters of constructor ok + ee.add(element); + } + } + } + if (ee.isEmpty()) { + throw new LayerGenerationException("DataObject.Factory subclass with @DataObject.Registration needs a public default constructor", e, processingEnv, dfr); // NOI18N + } else { + useFactory = false; + factoryId = className.replace(".class", "").replace(".", "-"); + } + } else { + throw new LayerGenerationException("Usage @DataObject.Registration only on DataObject.Factory subclass or DataObject subclass", e, processingEnv, dfr); // NOI18N + } + + // check if mimeType annotation is set + if (dfr.mimeType() == null) { + throw new LayerGenerationException("@DataObject.Factory.Registration mimeType() cannot be null", e, processingEnv, dfr, "mimeTypes"); + } + // verify if all mimeType are valid + + String aMimeType = dfr.mimeType(); + LayerBuilder.File f = builder.file("Loaders/" + aMimeType + "/Factories/" + factoryId + ".instance"); + + // iconBase is optional but if set then shoud be in classpath + if (dfr.iconBase().length() > 0) { + builder.validateResource(dfr.iconBase(), e.getEnclosingElement(), dfr, "icon", true); + f.stringvalue("iconBase", dfr.iconBase()); + } + + // position LayerBuilder + f.position(dfr.position()); + + if (!dfr.displayName().isEmpty()) { + f.bundlevalue("displayName", dfr.displayName(), dfr, "displayName"); + } + + if (useFactory) { + f.methodvalue("instanceCreate", "org.openide.loaders.DataLoaderPool", "factory"); + f.stringvalue("dataObjectClass", className); + // if factory mimetype is needed otherwise not + f.stringvalue("mimeType", aMimeType); + } + f.write(); + + } +// reuse from Action Processor private TypeMirror type(Class type) { final TypeElement e = processingEnv.getElementUtils().getTypeElement(type.getCanonicalName()); return e == null ? null : e.asType(); diff --git a/openide.loaders/src/org/openide/loaders/DataObject.java b/openide.loaders/src/org/openide/loaders/DataObject.java --- a/openide.loaders/src/org/openide/loaders/DataObject.java +++ b/openide.loaders/src/org/openide/loaders/DataObject.java @@ -1185,7 +1185,7 @@ * {@link MIMEResolver.ExtensionRegistration} and co. to assign * a mime types to {@link FileObject files} in the system. */ - String[] mimeType(); + String mimeType(); /** * Display name for the file type created by this registration. @@ -1206,6 +1206,18 @@ int position() default Integer.MAX_VALUE; } + /** + * May be uses to allow multiple {@link DataObject.Registration DataObject.Registration} at one place. + * @since 7.36 + */ + @Retention(RetentionPolicy.SOURCE) + @Target({ElementType.TYPE}) + public static @interface Registrations { + + Registration[] value(); + } + + /** Registry of modified data objects. * The registry permits attaching of a change listener * to be informed when the count of modified objects changes. diff --git a/openide.loaders/test/unit/src/org/netbeans/modules/openide/loaders/DataObjectFactoryProcessorTest.java b/openide.loaders/test/unit/src/org/netbeans/modules/openide/loaders/DataObjectFactoryProcessorTest.java --- a/openide.loaders/test/unit/src/org/netbeans/modules/openide/loaders/DataObjectFactoryProcessorTest.java +++ b/openide.loaders/test/unit/src/org/netbeans/modules/openide/loaders/DataObjectFactoryProcessorTest.java @@ -45,9 +45,9 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; -import java.io.PrintStream; import org.netbeans.junit.NbTestCase; import org.netbeans.modules.openide.loaders.data.DoFPDataObject; +import org.netbeans.modules.openide.loaders.data.DoFPDataObjectMultiple; import org.openide.filesystems.FileLock; import org.openide.filesystems.FileObject; import org.openide.filesystems.FileUtil; @@ -78,7 +78,6 @@ @Override protected void setUp() throws Exception { super.setUp(); - createMIMEs(); } // Several test for javac @@ -209,8 +208,7 @@ assertEquals("Icon found", "org/openide/loaders/unknown.gif", icon); assertEquals("DataObjectClass found", DoFPDataObject.class.getName(), fo.getAttribute("dataObjectClass")); - } - + } } // use external DoFP* class and their registration to test if dataobject return is good @@ -223,35 +221,19 @@ assertEquals("DataLoader type", DoFPDataObject.class, find.getClass()); } { - FileObject fo = createXmlFile("sdfsdf", ".tt2"); - assertEquals("text/test2", fo.getMIMEType()); - DataObject find = DataObject.find(fo); - assertEquals("DataLoader type", DoFPDataObject.class, find.getClass()); - } - { FileObject fo = createXmlFile("sdfsdf", ".tt3"); assertEquals("text/test3", fo.getMIMEType()); // XXX DoFPCustomLoader not loaded cannot assert for loader } + { + FileObject fo = createXmlFile("sdfsdf", ".ttm2"); + assertEquals("text/testm2", fo.getMIMEType()); + DataObject find = DataObject.find(fo); + assertEquals("DataLoader type", DoFPDataObjectMultiple.class, find.getClass()); + } } - // utility method inspired by FsMimeResolverTest - private void createMIMEs() throws Exception { -// create resolver to get tt1 extension resolve as test/test1 and do so for 3 different - FileObject resolver = FileUtil.createData(FileUtil.getConfigRoot(), "Services/MIMEResolver/resolver.xml"); - OutputStream os = resolver.getOutputStream(); - PrintStream ps = new PrintStream(os); - ps.println(""); - ps.println(""); - for (int i = 1; i < 4; i++) { - ps.println(" "); - ps.println(" "); - ps.println(" "); - ps.println(" "); - } - ps.println(""); - os.close(); - } + private FileObject createXmlFile(String content, String ext) throws Exception { FileObject file = FileUtil.createMemoryFileSystem().getRoot().createData("file" + ext); diff --git a/openide.loaders/test/unit/src/org/netbeans/modules/openide/loaders/data/DoFPDataObject.java b/openide.loaders/test/unit/src/org/netbeans/modules/openide/loaders/data/DoFPDataObject.java --- a/openide.loaders/test/unit/src/org/netbeans/modules/openide/loaders/data/DoFPDataObject.java +++ b/openide.loaders/test/unit/src/org/netbeans/modules/openide/loaders/data/DoFPDataObject.java @@ -53,7 +53,7 @@ * @see DataObjectFactoryProcessorTest * @author Eric Barboni */ -@DataObject.Registration(mimeType = {"text/test1","text/test2"}, displayName = "labeltest", position = 3565, iconBase = "org/openide/loaders/unknown.gif") +@DataObject.Registration(mimeType = "text/test1", displayName = "labeltest", position = 3565, iconBase = "org/openide/loaders/unknown.gif") public class DoFPDataObject extends DataObject { public DoFPDataObject(FileObject pf, MultiFileLoader loader) throws DataObjectExistsException { diff --git a/openide.loaders/test/unit/src/org/netbeans/modules/openide/loaders/data/DoFPDataObjectMultiple.java b/openide.loaders/test/unit/src/org/netbeans/modules/openide/loaders/data/DoFPDataObjectMultiple.java new file mode 100644 --- /dev/null +++ b/openide.loaders/test/unit/src/org/netbeans/modules/openide/loaders/data/DoFPDataObjectMultiple.java @@ -0,0 +1,114 @@ +/* + * 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.modules.openide.loaders.data; + +import java.io.IOException; +import org.openide.filesystems.FileObject; +import org.openide.loaders.DataFolder; +import org.openide.loaders.DataObject; +import org.openide.loaders.DataObjectExistsException; +import org.openide.loaders.MultiFileLoader; +import org.openide.util.HelpCtx; + +/** + * @see DataObjectFactoryProcessorTest + * @author Eric Barboni + */ +@DataObject.Registrations({ + @DataObject.Registration(mimeType = "text/testm1", displayName = "labeltest", position = 3565, iconBase = "org/openide/loaders/unknown.gif"), + @DataObject.Registration(mimeType = "text/testm2", displayName = "labeltestm1", position = 4050, iconBase = "org/openide/loaders/unknown.gif")}) +public class DoFPDataObjectMultiple extends DataObject { + + public DoFPDataObjectMultiple(FileObject pf, MultiFileLoader loader) throws DataObjectExistsException { + super(pf, loader); + } + + @Override + public boolean isDeleteAllowed() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean isCopyAllowed() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean isMoveAllowed() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean isRenameAllowed() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public HelpCtx getHelpCtx() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + protected DataObject handleCopy(DataFolder f) throws IOException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + protected void handleDelete() throws IOException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + protected FileObject handleRename(String name) throws IOException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + protected FileObject handleMove(DataFolder df) throws IOException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + protected DataObject handleCreateFromTemplate(DataFolder df, String name) throws IOException { + throw new UnsupportedOperationException("Not supported yet."); + } +} diff --git a/openide.loaders/test/unit/src/org/netbeans/modules/openide/loaders/data/DoFPMIMEType.java b/openide.loaders/test/unit/src/org/netbeans/modules/openide/loaders/data/DoFPMIMEType.java new file mode 100644 --- /dev/null +++ b/openide.loaders/test/unit/src/org/netbeans/modules/openide/loaders/data/DoFPMIMEType.java @@ -0,0 +1,67 @@ +/* + * 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.modules.openide.loaders.data; + +import org.openide.filesystems.MIMEResolver; + +/** + * + * @author Eric Barboni + */ +public class DoFPMIMEType { + + @MIMEResolver.ExtensionRegistration(displayName = "tt1", extension = "tt1", mimeType = "text/test1",position=1000) + public void tt1() { + } + + @MIMEResolver.ExtensionRegistration(displayName = "tt3", extension = "tt3", mimeType = "text/test3",position=1002) + public void tt3() { + } + + @MIMEResolver.ExtensionRegistration(displayName = "ttm1", extension = "ttm1", mimeType = "text/testm1",position=1003) + public void ttm1() { + } + + @MIMEResolver.ExtensionRegistration(displayName = "ttm2", extension = "ttm2", mimeType = "text/testm2",position=1004) + public void ttm2() { + } +}