jadex.base.gui.CMSUpdateHandler Maven / Gradle / Ivy
package jadex.base.gui;
import java.util.Collection;
import java.util.Iterator;
import javax.swing.SwingUtilities;
import jadex.base.RemoteCMSListener;
import jadex.base.SRemoteGui;
import jadex.bridge.IComponentIdentifier;
import jadex.bridge.IExternalAccess;
import jadex.bridge.service.RequiredServiceInfo;
import jadex.bridge.service.search.SServiceProvider;
import jadex.bridge.service.types.cms.ICMSComponentListener;
import jadex.bridge.service.types.cms.IComponentDescription;
import jadex.bridge.service.types.cms.IComponentManagementService;
import jadex.commons.ChangeEvent;
import jadex.commons.IRemoteChangeListener;
import jadex.commons.collection.MultiCollection;
import jadex.commons.future.CounterResultListener;
import jadex.commons.future.Future;
import jadex.commons.future.IFuture;
import jadex.commons.gui.future.SwingDefaultResultListener;
import jadex.commons.gui.future.SwingDelegationResultListener;
import jadex.commons.gui.future.SwingExceptionDelegationResultListener;
/**
* A change handler which receives remote CMS events and delegates to the registered listeners.
*/
public class CMSUpdateHandler
{
//-------- attributes --------
/** The local external access. */
protected IExternalAccess access;
/** The change listener called from remote. */
protected IRemoteChangeListener> rcl;
/** The local listeners for the remote CMSs (cms cid->listeners). */
protected MultiCollection listeners;
/** The futures of listeners registered during ongoing installation (cms cid->futures). */
protected MultiCollection> futures;
//-------- constructors --------
/**
* Create a CMS update handler.
*/
public CMSUpdateHandler(IExternalAccess access)
{
this.access = access;
this.rcl = new IRemoteChangeListener()
{
public IFuture changeOccurred(final ChangeEvent event)
{
final Future ret = new Future();
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
if(listeners!=null && listeners.containsKey(event.getSource()))
{
Collection clis = listeners.getCollection(event.getSource());
// System.out.println("cmshandler: "+CMSUpdateHandler.this+" "+event+" "+clis);
informListeners(event, clis.toArray(new ICMSComponentListener[clis.size()]));
ret.setResult(null);
}
else
{
// Set exception to trigger listener removal.
ret.setException(new RuntimeException("No more listeners."));
}
}
});
return ret;
}
};
}
//-------- methods --------
/**
* Dispose the handler for triggering remote listener removal.
*/
public IFuture dispose()
{
assert SwingUtilities.isEventDispatchThread();// || Starter.isShutdown();
IFuture ret;
if(listeners!=null)
{
Future fut = new Future();
CounterResultListener crl = new CounterResultListener(listeners.keySet().size(), true, new SwingDelegationResultListener(fut));
for(Iterator> it=listeners.keySet().iterator(); it.hasNext(); )
{
IComponentIdentifier cid = (IComponentIdentifier)it.next();
// Deregister if not registration in progress.
if(futures==null || !futures.containsKey(cid))
SRemoteGui.deregisterRemoteCMSListener(access, cid, buildId(cid)).addResultListener(crl);
else
crl.resultAvailable(null);
}
listeners = null;
ret = fut;
}
else
{
ret = IFuture.DONE;
}
return ret;
}
/**
* Add a CMS listener.
*/
public IFuture addCMSListener(final IComponentIdentifier cid, final ICMSComponentListener listener)
{
assert SwingUtilities.isEventDispatchThread();
// System.out.println("added: "+cid+" "+listener+" "+this);
// if(cid==null)
// System.out.println("cid: "+cid);
// if(cid.getPlatformName()==null)
// System.out.println("platformname: "+cid.getPlatformName());
// if(access==null)
// System.out.println("access: "+access);
// if(access.getComponentIdentifier()==null)
// System.out.println("accesscid"+access.getComponentIdentifier());
// if(access.getComponentIdentifier().getPlatformName()==null)
// System.out.println("accesscidpfname: "+access.getComponentIdentifier().getPlatformName());
// For local component use direct listener.
if(cid.getPlatformName().equals(access.getComponentIdentifier().getPlatformName()))
{
return installLocalCMSListener(listener);
}
Future ret = new Future();
if(listeners==null)
{
this.listeners = new MultiCollection();
}
// Already registered
if(listeners.containsKey(cid))
{
listeners.add(cid, listener);
// Ongoing registration.
if(futures!=null && futures.containsKey(cid))
{
futures.add(cid, ret);
}
// Registration already finished.
else
{
ret.setResult(null);
}
}
// First registration for cid.
else
{
if(futures==null)
{
this.futures = new MultiCollection>();
}
futures.add(cid, ret);
listeners.add(cid, listener);
SRemoteGui.installRemoteCMSListener(access, cid, rcl, buildId(cid))
.addResultListener(new SwingDefaultResultListener()
{
public void customResultAvailable(Void result)
{
assert SwingUtilities.isEventDispatchThread();
if(futures!=null) // Todo: can be null?
{
Collection> coll = futures.getCollection(cid);
for(Iterator> it=coll.iterator(); it.hasNext(); )
{
it.next().setResult(null);
}
futures.remove(cid);
if(futures.isEmpty())
futures = null;
}
}
public void customExceptionOccurred(Exception exception)
{
assert SwingUtilities.isEventDispatchThread();
// System.out.println("remove: "+cid+", "+listener+", "+this);
if(listeners!=null)
listeners.removeObject(cid, listener);
if(futures!=null) // Todo: why can be null?
{
Collection> coll = futures.getCollection(cid);
for(Iterator> it=coll.iterator(); it.hasNext(); )
{
it.next().setException(exception);
}
futures.remove(cid);
if(futures.isEmpty())
futures = null;
}
}
});
}
return ret;
}
/**
* Remove a CMS listener.
*/
public IFuture removeCMSListener(IComponentIdentifier cid, ICMSComponentListener listener)
{
assert SwingUtilities.isEventDispatchThread();// || Starter.isShutdown();
// System.out.println("removed lis: "+cid+" "+listener+" "+this);
IFuture ret = IFuture.DONE;
// For local component use direct listener.
if(cid.getPlatformName().equals(access.getComponentIdentifier().getPlatformName()))
{
ret = removeLocalCMSListener(listener);
}
else if(listeners!=null)
{
// System.out.println("remove: "+cid+", "+listener+", "+this);
listeners.removeObject(cid, listener);
if(!listeners.containsKey(cid))
{
Future fut = new Future();
ret = fut;
SRemoteGui.deregisterRemoteCMSListener(access, cid, buildId(cid))
.addResultListener(new SwingDelegationResultListener(fut));
if(listeners.isEmpty())
listeners = null;
}
}
return ret;
}
/**
* Get the local CMS.
* @return The local CMS.
*/
public IFuture getLocalCMS()
{
IFuture ret = SServiceProvider.getService(access, IComponentManagementService.class, RequiredServiceInfo.SCOPE_PLATFORM);
return ret;
}
//-------- helper methods --------
/**
* Inform listeners about an event.
*/
protected void informListeners(final ChangeEvent> event, ICMSComponentListener[] cls)
{
assert SwingUtilities.isEventDispatchThread();
if(RemoteCMSListener.EVENT_COMPONENT_ADDED.equals(event.getType()))
{
for(int i=0; i()
{
public void customResultAvailable(Void result)
{
}
public void customExceptionOccurred(Exception exception)
{
removeCMSListener(((IComponentDescription)event.getValue()).getName(), lis);
}
});
}
}
else if(RemoteCMSListener.EVENT_COMPONENT_CHANGED.equals(event.getType()))
{
for(int i=0; i()
{
public void customResultAvailable(Void result)
{
}
public void customExceptionOccurred(Exception exception)
{
removeCMSListener(((IComponentDescription)event.getValue()).getName(), lis);
}
});
}
}
else if(RemoteCMSListener.EVENT_COMPONENT_REMOVED.equals(event.getType()))
{
for(int i=0; i()
{
public void customResultAvailable(Void result)
{
}
public void customExceptionOccurred(Exception exception)
{
removeCMSListener(((IComponentDescription)event.getValue()).getName(), lis);
}
});
}
}
else if(RemoteCMSListener.EVENT_BULK.equals(event.getType()))
{
Collection> events = (Collection>)event.getValue();
for(Iterator> it=events.iterator(); it.hasNext(); )
{
informListeners(it.next(), cls);
}
}
}
/**
* Install a local listener.
* @param listener The local listener.
*/
protected IFuture installLocalCMSListener(final ICMSComponentListener listener)
{
final Future ret = new Future();
SServiceProvider.getService(access, IComponentManagementService.class, RequiredServiceInfo.SCOPE_PLATFORM)
.addResultListener(new SwingExceptionDelegationResultListener(ret)
{
public void customResultAvailable(IComponentManagementService cms)
{
// IComponentManagementService cms = (IComponentManagementService)result;
cms.addComponentListener(null, listener);
ret.setResult(null);
}
});
return ret;
}
/**
* Remove a local listener.
* @param listener The local listener.
*/
protected IFuture removeLocalCMSListener(final ICMSComponentListener listener)
{
final Future ret = new Future();
SServiceProvider.getService(access, IComponentManagementService.class, RequiredServiceInfo.SCOPE_PLATFORM)
.addResultListener(new SwingExceptionDelegationResultListener(ret)
{
public void customResultAvailable(IComponentManagementService cms)
{
// IComponentManagementService cms = (IComponentManagementService)result;
cms.removeComponentListener(null, listener);
ret.setResult(null);
}
});
return ret;
}
/**
* Build an id to be used for remote listener (de-)registration.
* @param cid The remote component id.
* @return An id for remote listener (de-)registration.
*/
protected String buildId(final IComponentIdentifier cid)
{
return "cmslistener_"+hashCode()+"_"+access.getComponentIdentifier().toString()+"_"+cid;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy