diff -r 653165c34dbc j2eeserver/apichanges.xml --- a/j2eeserver/apichanges.xml Wed Jul 16 17:48:48 2008 +0200 +++ b/j2eeserver/apichanges.xml Wed Jul 16 17:55:31 2008 +0200 @@ -106,11 +106,32 @@ J2EE Server Common API J2EE Server Common API + + Server Integration Plugin SPI Support + + + + LookupProvider support for J2eePlatform lookup. + + + + + + +

+ Server plugins will use this static method in J2eePlatformImpl.getLookup() + method to enable registration of additional Lookup Providers in layer.xml files. +

+
+ + + +
diff -r 653165c34dbc j2eeserver/nbproject/project.properties --- a/j2eeserver/nbproject/project.properties Wed Jul 16 17:48:48 2008 +0200 +++ b/j2eeserver/nbproject/project.properties Wed Jul 16 17:55:31 2008 +0200 @@ -39,7 +39,7 @@ is.autoload=true javac.source=1.5 -spec.version.base=1.49.0 +spec.version.base=1.50.0 javadoc.overview=${basedir}/api/doc/overview.html javadoc.arch=${basedir}/arch.xml diff -r 653165c34dbc j2eeserver/nbproject/project.xml --- a/j2eeserver/nbproject/project.xml Wed Jul 16 17:48:48 2008 +0200 +++ b/j2eeserver/nbproject/project.xml Wed Jul 16 17:55:31 2008 +0200 @@ -334,6 +334,7 @@ org.netbeans.modules.j2ee.deployment.plugins.api org.netbeans.modules.j2ee.deployment.plugins.spi org.netbeans.modules.j2ee.deployment.plugins.spi.config + org.netbeans.modules.j2ee.deployment.plugins.spi.support org.netbeans.modules.j2ee.deployment.profiler.api org.netbeans.modules.j2ee.deployment.profiler.spi diff -r 653165c34dbc j2eeserver/src/org/netbeans/modules/j2ee/deployment/plugins/spi/LookupProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/j2eeserver/src/org/netbeans/modules/j2ee/deployment/plugins/spi/LookupProvider.java Wed Jul 16 17:55:31 2008 +0200 @@ -0,0 +1,67 @@ +/* + * 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.modules.j2ee.deployment.plugins.spi; + +import org.openide.util.Lookup; + +/** + * interface for inclusion of 3rd party content in + * {@link org.netbeans.modules.j2ee.deployment.devmodules.api.J2eePlatform}'s lookup. + * Typically, if the serverplugin type allows composition of lookup from + * multiple sources, it will make a layer location public where 3rd parties + * will register implementations of this interface. + * @author phejl, mkleint + * @since 1.50 + */ +public interface LookupProvider { + + /** + * implementations will be asked to create their additional project lookup based on the baseContext + * passed as parameter. The content of baseLookup is undefined on this level, is a contract + * of the actual serverplugin type. Each implementation is only asked once for it's lookup + * for a given platform instance at the time when platform's lookup is being created. + * @param baseContext implementation shall decide what to return for a given platform instance based on context + * passed in. + * @return a {@link org.openide.util.Lookup} instance that is to be added to the platform's lookup, never null. + */ + Lookup createAdditionalLookup(Lookup baseContext); +} diff -r 653165c34dbc j2eeserver/src/org/netbeans/modules/j2ee/deployment/plugins/spi/support/LookupProviderSupport.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/j2eeserver/src/org/netbeans/modules/j2ee/deployment/plugins/spi/support/LookupProviderSupport.java Wed Jul 16 17:55:31 2008 +0200 @@ -0,0 +1,193 @@ +/* + * 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.modules.j2ee.deployment.plugins.spi.support; + +import java.lang.ref.Reference; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Set; +import java.util.logging.Logger; +import org.netbeans.modules.j2ee.deployment.plugins.spi.LookupProvider; +import org.openide.util.Lookup; +import org.openide.util.LookupEvent; +import org.openide.util.LookupListener; +import org.openide.util.WeakListeners; +import org.openide.util.lookup.Lookups; +import org.openide.util.lookup.ProxyLookup; + +/** + * Factory for lookup capable of merging content from registered + * {@link org.netbeans.spi.project.LookupProvider} instances. + * @author phejl, mkleint + * @since 1.50 + */ +public final class LookupProviderSupport { + + private LookupProviderSupport() { + } + + /** + * Creates a platform lookup instance that combines the content from multiple sources. + * A convenience factory method for implementors of + * {@link org.netbeans.modules.j2ee.deployment.devmodules.api.J2eePlatform}. + * + * @param baseLookup initial, base content of the project lookup created by the plugin + * @param folderPath the path in the System Filesystem that is used as root for lookup composition, as for {@link Lookups#forPath}. + * The content of the folder is assumed to be {@link LookupProvider} instances. + * @return a lookup to be used in platform + */ + public static Lookup createCompositeLookup(Lookup baseLookup, String folderPath) { + return new DelegatingLookupImpl(baseLookup, folderPath); + } + + static class DelegatingLookupImpl extends ProxyLookup implements LookupListener { + private Lookup baseLookup; + private Lookup.Result providerResult; + private LookupListener providerListener; + private List old = Collections.emptyList(); + private List currentLookups; + + //private Lookup.Result mergers; + private Reference listenerRef; + //#68623: the proxy lookup fires changes only if someone listens on a particular template: + private List> results = new ArrayList>(); + + public DelegatingLookupImpl(Lookup base, String path) { + this(base, Lookups.forPath(path), path); + } + + public DelegatingLookupImpl(Lookup base, Lookup providerLookup, String path) { + super(); + assert base != null; + baseLookup = base; + providerResult = providerLookup.lookup(new Lookup.Template(LookupProvider.class)); + assert isAllJustLookupProviders(providerLookup) : + "Layer content at " + path + " contains other than LookupProvider instances! See messages.log file for more details."; //NOI18N + doDelegate(providerResult.allInstances()); + providerListener = new LookupListener() { + public void resultChanged(LookupEvent ev) { + doDelegate(providerResult.allInstances()); + } + }; + providerResult.addLookupListener( + WeakListeners.create(LookupListener.class, providerListener, providerResult)); + } + + //just for assertion evaluation. + private boolean isAllJustLookupProviders(Lookup lkp) { + Lookup.Result res = lkp.lookupResult(Object.class); + Set> set = res.allClasses(); + for (Class clzz : set) { + if (!LookupProvider.class.isAssignableFrom(clzz)) { + Logger.getLogger(LookupProviderSupport.class.getName()).warning("" + clzz.getName() + " is not instance of LookupProvider."); //NOI18N + return false; + } + } + return true; + } + + + public void resultChanged(LookupEvent ev) { + doDelegate(providerResult.allInstances()); + } + + + private synchronized void doDelegate(Collection providers) { + //unregister listeners from the old results: + for (Lookup.Result r : results) { + r.removeLookupListener(this); + } + + List newLookups = new ArrayList(); + for (LookupProvider elem : providers) { + if (old.contains(elem)) { + int index = old.indexOf(elem); + newLookups.add(currentLookups.get(index)); + } else { + Lookup newone = elem.createAdditionalLookup(baseLookup); + assert newone != null; + newLookups.add(newone); + } + } + old = new ArrayList(providers); + currentLookups = newLookups; + newLookups.add(baseLookup); + Lookup lkp = new ProxyLookup(newLookups.toArray(new Lookup[newLookups.size()])); + + //merge: +// List> filteredClasses = new ArrayList>(); +// List mergedInstances = new ArrayList(); +// LookupListener l = listenerRef != null ? listenerRef.get() : null; +// if (l != null) { +// mergers.removeLookupListener(l); +// } +// mergers = lkp.lookupResult(LookupMerger.class); +// l = WeakListeners.create(LookupListener.class, this, mergers); +// listenerRef = new WeakReference(l); +// mergers.addLookupListener(l); +// for (LookupMerger lm : mergers.allInstances()) { +// Class c = lm.getMergeableClass(); +// if (filteredClasses.contains(c)) { +// ErrorManager.getDefault().log(ErrorManager.WARNING, +// "Two LookupMerger registered for class " + c + +// ". Only first one will be used"); // NOI18N +// continue; +// } +// filteredClasses.add(c); +// mergedInstances.add(lm.merge(lkp)); +// +// Lookup.Result result = lkp.lookupResult(c); +// +// result.addLookupListener(this); +// results.add(result); +// } +// lkp = Lookups.exclude(lkp, filteredClasses.toArray(new Class[filteredClasses.size()])); +// Lookup fixed = Lookups.fixed(mergedInstances.toArray(new Object[mergedInstances.size()])); +// setLookups(fixed, lkp); + + setLookups(lkp); + } + } + +}