jadex.base.test.impl.SharedServiceFactory Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jadex-platform-bridge Show documentation
Show all versions of jadex-platform-bridge Show documentation
Jadex bridge is a base package for kernels and platforms, i.e., it is used by both and provides commonly used interfaces and classes for active components and their management.
package jadex.base.test.impl;
import java.lang.reflect.Method;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;
import jadex.bridge.IComponentIdentifier;
import jadex.bridge.service.IInternalService;
import jadex.bridge.service.annotation.OnEnd;
import jadex.bridge.service.annotation.OnStart;
import jadex.bridge.service.component.interceptors.ResolveInterceptor;
import jadex.commons.future.DelegationResultListener;
import jadex.commons.future.Future;
import jadex.commons.future.IFuture;
/**
* A factory for creating service instances that delegate to the same shared instance, i.e. it uses the first instance and ignores subsequent ones.
*/
public class SharedServiceFactory implements Function, T>
{
//-------- attributes --------
/** The wrapper creation function. */
protected BiFunction, SharedService> wrapperfactory;
/** The shared service instance. */
protected volatile T instance = null;
/** The init future of the shared service. */
protected volatile IFuture inited = null;
/** The usage count to know when the service can be shut down. */
protected volatile int cnt = 0;
//-------- constructors --------
/**
* Create a factory for service sharing.
* @param wrapperfactory Function to create the individual wrappers for each platform.
*/
public SharedServiceFactory(BiFunction, SharedService> wrapperfactory)
{
this.wrapperfactory = wrapperfactory;
}
/**
* Create a new wrapper for the first supplied instance.
*/
@SuppressWarnings("unchecked")
@Override
public T apply(Supplier creator)
{
synchronized(this)
{
if(instance==null)
{
instance = creator.get();
// System.out.println("Created shared service instance: "+instance);
}
}
return (T) wrapperfactory.apply(IComponentIdentifier.LOCAL.get(), this);
}
/**
* Start the original service on first invocation.
*/
public IFuture startService()
{
Future init = null;
synchronized(this)
{
cnt++;
if(inited==null)
{
init = new Future();
inited = init;
}
}
if(init!=null)
{
// System.out.println("Starting shared service instance: "+instance);
if(instance instanceof IInternalService)
{
((IInternalService)instance).startService().addResultListener(new DelegationResultListener(init));
}
else
{
Method m = ResolveInterceptor.searchMethod(instance.getClass(), OnStart.class);
if(m!=null)
{
try
{
Object ret = m.invoke(instance);
if(ret instanceof IFuture)
{
@SuppressWarnings("unchecked")
IFuture fut = (IFuture)ret;
fut.addResultListener(new DelegationResultListener(init));
}
else
{
init.setResult(null);
}
}
catch(Exception e)
{
init.setException(e);
}
}
else
{
init.setResult(null);
}
}
}
return inited;
}
/**
* Shutdown the original service on last invocation.
*/
public IFuture shutdownService()
{
Object tmp = null;
synchronized(this)
{
cnt--;
if(cnt==0)
{
tmp = instance;
// Clear to allow another platform to be started with new service.
instance = null;
inited = null;
}
}
if(tmp!=null)
{
// System.out.println("Terminating shared service instance: "+tmp);
if(tmp instanceof IInternalService)
{
return ((IInternalService)tmp).shutdownService();
}
else
{
Method m = ResolveInterceptor.searchMethod(tmp.getClass(), OnEnd.class);
if(m!=null)
{
try
{
Object ret = m.invoke(tmp);
if(ret instanceof IFuture)
{
@SuppressWarnings("unchecked")
IFuture fut = (IFuture)ret;
return fut;
}
else
{
return IFuture.DONE;
}
}
catch(Exception e)
{
return new Future<>(e);
}
}
else
{
return IFuture.DONE;
}
}
}
else
{
return IFuture.DONE;
}
}
}