--- a/apisupport.project/src/org/netbeans/modules/apisupport/project/NbModuleProject.java Wed Jan 21 11:37:41 2009 +0300 +++ a/apisupport.project/src/org/netbeans/modules/apisupport/project/NbModuleProject.java Thu Jan 22 20:03:09 2009 +0100 @@ -112,6 +112,7 @@ import org.netbeans.modules.apisupport.project.universe.LocalizedBundleInfo; import org.netbeans.modules.apisupport.project.universe.ModuleEntry; import org.netbeans.spi.project.support.LookupProviderSupport; +import org.netbeans.spi.project.support.ant.AntBasedProjectRegistration; import org.netbeans.spi.project.ui.RecommendedTemplates; import org.netbeans.spi.project.ui.support.UILookupMergerSupport; import org.openide.modules.SpecificationVersion; @@ -121,6 +122,18 @@ * A NetBeans module project. * @author Jesse Glick */ +@AntBasedProjectRegistration( + type=NbModuleProjectType.TYPE, + iconResource="org/netbeans/modules/apisupport/project/resources/module.png", // NOI18N + sharedConfiguration=@AntBasedProjectRegistration.PrimaryConfigurationDataElement( + name=NbModuleProjectType.NAME_SHARED, + namespace= NbModuleProjectType.NAMESPACE_SHARED + ), + privateConfiguration=@AntBasedProjectRegistration.PrimaryConfigurationDataElement( + name=NbModuleProjectType.NAME_PRIVATE, + namespace= NbModuleProjectType.NAMESPACE_PRIVATE + ) +) public final class NbModuleProject implements Project { public static final String NB_PROJECT_ICON_PATH = @@ -139,7 +152,7 @@ private final GeneratedFilesHelper genFilesHelper; private final NbModuleProviderImpl typeProvider; - NbModuleProject(AntProjectHelper helper) throws IOException { + public NbModuleProject(AntProjectHelper helper) throws IOException { AuxiliaryConfiguration aux = helper.createAuxiliaryConfiguration(); for (int v = 4; v < 10; v++) { if (aux.getConfigurationFragment("data", "http://www.netbeans.org/ns/nb-module-project/" + v, true) != null) { // NOI18N --- a/apisupport.project/src/org/netbeans/modules/apisupport/project/NbModuleProjectType.java Wed Jan 21 11:37:41 2009 +0300 +++ a/apisupport.project/src/org/netbeans/modules/apisupport/project/NbModuleProjectType.java Thu Jan 22 20:03:09 2009 +0100 @@ -41,48 +41,18 @@ package org.netbeans.modules.apisupport.project; -import java.io.IOException; -import javax.swing.Icon; -import org.netbeans.api.project.Project; -import org.netbeans.spi.project.support.ant.AntBasedProjectType2; -import org.netbeans.spi.project.support.ant.AntProjectHelper; -import org.openide.util.ImageUtilities; - /** - * Factory for NetBeans module projects. + * Constants. * @author Jesse Glick */ -@org.openide.util.lookup.ServiceProvider(service=org.netbeans.spi.project.support.ant.AntBasedProjectType.class) -public final class NbModuleProjectType implements AntBasedProjectType2 { +public final class NbModuleProjectType { static final String TYPE = "org.netbeans.modules.apisupport.project"; // NOI18N static final String NAME_SHARED = "data"; // NOI18N public static final String NAMESPACE_SHARED = "http://www.netbeans.org/ns/nb-module-project/3"; // NOI18N public static final String NAMESPACE_SHARED_2 = "http://www.netbeans.org/ns/nb-module-project/2"; // NOI18N - private static final String NAME_PRIVATE = "data"; // NOI18N - private static final String NAMESPACE_PRIVATE = "http://www.netbeans.org/ns/nb-module-project-private/1"; // NOI18N + static final String NAME_PRIVATE = "data"; // NOI18N + static final String NAMESPACE_PRIVATE = "http://www.netbeans.org/ns/nb-module-project-private/1"; // NOI18N - /** Default constructor for lookup. */ - public NbModuleProjectType() {} - - public String getType() { - return TYPE; - } - - public Project createProject(AntProjectHelper helper) throws IOException { - return new NbModuleProject(helper); - } - - public String getPrimaryConfigurationDataElementName(boolean shared) { - return shared ? NAME_SHARED : NAME_PRIVATE; - } - - public String getPrimaryConfigurationDataElementNamespace(boolean shared) { - return shared ? NAMESPACE_SHARED : NAMESPACE_PRIVATE; - } - - public Icon getIcon() { - return ImageUtilities.image2Icon(ImageUtilities.loadImage("org/netbeans/modules/apisupport/project/resources/module.png", true)); - } - + private NbModuleProjectType() {} } --- a/apisupport.project/src/org/netbeans/modules/apisupport/project/suite/SuiteProject.java Wed Jan 21 11:37:41 2009 +0300 +++ a/apisupport.project/src/org/netbeans/modules/apisupport/project/suite/SuiteProject.java Thu Jan 22 20:03:09 2009 +0100 @@ -67,6 +67,7 @@ import org.netbeans.modules.apisupport.project.ui.customizer.SuiteProperties; import org.netbeans.modules.apisupport.project.universe.NbPlatform; import org.netbeans.spi.project.support.LookupProviderSupport; +import org.netbeans.spi.project.support.ant.AntBasedProjectRegistration; import org.netbeans.spi.project.support.ant.AntProjectEvent; import org.netbeans.spi.project.support.ant.AntProjectHelper; import org.netbeans.spi.project.support.ant.AntProjectListener; @@ -93,6 +94,18 @@ * Represents one module suite project. * @author Jesse Glick */ +@AntBasedProjectRegistration( + type=SuiteProjectType.TYPE, + iconResource="org/netbeans/modules/apisupport/project/suite/resources/suite.png", // NOI18N + sharedConfiguration=@AntBasedProjectRegistration.PrimaryConfigurationDataElement( + name=SuiteProjectType.NAME_SHARED, + namespace= SuiteProjectType.NAMESPACE_SHARED + ), + privateConfiguration=@AntBasedProjectRegistration.PrimaryConfigurationDataElement( + name=SuiteProjectType.NAME_PRIVATE, + namespace= SuiteProjectType.NAMESPACE_PRIVATE + ) +) public final class SuiteProject implements Project { public static final String SUITE_ICON_PATH = --- a/apisupport.project/src/org/netbeans/modules/apisupport/project/suite/SuiteProjectType.java Wed Jan 21 11:37:41 2009 +0300 +++ a/apisupport.project/src/org/netbeans/modules/apisupport/project/suite/SuiteProjectType.java Thu Jan 22 20:03:09 2009 +0100 @@ -41,47 +41,18 @@ package org.netbeans.modules.apisupport.project.suite; -import java.io.IOException; -import javax.swing.Icon; -import org.netbeans.api.project.Project; -import org.netbeans.spi.project.support.ant.AntBasedProjectType2; -import org.netbeans.spi.project.support.ant.AntProjectHelper; -import org.openide.util.ImageUtilities; - /** * Factory for NetBeans module suite projects. * @author Jesse Glick */ -@org.openide.util.lookup.ServiceProvider(service=org.netbeans.spi.project.support.ant.AntBasedProjectType.class) -public final class SuiteProjectType implements AntBasedProjectType2 { +public final class SuiteProjectType { public static final String TYPE = "org.netbeans.modules.apisupport.project.suite"; // NOI18N static final String NAME_SHARED = "data"; // NOI18N public static final String NAMESPACE_SHARED = "http://www.netbeans.org/ns/nb-module-suite-project/1"; // NOI18N - private static final String NAME_PRIVATE = "data"; // NOI18N - private static final String NAMESPACE_PRIVATE = "http://www.netbeans.org/ns/nb-module-suite-project-private/1"; // NOI18N + static final String NAME_PRIVATE = "data"; // NOI18N + static final String NAMESPACE_PRIVATE = "http://www.netbeans.org/ns/nb-module-suite-project-private/1"; // NOI18N /** Default constructor for lookup. */ - public SuiteProjectType() {} - - public String getType() { - return TYPE; - } - - public Project createProject(AntProjectHelper helper) throws IOException { - return new SuiteProject(helper); - } - - public String getPrimaryConfigurationDataElementName(boolean shared) { - return shared ? NAME_SHARED : NAME_PRIVATE; - } - - public String getPrimaryConfigurationDataElementNamespace(boolean shared) { - return shared ? NAMESPACE_SHARED : NAMESPACE_PRIVATE; - } - - public Icon getIcon() { - return ImageUtilities.image2Icon(ImageUtilities.loadImage("org/netbeans/modules/apisupport/project/suite/resources/suite.png", true)); - } - + private SuiteProjectType() {} } --- a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/J2SEProject.java Wed Jan 21 11:37:41 2009 +0300 +++ a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/J2SEProject.java Thu Jan 22 20:03:09 2009 +0100 @@ -98,6 +98,7 @@ import org.netbeans.spi.project.ant.AntBuildExtenderFactory; import org.netbeans.spi.project.support.LookupProviderSupport; import org.netbeans.spi.project.ant.AntBuildExtenderImplementation; +import org.netbeans.spi.project.support.ant.AntBasedProjectRegistration; import org.netbeans.spi.project.support.ant.AntProjectEvent; import org.netbeans.spi.project.support.ant.AntProjectHelper; import org.netbeans.spi.project.support.ant.AntProjectListener; @@ -139,6 +140,18 @@ * Represents one plain J2SE project. * @author Jesse Glick, et al. */ +@AntBasedProjectRegistration( + type=J2SEProjectType.TYPE, + iconResource="org/netbeans/modules/java/j2seproject/ui/resources/j2seProject.png", // NOI18N + sharedConfiguration=@AntBasedProjectRegistration.PrimaryConfigurationDataElement( + name=J2SEProjectType.PROJECT_CONFIGURATION_NAME, + namespace= J2SEProjectType.PROJECT_CONFIGURATION_NAMESPACE + ), + privateConfiguration=@AntBasedProjectRegistration.PrimaryConfigurationDataElement( + name=J2SEProjectType.PRIVATE_CONFIGURATION_NAME, + namespace= J2SEProjectType.PRIVATE_CONFIGURATION_NAMESPACE + ) +) public final class J2SEProject implements Project, AntProjectListener { private static final Icon J2SE_PROJECT_ICON = new ImageIcon(ImageUtilities.loadImage("org/netbeans/modules/java/j2seproject/ui/resources/j2seProject.png")); // NOI18N @@ -159,7 +172,7 @@ private AntBuildExtender buildExtender; - J2SEProject(AntProjectHelper helper) throws IOException { + public J2SEProject(AntProjectHelper helper) throws IOException { this.helper = helper; eval = createEvaluator(); aux = helper.createAuxiliaryConfiguration(); --- a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/J2SEProjectType.java Wed Jan 21 11:37:41 2009 +0300 +++ a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/J2SEProjectType.java Thu Jan 22 20:03:09 2009 +0100 @@ -41,47 +41,13 @@ package org.netbeans.modules.java.j2seproject; -import java.io.IOException; -import javax.swing.Icon; -import org.netbeans.api.project.Project; -import org.netbeans.spi.project.support.ant.AntBasedProjectType2; -import org.netbeans.spi.project.support.ant.AntProjectHelper; -import org.openide.util.ImageUtilities; - /** - * Factory for simple J2SE projects. - * @author Jesse Glick + * Constants. */ -@org.openide.util.lookup.ServiceProvider(service=org.netbeans.spi.project.support.ant.AntBasedProjectType.class) -public final class J2SEProjectType implements AntBasedProjectType2 { - +public final class J2SEProjectType { public static final String TYPE = "org.netbeans.modules.java.j2seproject"; // NOI18N - private static final String PROJECT_CONFIGURATION_NAME = "data"; // NOI18N + static final String PROJECT_CONFIGURATION_NAME = "data"; // NOI18N public static final String PROJECT_CONFIGURATION_NAMESPACE = "http://www.netbeans.org/ns/j2se-project/3"; // NOI18N - private static final String PRIVATE_CONFIGURATION_NAME = "data"; // NOI18N - private static final String PRIVATE_CONFIGURATION_NAMESPACE = "http://www.netbeans.org/ns/j2se-project-private/1"; // NOI18N - - /** Do nothing, just a service. */ - public J2SEProjectType() {} - - public String getType() { - return TYPE; - } - - public Project createProject(AntProjectHelper helper) throws IOException { - return new J2SEProject(helper); - } - - public String getPrimaryConfigurationDataElementName(boolean shared) { - return shared ? PROJECT_CONFIGURATION_NAME : PRIVATE_CONFIGURATION_NAME; - } - - public String getPrimaryConfigurationDataElementNamespace(boolean shared) { - return shared ? PROJECT_CONFIGURATION_NAMESPACE : PRIVATE_CONFIGURATION_NAMESPACE; - } - - public Icon getIcon() { - return ImageUtilities.image2Icon(ImageUtilities.loadImage("org/netbeans/modules/java/j2seproject/ui/resources/j2seProject.png", true)); - } - + static final String PRIVATE_CONFIGURATION_NAME = "data"; // NOI18N + static final String PRIVATE_CONFIGURATION_NAMESPACE = "http://www.netbeans.org/ns/j2se-project-private/1"; // NOI18N } --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ 06c57b1428a4 Thu Jan 22 20:03:09 2009 +0100 @@ -0,0 +1,129 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * + * 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 2009 Sun Microsystems, Inc. + */ + +package org.netbeans.modules.project.ant; + +import java.io.IOException; +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; +import java.util.Map; +import javax.swing.Icon; +import org.netbeans.api.project.Project; +import org.netbeans.spi.project.support.ant.AntBasedProjectType; +import org.netbeans.spi.project.support.ant.AntProjectHelper; +import org.openide.util.ImageUtilities; +import org.openide.util.Lookup; +import org.openide.util.Parameters; + +/** Generic implementation of {@link AntBasedGenericType} that feeds itself + * from an layer data. + * + * @author Jaroslav Tulach + */ +final class AntBasedGenericType implements AntBasedProjectType { + private final String iconResource; + private final String type; + private final String className; + private final String methodName; + private final String[] configNames; + private final String[] configNamespaces; + + public AntBasedGenericType(Map map) { + iconResource = (String)map.get("iconResource"); // NOI18N + type = (String)map.get("type"); // NOI18N + className = (String)map.get("className"); // NOI18N + methodName = (String)map.get("methodName"); // NOI18N + configNames = new String[] { + (String)map.get("sharedName"), // NOI18N + (String)map.get("privateName"), // NOI18N + }; + configNamespaces = new String[] { + (String)map.get("sharedNamespace"), // NOI18N + (String)map.get("privateNamespace"), // NOI18N + }; + Parameters.notNull("iconResource", iconResource); // NOI18N + Parameters.notNull("type", type); // NOI18N + Parameters.notNull("className", className); // NOI18N + Parameters.notNull("sharedName", configNames[0]); // NOI18N + Parameters.notNull("privateName", configNames[1]); // NOI18N + Parameters.notNull("sharedNamespace", configNamespaces[0]); // NOI18N + Parameters.notNull("privateNamespace", configNamespaces[1]); // NOI18N + } + + public Icon getIcon() { + return ImageUtilities.image2Icon(ImageUtilities.loadImage(iconResource, true)); + } + + public String getType() { + return type; + } + + public String getPrimaryConfigurationDataElementName(boolean shared) { + return shared ? configNames[0] : configNames[1]; + } + + public String getPrimaryConfigurationDataElementNamespace(boolean shared) { + return shared ? configNamespaces[0] : configNamespaces[1]; + } + + + public Project createProject(AntProjectHelper helper) throws IOException { + ClassLoader l = Lookup.getDefault().lookup(ClassLoader.class); + if (l == null) { + l = Thread.currentThread().getContextClassLoader(); + } + if (l == null) { + l = AntBasedGenericType.class.getClassLoader(); + } + try { + Class clazz = l.loadClass(className); + if (methodName != null) { + Method m = clazz.getDeclaredMethod(methodName, AntProjectHelper.class); + return (Project)m.invoke(null, helper); + } else { + Constructor c = clazz.getConstructor(AntProjectHelper.class); + return (Project) c.newInstance(helper); + } + } catch (RuntimeException ex) { + throw ex; + } catch (Exception ex) { + throw (IllegalArgumentException)new IllegalArgumentException().initCause(ex); + } + } +} --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ 06c57b1428a4 Thu Jan 22 20:03:09 2009 +0100 @@ -0,0 +1,156 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * + * 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 2008 Sun Microsystems, Inc. + */ + +package org.netbeans.modules.project.ant; + +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.ExecutableElement; +import javax.lang.model.element.Modifier; +import javax.lang.model.element.TypeElement; +import javax.lang.model.type.TypeMirror; +import org.netbeans.spi.project.support.ant.AntBasedProjectRegistration; +import org.netbeans.spi.project.support.ant.AntBasedProjectType; +import org.netbeans.spi.project.support.ant.AntProjectHelper; +import org.openide.filesystems.annotations.LayerBuilder.File; +import org.openide.filesystems.annotations.LayerGeneratingProcessor; +import org.openide.filesystems.annotations.LayerGenerationException; +import org.openide.util.lookup.ServiceProvider; + +/** + * processor for {@link AntBasedProjectRegistration} annotation. + * @author Jaroslav Tulach + */ +@ServiceProvider(service=Processor.class) +@SupportedSourceVersion(SourceVersion.RELEASE_6) +@SupportedAnnotationTypes("org.netbeans.spi.project.support.ant.AntBasedProjectRegistration")//NOI18N +public class AntBasedProcessor extends LayerGeneratingProcessor { + + @Override + protected boolean handleProcess(Set annotations, RoundEnvironment roundEnv) throws LayerGenerationException { + if (roundEnv.processingOver()) { + return false; + } + TypeMirror antHelper = processingEnv.getElementUtils().getTypeElement(AntProjectHelper.class.getName()).asType(); + for (Element e : roundEnv.getElementsAnnotatedWith(AntBasedProjectRegistration.class)) { + AntBasedProjectRegistration reg = e.getAnnotation(AntBasedProjectRegistration.class); + String name; + String classname; + String methodname; + switch (e.getKind()) { + case CLASS: + classname = processingEnv.getElementUtils().getBinaryName((TypeElement)e).toString(); + name = classname.replace('.', '-'); + methodname = null; + if (!e.getModifiers().contains(Modifier.PUBLIC)) { + throw new LayerGenerationException("Class needs to be public"); // NOI18N + } + boolean found = false; + for (Element cns : processingEnv.getElementUtils().getAllMembers((TypeElement)e)) { + if (cns.getKind() != ElementKind.CONSTRUCTOR) { + continue; + } + ExecutableElement exec = (ExecutableElement)cns; + if (!exec.getModifiers().contains(Modifier.PUBLIC)) { + continue; + } + if (exec.getParameters().size() != 1) { + continue; + } + if (exec.getParameters().get(0).asType().equals(antHelper)) { + found = true; + break; + } + } + if (!found) { + throw new LayerGenerationException("There needs to be public constructor taking AntProjectHelper parameter"); // NOI18N + } + + break; + case METHOD: + classname = processingEnv.getElementUtils().getBinaryName((TypeElement)e.getEnclosingElement()).toString(); + methodname = ((ExecutableElement) e).getSimpleName().toString(); + name = (classname + "." + methodname).replace('.', '-'); + + if (!e.getEnclosingElement().getModifiers().contains(Modifier.PUBLIC)) { + throw new LayerGenerationException("Class needs to be public"); // NOI18N + } + + ExecutableElement exec = (ExecutableElement)e; + if ( + !exec.getModifiers().contains(Modifier.PUBLIC) || + !exec.getModifiers().contains(Modifier.STATIC) || + exec.getParameters().size() != 1 || + !exec.getParameters().get(0).asType().equals(antHelper) + ) { + throw new LayerGenerationException("The method needs to be public, static and take AntProjectHelper argument"); // NOI18N + } + + break; + default: + throw new IllegalArgumentException(e.toString()); + } + + File f = layer(e). + file("Services/AntBasedProjectTypes/" + name + ".instance"). + stringvalue("type", reg.type()). + stringvalue("iconResource", reg.iconResource()). + stringvalue("sharedName", reg.sharedConfiguration().name()). + stringvalue("sharedNamespace", reg.sharedConfiguration().namespace()). + stringvalue("privateName", reg.privateConfiguration().name()). + stringvalue("privateNamespace", reg.privateConfiguration().namespace()). + stringvalue("className", classname). + stringvalue("instanceClass", AntBasedProjectType.class.getName()). + methodvalue("instanceCreate", AntBasedProjectFactorySingleton.class.getName(), "create"); + + if (methodname != null) { + f = f.stringvalue("methodName", methodname); + } + f.write(); + } + return true; + } + +} --- a/project.ant/src/org/netbeans/modules/project/ant/AntBasedProjectFactorySingleton.java Wed Jan 21 11:37:41 2009 +0300 +++ a/project.ant/src/org/netbeans/modules/project/ant/AntBasedProjectFactorySingleton.java Thu Jan 22 20:03:09 2009 +0100 @@ -69,7 +69,6 @@ import org.netbeans.spi.project.ProjectFactory2; import org.netbeans.spi.project.ProjectState; import org.netbeans.spi.project.support.ant.AntBasedProjectType; -import org.netbeans.spi.project.support.ant.AntBasedProjectType2; import org.netbeans.spi.project.support.ant.AntProjectHelper; import org.openide.filesystems.FileObject; import org.openide.filesystems.FileUtil; @@ -187,8 +186,8 @@ if (type != null) { AntBasedProjectType provider = findAntBasedProjectType(type); if (provider != null) { - if (provider instanceof AntBasedProjectType2) { - return new ProjectManager.Result(((AntBasedProjectType2)provider).getIcon()); + if (provider instanceof AntBasedGenericType) { + return new ProjectManager.Result(((AntBasedGenericType)provider).getIcon()); } else { //put special icon? return new ProjectManager.Result(null); @@ -385,5 +384,10 @@ } assert HELPER_CALLBACK != null; } - + + public static AntBasedProjectType create(Map map) { + return new AntBasedGenericType(map); + } + + } --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ 06c57b1428a4 Thu Jan 22 20:03:09 2009 +0100 @@ -0,0 +1,114 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. + * + * 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun + * Microsystems, Inc. All Rights Reserved. + * + * 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. + */ + +package org.netbeans.spi.project.support.ant; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.netbeans.api.project.Project; + +/** Registers a {@link Project} implementation as an + * {@link org.netbeans.spi.project.support.ant.AntBasedProjectType} extension. + * Just write a project with constructor that takes one + * {@link AntProjectHelper} argument and annotate the class with this annotation. + * As an alternative you can annotate a factory method with the same parameter. + * + * @author Jaroslav Tulach + * @since 1.30 + */ +@Retention(RetentionPolicy.SOURCE) +@Target({ ElementType.TYPE, ElementType.METHOD }) +public @interface AntBasedProjectRegistration { + /** + * icon of the project type represented by the given implementation of the interface. + * @return the {@link ClassLoader#getResource(java.lang.String)} path to the icon + */ + public String iconResource(); + + + /** + * Get a unique type identifier for this kind of project. + * No two registered {@link AntBasedProjectType} instances may share the same type. + * The type is stored in nbproject/project.xml in the type element. + * It is forbidden for the result of this method to change from call to call. + * @return the project type + */ + String type(); + + /** Returns setup for configuration of shared data section inside project.xml + * @return the configuration data element + */ + PrimaryConfigurationDataElement sharedConfiguration(); + + /** Returns setup for configuration of private data section inside private.xml + * @return the configuration data element + */ + PrimaryConfigurationDataElement privateConfiguration(); + + + public @interface PrimaryConfigurationDataElement { + /** + * Get the simple name of the XML element that should be used to store + * the project's specific configuration data in nbproject/project.xml + * (inside <configuration>) or nbproject/private/private.xml + * (inside <project-private>). + * It is forbidden for the result of this method to change from call to call. + * @param shared if true, refers to project.xml, else refers to + * private.xml + * @return a simple name; data is recommended but not required + */ + String name(); + /** + * Get the namespace of the XML element that should be used to store + * the project's specific configuration data in nbproject/project.xml + * (inside <configuration>) or nbproject/private/private.xml + * (inside <project-private>). + * It is forbidden for the result of this method to change from call to call. + * @param shared if true, refers to project.xml, else refers to + * private.xml + * @return an XML namespace, e.g. http://www.netbeans.org/ns/j2se-project + * or http://www.netbeans.org/ns/j2se-project-private + */ + String namespace(); + } +} --- a/project.ant/src/org/netbeans/spi/project/support/ant/AntBasedProjectType2.java Wed Jan 21 11:37:41 2009 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,60 +0,0 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. - * - * 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. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun 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]" - * - * Contributor(s): - * - * The Original Software is NetBeans. The Initial Developer of the Original - * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun - * Microsystems, Inc. All Rights Reserved. - * - * 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. - */ - -package org.netbeans.spi.project.support.ant; - -import javax.swing.Icon; - -/** - * extension of {@link org.netbeans.spi.project.support.ant.AntBasedProjectType} - * that provides an icon for the project without actually creating an project instance for it. - * @author mkleint - * @since org.netbeans.modules.project.ant 1.28 - */ -public interface AntBasedProjectType2 extends AntBasedProjectType { - - /** - * icon of the project type represented by the given implementation of the interface. - * @return - */ - public Icon getIcon(); - -} --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ 06c57b1428a4 Thu Jan 22 20:03:09 2009 +0100 @@ -0,0 +1,148 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. + * + * 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun + * Microsystems, Inc. All Rights Reserved. + * + * 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. + */ + +package org.netbeans.spi.project.support.ant; + +import java.io.IOException; +import java.util.Collection; +import java.util.Iterator; +import org.netbeans.api.project.Project; +import org.netbeans.api.project.ProjectManager; +import org.netbeans.api.project.TestUtil; +import org.netbeans.junit.NbTestCase; +import org.openide.filesystems.FileObject; +import org.openide.filesystems.FileUtil; +import org.openide.util.Lookup; +import org.openide.util.lookup.Lookups; +import org.openide.util.test.MockLookup; + +/** + * That that a project registered by annotation is really found. + * @author Jaroslav Tulach + */ +public class AntBasedProjectRegistrationTest extends NbTestCase { + + public AntBasedProjectRegistrationTest(String name) { + super(name); + } + + private FileObject scratch; + private FileObject projdir; + private ProjectManager pm; + + protected @Override void setUp() throws Exception { + super.setUp(); + MockLookup.init(); + assertEquals("No factory has been used yet", 0, AnnotatedProject.factoryCalls); + Collection all = Lookups.forPath("Services/AntBasedProjectTypes").lookupAll(AntBasedProjectType.class); + assertEquals("Two found", 2, all.size()); + Iterator it = all.iterator(); + if ("testFactory".equals(getName())) { + it.next(); + } + MockLookup.setInstances(it.next()); + scratch = TestUtil.makeScratchDir(this); + projdir = scratch.createFolder("proj"); + ProjectGenerator.createProject(projdir, "test"); + pm = ProjectManager.getDefault(); + } + + protected @Override void tearDown() throws Exception { + scratch = null; + projdir = null; + pm = null; + super.tearDown(); + } + + public void testFindProject() throws Exception { + Project p = pm.findProject(projdir); + assertNotNull("Annotation project found", p.getLookup().lookup(AnnotatedProject.class)); + } + + public void testFactory() throws Exception { + Project p = pm.findProject(projdir); + assertNotNull("Annotation project found", p.getLookup().lookup(AnnotatedProject.class)); + assertEquals(1, AnnotatedProject.factoryCalls); + } + + @AntBasedProjectRegistration( + iconResource="noicon", + type="test", + privateConfiguration=@AntBasedProjectRegistration.PrimaryConfigurationDataElement( + name="data", + namespace="urn:test:private" + ), + sharedConfiguration=@AntBasedProjectRegistration.PrimaryConfigurationDataElement( + name="data", + namespace="urn:test:shared" + ) + ) + public static final class AnnotatedProject extends AntBasedTestUtil.TestAntBasedProject { + static int factoryCalls; + + public AnnotatedProject(AntProjectHelper h) throws IOException { + super(h, null); + } + + @Override + public Lookup getLookup() { + return Lookups.singleton(this); + } + + @AntBasedProjectRegistration( + iconResource = "noicon", + type = "test", + privateConfiguration = @AntBasedProjectRegistration.PrimaryConfigurationDataElement( + name = "data", + namespace = "urn:test:private" + ), + sharedConfiguration = @AntBasedProjectRegistration.PrimaryConfigurationDataElement( + name = "data", + namespace = "urn:test:shared" + ) + ) + public static Project factoryMethod(AntProjectHelper h) throws IOException { + factoryCalls++; + return new AnnotatedProject(h); + } + } + +} --- a/project.ant/test/unit/src/org/netbeans/spi/project/support/ant/AntBasedTestUtil.java Wed Jan 21 11:37:41 2009 +0300 +++ a/project.ant/test/unit/src/org/netbeans/spi/project/support/ant/AntBasedTestUtil.java Thu Jan 22 20:03:09 2009 +0100 @@ -157,14 +157,14 @@ } - private static final class TestAntBasedProject implements Project { + public static class TestAntBasedProject implements Project { private final AntProjectHelper helper; private final ReferenceHelper refHelper; private final GeneratedFilesHelper genFilesHelper; private final Lookup l; - TestAntBasedProject(AntProjectHelper helper, AntBuildExtenderImplementation ext) throws IOException { + protected TestAntBasedProject(AntProjectHelper helper, AntBuildExtenderImplementation ext) throws IOException { if (helper.getProjectDirectory().getFileObject("nbproject/broken") != null) { throw new IOException("broken"); } --- a/web.project/src/org/netbeans/modules/web/project/WebProjectType.java Wed Jan 21 11:37:41 2009 +0300 +++ a/web.project/src/org/netbeans/modules/web/project/WebProjectType.java Thu Jan 22 20:03:09 2009 +0100 @@ -43,16 +43,13 @@ import java.io.IOException; import java.util.Collection; -import javax.swing.Icon; import org.netbeans.api.project.Project; import org.netbeans.modules.web.project.spi.WebProjectImplementationFactory; -import org.netbeans.spi.project.support.ant.AntBasedProjectType2; +import org.netbeans.spi.project.support.ant.AntBasedProjectRegistration; import org.netbeans.spi.project.support.ant.AntProjectHelper; -import org.openide.util.ImageUtilities; import org.openide.util.Lookup; -@org.openide.util.lookup.ServiceProvider(service=org.netbeans.spi.project.support.ant.AntBasedProjectType.class) -public final class WebProjectType implements AntBasedProjectType2 { +public final class WebProjectType { public static final String TYPE = "org.netbeans.modules.web.project"; private static final String PROJECT_CONFIGURATION_NAME = "data"; @@ -66,13 +63,24 @@ "http://www.netbeans.org/ns/web-project/3"}; /** Do nothing, just a service. */ - public WebProjectType() {} + private WebProjectType() {} public String getType() { return TYPE; } - - public Project createProject(AntProjectHelper helper) throws IOException { + @AntBasedProjectRegistration( + iconResource="org/netbeans/modules/web/project/ui/resources/webProjectIcon.gif", // NOI18N + type=TYPE, + sharedConfiguration=@AntBasedProjectRegistration.PrimaryConfigurationDataElement( + name=PROJECT_CONFIGURATION_NAME, + namespace=PROJECT_CONFIGURATION_NAMESPACE + ), + privateConfiguration=@AntBasedProjectRegistration.PrimaryConfigurationDataElement( + name=PRIVATE_CONFIGURATION_NAME, + namespace=PRIVATE_CONFIGURATION_NAMESPACE + ) + ) + public static Project createProject(AntProjectHelper helper) throws IOException { for(WebProjectImplementationFactory factory : getProjectFactories()) { if (factory.acceptProject(helper)) { //delegate project completely to another implementation @@ -82,19 +90,7 @@ return new WebProject(helper); } - public String getPrimaryConfigurationDataElementName(boolean shared) { - return shared ? PROJECT_CONFIGURATION_NAME : PRIVATE_CONFIGURATION_NAME; - } - - public String getPrimaryConfigurationDataElementNamespace(boolean shared) { - return shared ? PROJECT_CONFIGURATION_NAMESPACE : PRIVATE_CONFIGURATION_NAMESPACE; - } - - private Collection getProjectFactories() { + private static Collection getProjectFactories() { return Lookup.getDefault().lookupAll(WebProjectImplementationFactory.class); } - - public Icon getIcon() { - return ImageUtilities.image2Icon(ImageUtilities.loadImage("org/netbeans/modules/web/project/ui/resources/webProjectIcon.gif", true)); - } }