/*
* 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-2002 Sun
* Microsystems, Inc. All Rights Reserved.
*/
package org.openide.util.lookup;
import java.util.*;
import org.openide.util.Lookup;
import org.openide.util.LookupListener;
import org.openide.util.LookupEvent;
/**
* Simple proxy lookup. Keeps reference to a lookup it delegates to and
* forwards all requests.
*
* @author Jaroslav Tulach
*/
final class SimpleProxyLookup extends org.openide.util.Lookup {
/** the provider to check for the status */
private Provider provider;
/** the lookup we currently delegate to */
private Lookup delegate;
/** set of all results associated to this lookup */
private org.openide.util.WeakSet results;
/**
* @param provider provider to delegate to
*/
SimpleProxyLookup(Provider provider) {
this.provider = provider;
}
/** Checks whether we still delegate to the same lookup */
private Lookup checkLookup () {
Lookup l = provider.getLookup ();
Iterator toCheck = null;
synchronized (this) {
if (l != delegate) {
this.delegate = l;
if (results != null) {
toCheck = Arrays.asList (results.toArray ()).iterator();
}
}
}
if (toCheck != null) {
// update
Iterator it = toCheck;
while (it.hasNext()) {
ProxyResult p = (ProxyResult)it.next ();
if (p.updateLookup (l)) {
p.resultChanged (null);
}
}
}
return delegate;
}
public Result lookup(Template template) {
ProxyResult p = new ProxyResult (template);
synchronized (this) {
if (results == null) {
results = new org.openide.util.WeakSet ();
}
results.add (p);
}
return p;
}
public Object lookup(Class clazz) {
return checkLookup ().lookup (clazz);
}
public Item lookupItem(Template template) {
return checkLookup ().lookupItem (template);
}
/**
* Result used in SimpleLookup. It holds a reference to the collection
* passed in constructor. As the contents of this lookup result never
* changes the addLookupListener and removeLookupListener are empty.
*/
private final class ProxyResult extends WaitableResult
implements LookupListener {
/** Template used for this result. It is never null.*/
private Template template;
/** result to delegate to */
private Lookup.Result delegate;
/** listeners set */
private javax.swing.event.EventListenerList listeners;
/** Just remembers the supplied argument in variable template.*/
ProxyResult (Template template) {
this.template = template;
}
/** Checks state of the result
*/
private Result checkResult () {
updateLookup (checkLookup ());
return this.delegate;
}
/** Updates the state of the lookup.
* @return true if the lookup really changed
*/
public boolean updateLookup (Lookup l) {
Collection oldPairs = delegate != null ? delegate.allItems () : null;
synchronized (this) {
if (delegate != null) {
delegate.removeLookupListener (this);
}
delegate = l.lookup (template);
delegate.addLookupListener (this);
}
if (oldPairs == null) {
// nobody knows about a change
return false;
}
Collection newPairs = delegate.allItems ();
return !oldPairs.equals (newPairs);
}
public synchronized void addLookupListener(LookupListener l) {
if (listeners == null) {
listeners = new javax.swing.event.EventListenerList ();
}
listeners.add (LookupListener.class, l);
}
public synchronized void removeLookupListener(LookupListener l) {
if (listeners != null) {
listeners.remove (LookupListener.class, l);
}
}
public java.util.Collection allInstances() {
return checkResult ().allInstances ();
}
public Set allClasses () {
return checkResult ().allClasses ();
}
public Collection allItems () {
return checkResult ().allItems ();
}
protected void beforeLookup(Lookup.Template t) {
Lookup.Result r = checkResult ();
if (r instanceof WaitableResult) {
((WaitableResult)r).beforeLookup (t);
}
}
/** A change in lookup occured.
* @param ev event describing the change
*
*/
public void resultChanged(LookupEvent anEvent) {
javax.swing.event.EventListenerList l = this.listeners;
if (l == null) return;
Object[] listeners = l.getListenerList();
if (listeners.length == 0) return;
LookupEvent ev = new LookupEvent (this);
AbstractLookup.notifyListeners(listeners, ev);
}
} // end of ProxyResult
}