All Downloads are FREE. Search and download functionalities are using the official Maven repository.

jadex.android.controlcenter.componentViewer.tree.CMSUpdateHandler Maven / Gradle / Ivy

Go to download

The Jadex rules tools package contains tools for the Jadex active components infrastructure.

The newest version!
package jadex.android.controlcenter.componentViewer.tree;

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.DefaultResultListener;
import jadex.commons.future.DelegationResultListener;
import jadex.commons.future.ExceptionDelegationResultListener;
import jadex.commons.future.Future;
import jadex.commons.future.IFuture;

import java.util.Collection;
import java.util.Iterator;

/**
 * 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();
				if (listeners != null && listeners.containsKey(event.getSource()))
				{
					Collection clis = listeners.getCollection(event.getSource());
					// System.out.println("cmshandler: "+CMSUpdateHandler.this+" "+event+" "+clis);
					informListeners(event, (ICMSComponentListener[]) 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()
	{

		IFuture ret;
		if (listeners != null)
		{
			Future fut = new Future();
			CounterResultListener crl = new CounterResultListener(listeners.keySet().size(), true, new DelegationResultListener(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)
	{

		// 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.put(cid, listener);
			// Ongoing registration.
			if (futures != null && futures.containsKey(cid))
			{
				futures.put(cid, ret);
			}
			// Registration already finished.
			else
			{
				ret.setResult(null);
			}
		}

		// First registration for cid.
		else
		{
			if (futures == null)
			{
				this.futures = new MultiCollection();
			}
			futures.put(cid, ret);
			listeners.put(cid, listener);

			SRemoteGui.installRemoteCMSListener(access, cid, rcl, buildId(cid)).addResultListener(new DefaultResultListener()
			{
				public void resultAvailable(Void result)
				{
					if (futures != null) // Todo: can be null?
					{
						Collection coll = futures.getCollection(cid);
						for (Iterator it = coll.iterator(); it.hasNext();)
						{
							((Future) it.next()).setResult(null);
						}
						futures.remove(cid);
						if (futures.isEmpty())
							futures = null;
					}
				}

				public void customExceptionOccurred(Exception exception)
				{
					// System.out.println("remove: "+cid+", "+listener+", "+this);
					if (listeners != null)
						listeners.remove(cid, listener);

					if (futures != null) // Todo: why can be null?
					{
						Collection coll = futures.getCollection(cid);
						for (Iterator it = coll.iterator(); it.hasNext();)
						{
							((Future) 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)
	{

		// 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.remove(cid, listener);
			if (!listeners.containsKey(cid))
			{
				Future fut = new Future();
				ret = fut;
				SRemoteGui.deregisterRemoteCMSListener(access, cid, buildId(cid)).addResultListener(new DelegationResultListener(fut));
				if (listeners.isEmpty())
					listeners = null;
			}
		}
		return ret;
	}

	/**
	 * Get the local CMS.
	 * 
	 * @return The local CMS.
	 */
	public IFuture getLocalCMS()
	{
		IFuture ret = SServiceProvider.getService(access.getServiceProvider(), IComponentManagementService.class,
				RequiredServiceInfo.SCOPE_PLATFORM);
		return ret;
	}

	// -------- helper methods --------

	/**
	 * Inform listeners about an event.
	 */
	protected void informListeners(final ChangeEvent event, ICMSComponentListener[] cls)
	{
		if (RemoteCMSListener.EVENT_COMPONENT_ADDED.equals(event.getType()))
		{
			for (int i = 0; i < cls.length; i++)
			{
				final ICMSComponentListener lis = cls[i];
				lis.componentAdded((IComponentDescription) event.getValue()).addResultListener(new DefaultResultListener()
				{
					public void resultAvailable(Void result)
					{
					}

					public void exceptionOccurred(Exception exception)
					{
						removeCMSListener(((IComponentDescription) event.getValue()).getName(), lis);
					}
				});
			}
		} else if (RemoteCMSListener.EVENT_COMPONENT_CHANGED.equals(event.getType()))
		{
			for (int i = 0; i < cls.length; i++)
			{
				final ICMSComponentListener lis = cls[i];
				lis.componentChanged((IComponentDescription) event.getValue()).addResultListener(new DefaultResultListener()
				{
					public void resultAvailable(Void result)
					{
					}

					public void exceptionOccurred(Exception exception)
					{
						removeCMSListener(((IComponentDescription) event.getValue()).getName(), lis);
					}
				});
			}
		} else if (RemoteCMSListener.EVENT_COMPONENT_REMOVED.equals(event.getType()))
		{
			for (int i = 0; i < cls.length; i++)
			{
				// Todo: component results?
				final ICMSComponentListener lis = cls[i];
				// System.out.println("rem compo: "+((IComponentDescription)event.getValue()).getName());
				cls[i].componentRemoved((IComponentDescription) event.getValue(), null).addResultListener(new DefaultResultListener()
				{
					public void resultAvailable(Void result)
					{
					}

					public void exceptionOccurred(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.getServiceProvider(), IComponentManagementService.class, RequiredServiceInfo.SCOPE_PLATFORM).addResultListener(
				new ExceptionDelegationResultListener(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.getServiceProvider(), IComponentManagementService.class, RequiredServiceInfo.SCOPE_PLATFORM).addResultListener(
				new ExceptionDelegationResultListener(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