Index: ant/freeform/src/org/netbeans/modules/ant/freeform/FreeformProject.java =================================================================== RCS file: /cvs/ant/freeform/src/org/netbeans/modules/ant/freeform/FreeformProject.java,v retrieving revision 1.31 diff -u -r1.31 FreeformProject.java --- ant/freeform/src/org/netbeans/modules/ant/freeform/FreeformProject.java 7 Dec 2004 13:46:11 -0000 1.31 +++ ant/freeform/src/org/netbeans/modules/ant/freeform/FreeformProject.java 7 Jan 2005 08:21:08 -0000 @@ -15,6 +15,7 @@ import java.beans.PropertyChangeListener; import java.io.IOException; +import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -23,6 +24,7 @@ import org.netbeans.api.project.Project; import org.netbeans.api.project.ProjectInformation; import org.netbeans.api.project.ProjectManager; +import org.netbeans.modules.ant.freeform.spi.LookupMerger; import org.netbeans.modules.ant.freeform.spi.ProjectNature; import org.netbeans.modules.ant.freeform.spi.support.Util; import org.netbeans.modules.ant.freeform.ui.ProjectCustomizerProvider; @@ -31,7 +33,7 @@ import org.netbeans.spi.project.support.ant.AntProjectHelper; import org.netbeans.spi.project.support.ant.PropertyEvaluator; import org.netbeans.spi.project.support.ant.PropertyUtils; -import org.netbeans.spi.project.ui.PrivilegedTemplates; +import org.openide.ErrorManager; import org.openide.filesystems.FileObject; import org.openide.util.Lookup; import org.openide.util.LookupEvent; @@ -77,9 +79,9 @@ new ProjectCustomizerProvider(this, helper, eval), // CustomizerProvider aux, // AuxiliaryConfiguration helper().createCacheDirectoryProvider(), // CacheDirectoryProvider - new PrivilegedTemplatesImpl(), // List of templates in New action popup new Subprojects(this), // SubprojectProvider new ArtifactProvider(this), // AntArtifactProvider + new LookupMergerImpl(), // LookupMerger }); return new FreeformLookup(baseLookup, this, helper, eval, aux); } @@ -140,20 +142,6 @@ } - private static final class PrivilegedTemplatesImpl implements PrivilegedTemplates { - - private static final String[] PRIVILEGED_NAMES = new String[] { - "Templates/Classes/Class.java", // NOI18N - "Templates/Classes/Package", // NOI18N - "Templates/Classes/Interface.java", // NOI18N - }; - - public String[] getPrivilegedTemplates() { - return PRIVILEGED_NAMES; - } - - } - private static final class FreeformLookup extends ProxyLookup implements LookupListener { private final Lookup baseLookup; @@ -161,6 +149,8 @@ private final PropertyEvaluator evaluator; private final FreeformProject project; private final AuxiliaryConfiguration aux; + private Lookup.Result/**/ mergers; + private WeakReference listenerRef; public FreeformLookup(Lookup baseLookup, FreeformProject project, AntProjectHelper helper, PropertyEvaluator evaluator, AuxiliaryConfiguration aux) { super(new Lookup[0]); @@ -185,8 +175,40 @@ ProjectNature pn = (ProjectNature) it.next(); lookups.add(pn.getLookup(project, helper, evaluator, aux)); } - setLookups((Lookup[]) lookups.toArray(new Lookup[lookups.size()])); + Lookup lkp = new ProxyLookup((Lookup[]) lookups.toArray(new Lookup[lookups.size()])); + + //merge: + ArrayList filtredClasses = new ArrayList(); + ArrayList mergedInstances = new ArrayList(); + LookupListener l = listenerRef != null ? (LookupListener)listenerRef.get() : null; + if (l != null) { + mergers.removeLookupListener(l); + } + mergers = lkp.lookup(new Lookup.Template(LookupMerger.class)); + l = (LookupListener) WeakListeners.create(LookupListener.class, this, mergers); + listenerRef = new WeakReference(l); + mergers.addLookupListener(l); + it = mergers.allInstances().iterator(); + while (it.hasNext()) { + LookupMerger lm = (LookupMerger)it.next(); + Class[] classes = lm.getMergableClasses(); + for (int i=0; iFor example ClassPathProvider is implemented both by Java nature and Web + * nature and therefore these impls must be merged and substituted with single + * provider. The merger should be implemented by Java nature. + *

