Index: xml/core/src/org/netbeans/modules/xml/core/cookies/CookieManager.java =================================================================== RCS file: /cvs/xml/core/src/org/netbeans/modules/xml/core/cookies/CookieManager.java,v retrieving revision 1.1 diff -u -r1.1 CookieManager.java --- xml/core/src/org/netbeans/modules/xml/core/cookies/CookieManager.java 12 Sep 2001 14:52:47 -0000 1.1 +++ xml/core/src/org/netbeans/modules/xml/core/cookies/CookieManager.java 1 Feb 2002 11:20:11 -0000 @@ -7,7 +7,7 @@ * http://www.sun.com/ * * The Original Code is NetBeans. The Initial Developer of the Original - * Code is Sun Microsystems, Inc. Portions Copyright 1997-2001 Sun + * Code is Sun Microsystems, Inc. Portions Copyright 1997-2002 Sun * Microsystems, Inc. All Rights Reserved. */ package org.netbeans.modules.xml.core.cookies; @@ -41,8 +41,6 @@ /** */ public CookieManager (DataObject dataObject, CookieSet cookieSet, Class clazz) { - super (clazz); - if ( CookieFactoryCreator.class.isAssignableFrom (clazz) == false ) { throw new IllegalArgumentException ("Parameter class must extend CookieFactoryCreator class."); } @@ -51,15 +49,10 @@ this.cookieSet = cookieSet; this.factoryMap = new HashMap(); - init(); - } + register(clazz); - /** - */ - private void init () { - addedToResult (getResult()); + addedToResult(getResult()); } - /** */ @@ -77,6 +70,7 @@ /** */ protected void addedToResult (Collection added) { + // XXX is getResult() meant here (rather than added)? Iterator it = getResult().iterator(); while ( it.hasNext() ) { CookieFactoryCreator creator = (CookieFactoryCreator) it.next(); Index: xml/core/src/org/netbeans/modules/xml/core/lib/LookupManager.java =================================================================== RCS file: /cvs/xml/core/src/org/netbeans/modules/xml/core/lib/LookupManager.java,v retrieving revision 1.1 diff -u -r1.1 LookupManager.java --- xml/core/src/org/netbeans/modules/xml/core/lib/LookupManager.java 12 Sep 2001 14:52:48 -0000 1.1 +++ xml/core/src/org/netbeans/modules/xml/core/lib/LookupManager.java 1 Feb 2002 11:20:12 -0000 @@ -7,102 +7,116 @@ * http://www.sun.com/ * * The Original Code is NetBeans. The Initial Developer of the Original - * Code is Sun Microsystems, Inc. Portions Copyright 1997-2001 Sun + * Code is Sun Microsystems, Inc. Portions Copyright 1997-2002 Sun * Microsystems, Inc. All Rights Reserved. */ package org.netbeans.modules.xml.core.lib; -import java.util.Collection; -import java.util.ArrayList; +import java.util.*; -import org.openide.util.Lookup; -import org.openide.util.LookupListener; -import org.openide.util.LookupEvent; +import org.openide.util.*; /** * - * @author Libor Kramolis - * @version 0.1 + * @author Libor Kramolis, Jesse Glick + * @version 0.2 */ public abstract class LookupManager { - /** */ - private final Class lookupClass; - /** */ - private Lookup.Result lookupResult; - /** */ - private Collection lastResult; - - // - // init - // - - /** Create new LookupManager. */ - public LookupManager (Class clazz) { - lookupClass = clazz; - } - /** - */ - private Lookup.Result getLookupResult () { - if ( lookupResult == null ) { - lookupResult = (Lookup.getDefault()).lookup (new Lookup.Template (lookupClass)); - lookupResult.addLookupListener (new LookupListenerImpl()); + private static final Map handles = new WeakHashMap(); // Map + + private static final class Handle implements LookupListener { + + private final Class clazz; + private Lookup.Result lookupResult = null; + private Collection lastResult = null; + private final Set lms = new WeakSet(300); // Set + + private Handle(Class clazz) { + this.clazz = clazz; } - return lookupResult; - } - - // - // itself - // + public void register(LookupManager lm) { + synchronized (lms) { + lms.add(lm); + } + } - /** - */ - protected final Collection getResult () { - lastResult = getLookupResult().allInstances(); + private Lookup.Result getLookupResult () { + if ( lookupResult == null ) { + lookupResult = (Lookup.getDefault()).lookup (new Lookup.Template (clazz)); + lookupResult.addLookupListener (this); + } + return lookupResult; + } - return lastResult; - } + public void resultChanged (LookupEvent evt) { + Collection currentResult = getLookupResult().allInstances(); - /** - */ - private void updateResult () { - Collection currentResult = getLookupResult().allInstances(); - Collection lastResultCopy = new ArrayList (lastResult); - Collection currentResultCopy = new ArrayList (currentResult); - - if ( lastResultCopy.removeAll (currentResult) ) { - removedFromResult (lastResultCopy); + Collection removed = new HashSet(lastResult); + removed.removeAll(currentResult); + Collection added = new HashSet(currentResult); + added.removeAll(lastResult); + if (!removed.isEmpty() || !added.isEmpty()) { + synchronized (lms) { + Iterator it = lms.iterator(); + while (it.hasNext()) { + LookupManager lm = (LookupManager)it.next(); + if (!removed.isEmpty()) lm.removedFromResult(removed); + if (!added.isEmpty()) lm.addedToResult(added); + } + } + } + + lastResult = currentResult; } - if ( currentResultCopy.removeAll (lastResult) ) { - addedToResult (currentResultCopy); + + public Collection getInstances() { + if (lastResult == null) { + lastResult = getLookupResult().allInstances(); + } + return lastResult; } - lastResult = currentResult; } + + private Handle handle = null; - /** - */ - protected abstract void removedFromResult (Collection removed); + // + // init + // + + /** Create new LookupManager. Call register() when ready. */ + public LookupManager () {} - /** + /** To be called when it is fully initialized and ready to receive events. + * Subclasses may wish to call addedToResult(getResults()) immediately. */ - protected abstract void addedToResult (Collection added); + protected final void register(Class clazz) { + if (handle != null) throw new IllegalStateException(); + synchronized (handles) { + handle = (Handle)handles.get(clazz); + if (handle == null) { + handles.put(clazz, handle = new Handle(clazz)); + } + } + handle.register(this); + } + protected final Collection getResult() { + return handle.getInstances(); + } // - // class LookupListenerImpl + // itself // /** */ - private class LookupListenerImpl implements LookupListener { - /** - */ - public void resultChanged (LookupEvent evt) { - LookupManager.this.updateResult(); - } + protected abstract void removedFromResult (Collection removed); - } // end: class LookupListenerImpl + /** + */ + protected abstract void addedToResult (Collection added); }