There can be always only one merger for a class. If there is more then + * one of them the first one will be used and others will be ignored. It is + * undefined which will be the first one. + * + * @author David Konecny + */ +public interface LookupMerger { + + /** + * Returns array of classes which this merged is capable to merge. + * @return array of classes + */ + Class[] getMergableClasses(); + + /** + * Merge instances of the given class in the given lookup and return merged + * object which substitutes them. + * @param lookup lookup with the instances + * @param clazz class which instances will be merged. Only classes + * returned by {@link #getMergableClasses} will be passed to this method + * @return object to be used instead of instances in the lookup + */ + Object merge(Lookup lookup, Class clazz); + +} Index: java/freeform/src/org/netbeans/modules/java/freeform/JavaProjectNature.java =================================================================== RCS file: /cvs/java/freeform/src/org/netbeans/modules/java/freeform/JavaProjectNature.java,v retrieving revision 1.2 diff -u -r1.2 JavaProjectNature.java --- java/freeform/src/org/netbeans/modules/java/freeform/JavaProjectNature.java 7 Dec 2004 13:46:30 -0000 1.2 +++ java/freeform/src/org/netbeans/modules/java/freeform/JavaProjectNature.java 7 Jan 2005 08:21:08 -0000 @@ -35,6 +35,7 @@ import org.netbeans.spi.project.support.ant.AntProjectHelper; import org.netbeans.spi.project.support.ant.AntProjectListener; import org.netbeans.spi.project.support.ant.PropertyEvaluator; +import org.netbeans.spi.project.ui.PrivilegedTemplates; import org.netbeans.spi.project.ui.ProjectOpenedHook; import org.openide.filesystems.FileObject; import org.openide.filesystems.FileUtil; @@ -118,6 +119,8 @@ new SourceForBinaryQueryImpl(projectHelper, projectEvaluator, aux), // SourceForBinaryQueryImplementation new OpenHook(cp), // ProjectOpenedHook new TestQuery(project), // UnitTestForSourceQueryImplementation + new PrivilegedTemplatesImpl(), // List of templates in New action popup + new LookupMergerImpl(), }); } @@ -179,6 +182,20 @@ public void propertiesChanged(AntProjectEvent ev) { // ignore + } + + } + + private static final class PrivilegedTemplatesImpl implements PrivilegedTemplates { + + private static final String[] PRIVILEGED_NAMES = new String[] { + "Templates/Classes/Class.java", // NOI18N + "Templates/Classes/Package", // NOI18N + "Templates/Classes/Interface.java", // NOI18N + }; + + public String[] getPrivilegedTemplates() { + return PRIVILEGED_NAMES; } } Index: java/freeform/src/org/netbeans/modules/java/freeform/LookupMergerImpl.java =================================================================== RCS file: java/freeform/src/org/netbeans/modules/java/freeform/LookupMergerImpl.java diff -N java/freeform/src/org/netbeans/modules/java/freeform/LookupMergerImpl.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ java/freeform/src/org/netbeans/modules/java/freeform/LookupMergerImpl.java 7 Jan 2005 08:21:08 -0000 @@ -0,0 +1,65 @@ +/* + * 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-2005 Sun + * Microsystems, Inc. All Rights Reserved. + */ + +package org.netbeans.modules.java.freeform; + +import java.util.Iterator; +import org.netbeans.api.java.classpath.ClassPath; +import org.netbeans.modules.ant.freeform.spi.LookupMerger; +import org.netbeans.spi.java.classpath.ClassPathProvider; +import org.openide.filesystems.FileObject; +import org.openide.util.Lookup; + +/** + * Merges ClassPathProviders. + * + * @author David Konecny + */ +public class LookupMergerImpl implements LookupMerger { + + public LookupMergerImpl() {} + + public Class[] getMergableClasses() { + return new Class[]{ClassPathProvider.class}; + } + + public Object merge(Lookup lookup, Class clazz) { + if (clazz.equals(ClassPathProvider.class)) { + return new ClassPathProviderImpl(lookup); + } + throw new IllegalArgumentException("merging of "+clazz+" is not supported"); // NOI18N + } + + private static class ClassPathProviderImpl implements ClassPathProvider { + + private Lookup lkp; + + public ClassPathProviderImpl(Lookup lkp) { + this.lkp = lkp; + } + + public ClassPath findClassPath(FileObject file, String type) { + Iterator it = lkp.lookup(new Lookup.Template(ClassPathProvider.class)).allInstances().iterator(); + while (it.hasNext()) { + ClassPathProvider cpp = (ClassPathProvider)it.next(); + ClassPath cp = cpp.findClassPath(file, type); + if (cp != null) { + return cp; + } + } + return null; + } + + } + +} Index: java/project/src/org/netbeans/modules/java/project/ProjectClassPathProvider.java =================================================================== RCS file: /cvs/java/project/src/org/netbeans/modules/java/project/ProjectClassPathProvider.java,v retrieving revision 1.3 diff -u -r1.3 ProjectClassPathProvider.java --- java/project/src/org/netbeans/modules/java/project/ProjectClassPathProvider.java 16 Dec 2004 12:47:52 -0000 1.3 +++ java/project/src/org/netbeans/modules/java/project/ProjectClassPathProvider.java 7 Jan 2005 08:21:08 -0000 @@ -33,17 +33,15 @@ public ClassPath findClassPath(FileObject file, String type) { Project p = FileOwnerQuery.getOwner(file); if (p != null) { - // check all instances of classpath provider; e.g. freeform project can have more than one - Iterator it = p.getLookup().lookup(new Lookup.Template(ClassPathProvider.class)).allInstances().iterator(); - while (it.hasNext()) { - ClassPathProvider cpp = (ClassPathProvider)it.next(); - ClassPath cp = cpp.findClassPath(file, type); - if (cp != null) { - return cp; - } + ClassPathProvider cpp = (ClassPathProvider)p.getLookup().lookup(ClassPathProvider.class); + if (cpp != null) { + return cpp.findClassPath(file, type); + } else { + return null; } + } else { + return null; } - return null; } } Index: web/freeform/src/org/netbeans/modules/web/freeform/WebProjectNature.java =================================================================== RCS file: /cvs/web/freeform/src/org/netbeans/modules/web/freeform/WebProjectNature.java,v retrieving revision 1.2 diff -u -r1.2 WebProjectNature.java --- web/freeform/src/org/netbeans/modules/web/freeform/WebProjectNature.java 7 Dec 2004 13:46:43 -0000 1.2 +++ web/freeform/src/org/netbeans/modules/web/freeform/WebProjectNature.java 7 Jan 2005 08:21:20 -0000 @@ -30,6 +30,7 @@ import org.netbeans.spi.project.support.ant.AntProjectHelper; import org.netbeans.spi.project.support.ant.AntProjectListener; import org.netbeans.spi.project.support.ant.PropertyEvaluator; +import org.netbeans.spi.project.ui.PrivilegedTemplates; import org.openide.filesystems.FileObject; import org.openide.nodes.Node; import org.openide.util.Lookup; @@ -108,6 +109,7 @@ private static Lookup initLookup(Project project, AntProjectHelper projectHelper, PropertyEvaluator projectEvaluator, AuxiliaryConfiguration aux) { return Lookups.fixed(new Object[] { + new PrivilegedTemplatesImpl(), // List of templates in New action popup new WebModules(project, projectHelper, projectEvaluator), // WebModuleProvider, ClassPathProvider }); } @@ -151,4 +153,23 @@ } } + + private static final class PrivilegedTemplatesImpl implements PrivilegedTemplates { + + private static final String[] PRIVILEGED_NAMES = new String[] { + "Templates/JSP_Servlet/JSP.jsp", + "Templates/JSP_Servlet/Html.html", + "Templates/JSP_Servlet/Servlet.java", + "Templates/Other/Folder", + "Templates/JSP_Servlet/WebService", + "Templates/JSP_Servlet/MessageHandler", + "Templates/JSP_Servlet/WebServiceClient" + }; + + public String[] getPrivilegedTemplates() { + return PRIVILEGED_NAMES; + } + + } + }