Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
jadex.platform.service.cms.ComponentManagementService Maven / Gradle / Ivy
package jadex.platform.service.cms;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Logger;
import jadex.base.PlatformConfiguration;
import jadex.base.Starter;
import jadex.bridge.BasicComponentIdentifier;
import jadex.bridge.Cause;
import jadex.bridge.ClassInfo;
import jadex.bridge.ComponentCreationException;
import jadex.bridge.ComponentNotFoundException;
import jadex.bridge.ComponentTerminatedException;
import jadex.bridge.FactoryFilter;
import jadex.bridge.IComponentIdentifier;
import jadex.bridge.IExternalAccess;
import jadex.bridge.IInternalAccess;
import jadex.bridge.IResourceIdentifier;
import jadex.bridge.ISearchConstraints;
import jadex.bridge.SFuture;
import jadex.bridge.ServiceCall;
import jadex.bridge.component.ComponentCreationInfo;
import jadex.bridge.component.IArgumentsResultsFeature;
import jadex.bridge.component.IComponentFeatureFactory;
import jadex.bridge.component.IExecutionFeature;
import jadex.bridge.component.ISubcomponentsFeature;
import jadex.bridge.component.impl.IInternalArgumentsResultsFeature;
import jadex.bridge.component.impl.IInternalExecutionFeature;
import jadex.bridge.component.impl.IInternalSubcomponentsFeature;
import jadex.bridge.modelinfo.Argument;
import jadex.bridge.modelinfo.IModelInfo;
import jadex.bridge.modelinfo.SubcomponentTypeInfo;
import jadex.bridge.modelinfo.UnparsedExpression;
import jadex.bridge.service.IServiceIdentifier;
import jadex.bridge.service.RequiredServiceInfo;
import jadex.bridge.service.annotation.Service;
import jadex.bridge.service.annotation.ServiceComponent;
import jadex.bridge.service.annotation.ServiceIdentifier;
import jadex.bridge.service.annotation.ServiceShutdown;
import jadex.bridge.service.annotation.ServiceStart;
import jadex.bridge.service.component.IRequiredServicesFeature;
import jadex.bridge.service.search.SServiceProvider;
import jadex.bridge.service.search.ServiceNotFoundException;
import jadex.bridge.service.search.ServiceRegistry;
import jadex.bridge.service.search.SynchronizedServiceRegistry;
import jadex.bridge.service.types.clock.IClockService;
import jadex.bridge.service.types.cms.CMSComponentDescription;
import jadex.bridge.service.types.cms.CreationInfo;
import jadex.bridge.service.types.cms.ICMSComponentListener;
import jadex.bridge.service.types.cms.IComponentDescription;
import jadex.bridge.service.types.cms.IComponentManagementService;
import jadex.bridge.service.types.factory.IComponentFactory;
import jadex.bridge.service.types.factory.IPlatformComponentAccess;
import jadex.bridge.service.types.library.ILibraryService;
import jadex.bridge.service.types.message.IMessageService;
import jadex.bridge.service.types.monitoring.IMonitoringService.PublishEventLevel;
import jadex.bridge.service.types.remote.IRemoteServiceManagementService;
import jadex.commons.ResourceInfo;
import jadex.commons.SUtil;
import jadex.commons.Tuple;
import jadex.commons.Tuple2;
import jadex.commons.collection.LRU;
import jadex.commons.collection.MultiCollection;
import jadex.commons.collection.SCollection;
import jadex.commons.future.CollectionResultListener;
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.FutureHelper;
import jadex.commons.future.IFuture;
import jadex.commons.future.IIntermediateResultListener;
import jadex.commons.future.IResultListener;
import jadex.commons.future.ISubscriptionIntermediateFuture;
import jadex.commons.future.ITerminationCommand;
import jadex.commons.future.ITuple2Future;
import jadex.commons.future.SubscriptionIntermediateFuture;
import jadex.commons.future.Tuple2Future;
import jadex.javaparser.IParsedExpression;
import jadex.javaparser.SJavaParser;
import jadex.javaparser.SimpleValueFetcher;
import jadex.kernelbase.IBootstrapFactory;
/**
* Abstract default implementation of component management service.
*/
@Service
public class ComponentManagementService implements IComponentManagementService
{
//-------- attributes --------
/** Flag to avoid double initialization. */
protected boolean running;
/** The agent. */
@ServiceComponent
protected IInternalAccess agent;
@ServiceIdentifier
protected IServiceIdentifier sid;
/** The platform access. */
protected IPlatformComponentAccess access;
/** The logger. */
protected Logger logger;
/** The components (id->component). */
protected Map components;
/** The cleanup commands for the components (component id -> cleanup command). */
protected Map ccs;
/** The cleanup futures for the components (component id -> cleanup future). */
protected Map>> cfs;
/** The listeners. */
protected MultiCollection listeners;
// /** The execution service (cached to avoid using futures). */
// protected IExecutionService exeservice;
// /** The message service (cached to avoid using futures). */
// protected IMessageService msgservice;
/** The init adapters and descriptions, i.e. adapters and desc of initing components,
* are only visible for the component and child components in their init. */
protected Map initinfos;
/** Number of non-daemon children for each autoshutdown component (cid->Integer). */
protected Map childcounts;
/** The local filename cache (tuple(parent filename, child filename) -> local typename)*/
protected Map localtypes;
/** The cached factories. */
protected Collection factories;
/** The bootstrap component factory. */
protected IBootstrapFactory componentfactory;
/** The locked components (component are locked till init is finished,
i.e. if destroy is called during init it wait till lock is away). */
protected Map lockentries;
// /** The time service. */
// protected IClockService clockservice;
/** Flag to enable unique id generation. */
// Todo: move to platform data ?
protected boolean uniqueids;
/** The cid count. */
protected Map cidcounts;
//-------- constructors --------
/**
* Create a new component execution service.
* @param exta The service provider.
*/
public ComponentManagementService(IPlatformComponentAccess access, IBootstrapFactory componentfactory, boolean uniqueids)
{
this.access = access;
this.componentfactory = componentfactory;
this.uniqueids = uniqueids;
this.components = SCollection.createHashMap();
this.ccs = SCollection.createLinkedHashMap();
this.cfs = SCollection.createLinkedHashMap();
// this.logger = Logger.getLogger(AbstractComponentAdapter.getLoggerName(exta.getComponentIdentifier())+".cms");
this.listeners = SCollection.createMultiCollection();
this.initinfos = SCollection.createHashMap();
this.childcounts = SCollection.createHashMap();
this.localtypes = new LRU(100);
this.lockentries = SCollection.createHashMap();
this.cidcounts = new HashMap();
putInitInfo(access.getInternalAccess().getComponentIdentifier(), new InitInfo(access, null, null));
}
//-------- IComponentManagementService interface --------
/**
* Load a component model.
* @param name The component name.
* @return The model info of the
*/
public IFuture loadComponentModel(final String filename, final IResourceIdentifier rid)
{
// if(filename!=null && filename.indexOf("Remote")!=-1)
// System.out.println("cache miss: "+filename);
final Future ret = new Future();
if(filename==null)
{
ret.setException(new IllegalArgumentException("Filename must not null"));
}
else
{
SServiceProvider.getService(agent, ILibraryService.class, RequiredServiceInfo.SCOPE_PLATFORM)
.addResultListener(createResultListener(new ExceptionDelegationResultListener(ret)
{
public void customResultAvailable(final ILibraryService ls)
{
IFuture fut = SServiceProvider.getService(agent, IComponentFactory.class, RequiredServiceInfo.SCOPE_PLATFORM, new FactoryFilter(filename, null, rid));
fut.addResultListener(createResultListener(new ExceptionDelegationResultListener(ret)
{
public void customResultAvailable(IComponentFactory factory)
{
factory.loadModel(filename, null, rid)
.addResultListener(new DelegationResultListener(ret));
}
public void exceptionOccurred(Exception exception)
{
if(exception instanceof ServiceNotFoundException)
{
ret.setResult(null);
}
else
{
super.exceptionOccurred(exception);
}
}
}));
}
}));
}
return ret;
}
/**
* Create a new component on the platform.
* @param model The model identifier (e.g. file name).
* @param info Additional start information such as parent component or arguments (optional).
* @return The id of the component and the results after the component has been killed.
*/
public ITuple2Future> createComponent(String model, CreationInfo info)
{
return createComponent(null, model, info);
}
/**
* Create a new component on the platform.
* @param name The component name or null for automatic generation.
* @param model The model identifier (e.g. file name).
* @param info Additional start information such as parent component or arguments (optional).
* @return The id of the component and the results after the component has been killed.
*/
public ITuple2Future> createComponent(String name, final String model, CreationInfo info)
{
// final Tuple2Future> ret = new Tuple2Future>();
final Tuple2Future> ret = (Tuple2Future>)SFuture.getNoTimeoutFuture(Tuple2Future.class, agent);
createComponent(name, model, info, new IResultListener>>()
{
public void resultAvailable(Collection> result)
{
// if(model.toString().indexOf("Feature")!=-1)
// System.err.println("createComponent.resultAvailable: "+model+", "+result);
ret.setSecondResultIfUndone(Argument.convertArguments(result));
}
public void exceptionOccurred(Exception exception)
{
ret.setExceptionIfUndone(exception);
}
}).addResultListener(new IResultListener()
{
public void resultAvailable(IComponentIdentifier result)
{
ret.setFirstResultIfUndone(result);
}
public void exceptionOccurred(Exception exception)
{
ret.setExceptionIfUndone(exception);
}
});
return ret;
}
/**
* Create a new component on the platform.
* This method allows for retrieving intermediate results of the component via
* status events.
* @param name The component name or null for automatic generation.
* @param model The model identifier (e.g. file name).
* @param info Additional start information such as parent component or arguments (optional).
* @return The status events of the components. Consists of CMSCreatedEvent, (CMSIntermediateResultEvent)*, CMSTerminatedEvent
*/
public ISubscriptionIntermediateFuture createComponent(CreationInfo info, String name, String model)
{
final SubscriptionIntermediateFuture ret = (SubscriptionIntermediateFuture)SFuture.getNoTimeoutFuture(SubscriptionIntermediateFuture.class, agent);
final IComponentIdentifier[] mycid = new IComponentIdentifier[1];
final boolean[] terminate = new boolean[1];
ret.setTerminationCommand(new ITerminationCommand()
{
public void terminated(Exception reason)
{
if(mycid[0]!=null)
{
destroyComponent(mycid[0]);
}
else
{
terminate[0] = true;
}
}
public boolean checkTermination(Exception reason)
{
return true;
}
});
createComponent(name, model, info, new IIntermediateResultListener>()
{
Map results = new HashMap();
public void intermediateResultAvailable(Tuple2 result)
{
ret.addIntermediateResultIfUndone(new CMSIntermediateResultEvent(mycid[0], result.getFirstEntity(), result.getSecondEntity()));
results.put(result.getFirstEntity(), result.getSecondEntity());
}
public void resultAvailable(Collection> result)
{
if(result!=null)
{
for(Tuple2 res: result)
{
intermediateResultAvailable(res);
}
}
finished();
}
public void finished()
{
ret.addIntermediateResultIfUndone(new CMSTerminatedEvent(mycid[0], results));
ret.setFinishedIfUndone();
}
public void exceptionOccurred(Exception exception)
{
ret.setExceptionIfUndone(exception);
}
}).addResultListener(new IResultListener()
{
public void resultAvailable(IComponentIdentifier cid)
{
mycid[0] = cid;
ret.addIntermediateResultIfUndone(new CMSCreatedEvent(cid));
if(terminate[0])
{
destroyComponent(cid);
}
}
public void exceptionOccurred(Exception exception)
{
ret.setExceptionIfUndone(exception);
}
});
return ret;
}
/**
* Create a new component on the platform.
* @param name The component name.
* @param model The model identifier (e.g. file name).
* @param info The creation info, if any.
* @param listener The result listener (if any). Will receive the id of the component as result, when the component has been created.
* @param resultlistener The kill listener (if any). Will receive the results of the component execution, after the component has terminated.
*/
public IFuture createComponent(final String name, final String modelname, CreationInfo info,
final IResultListener>> resultlistener)
{
if(modelname==null)
return new Future(new IllegalArgumentException("Error creating component: " + name + " : Modelname must not be null."));
// System.out.println("create: "+name+" "+modelname+" "+agent.getComponentIdentifier());
// if(name!=null && name.toLowerCase().indexOf("provider")!=-1)
// System.out.println("create compo: "+modelname+" "+info);
ServiceCall sc = ServiceCall.getCurrentInvocation();
final IComponentIdentifier creator = sc==null? null: sc.getCaller();
final Cause curcause = sc==null? agent.getComponentDescription().getCause(): sc.getCause();
// if(modelname.indexOf("jadex.platform.service.message.transport.ssltcpmtp.ProviderAgent")!=-1)
// System.out.println("create: "+modelname);//+" "+info!=null? info.getResourceIdentifier(): "norid");
// final DebugException de = new DebugException();
// if(modelname.indexOf("Provider")!=-1)
// System.out.println("create component: "+modelname+" "+name);
final Future inited = new Future();
final Future resfut = new Future();
final CreationInfo cinfo = new CreationInfo(info); // Dummy default info, if null. Must be cloned as localtype is set on info later.
if(cinfo.getParent()!=null)
{
// Check if parent is killing itself -> no new child component, exception
if(cfs.containsKey(cinfo.getParent()))
return new Future(new ComponentTerminatedException(cinfo.getParent() ,"Parent is killing itself. Child component creation no allowed."));
}
if(cinfo.getParent()!=null && isRemoteComponent(cinfo.getParent()))
{
getRemoteCMS(cinfo.getParent()).addResultListener(createResultListener(
new ExceptionDelegationResultListener(inited)
{
public void customResultAvailable(IComponentManagementService rcms)
{
// todo: problem, the call will get a wrong caller due to IComponentIdentidier.LOCAL.get()
// will deliver the platform (as this second call is performed by the cms itself)
rcms.createComponent(name, modelname, cinfo, resultlistener).addResultListener(new DelegationResultListener(inited));
}
}));
}
else
{
// System.out.println("create start1: "+model+" "+cinfo.getParent());
if(name!=null && name.indexOf('@')!=-1)
{
inited.setException(new ComponentCreationException("No '@' allowed in component name.", ComponentCreationException.REASON_WRONG_ID));
}
else
{
// getAddresses().addResultListener(createResultListener(new ExceptionDelegationResultListener(inited)
// {
// public void customResultAvailable(final String[] addresses)
// {
// Load the model with fitting factory.
getResourceIdentifier(cinfo).addResultListener(createResultListener(new ExceptionDelegationResultListener(inited)
{
public void customResultAvailable(final IResourceIdentifier rid)
{
// System.out.println("loading: "+modelname+" "+rid);
resolveFilename(modelname, cinfo, rid).addResultListener(createResultListener(new ExceptionDelegationResultListener(inited)
{
public void customResultAvailable(final String model)
{
getComponentFactory(model, cinfo, rid, false, false)
.addResultListener(createResultListener(new ExceptionDelegationResultListener(inited)
{
public void customResultAvailable(final IComponentFactory factory)
{
// System.out.println("load: "+model+" "+rid);
factory.loadModel(model, cinfo.getImports(), rid)
.addResultListener(createResultListener(new ExceptionDelegationResultListener(inited)
{
public void customResultAvailable(final IModelInfo lmodel)
{
if(lmodel.getReport()!=null)
{
inited.setException(new ComponentCreationException("Errors loading model: "+model+"\n"+lmodel.getReport().getErrorText(),
ComponentCreationException.REASON_MODEL_ERROR));
}
else
{
factory.getComponentFeatures(lmodel)
.addResultListener(createResultListener(new ExceptionDelegationResultListener, IComponentIdentifier>(inited)
{
public void customResultAvailable(Collection features)
{
// Create id and adapter.
final BasicComponentIdentifier cid;
// check if system component is located in system tree
Map props = lmodel.getProperties();
IComponentIdentifier pacid = getParentIdentifier(cinfo);
boolean systemcomponent = "system".equals(name) && pacid.getParent()==null;
if(props.containsKey("system") && !"system".equals(name))
{
UnparsedExpression uexp = (UnparsedExpression)props.get("system");
IParsedExpression exp = SJavaParser.parseExpression(uexp, lmodel.getAllImports(), null); // todo: classloader
Boolean bool = (Boolean)exp.getValue(new SimpleValueFetcher()
{
public Object fetchValue(String name)
{
Object ret = null;
if("$config".equals(name) || "$configuration".equals(name))
{
if(cinfo.getConfiguration()!=null)
{
ret = cinfo.getConfiguration();
}
else
{
String[] cs = lmodel.getConfigurationNames();
if(cs!=null && cs.length>0)
{
ret = cs[0];
}
}
}
else if("$model".equals(name))
{
ret = lmodel;
}
return ret;
}
});
if(bool!=null && bool.booleanValue())// || (props.get("system").toString().indexOf("true")!=-1))
{
systemcomponent = true;
// is system component, now check whether parent is ok
// boolean insystem = false;
//
// while(pacid.getParent()!=null && !insystem)
// {
// insystem = pacid.getLocalName().equals("system");
// pacid = pacid.getParent();
// }
//
// if(!insystem)
// {
//// System.out.println("Relocating system component: "+name+" - "+modelname);
// logger.info("Relocating system component: "+name+" - "+modelname);
// ComponentIdentifier npa = new ComponentIdentifier("system", agent.getComponentIdentifier());
// cinfo.setParent(npa);
// }
}
}
// Lock the parent while creating
final String lockkey = SUtil.createUniqueId("lock");
LockEntry kt = lockentries.get(cinfo.getParent());
if(kt==null)
{
kt= new LockEntry(cinfo.getParent());
lockentries.put(cinfo.getParent(), kt);
}
kt.addLocker(lockkey);
inited.addResultListener(createResultListener(new IResultListener()
{
public void resultAvailable(IComponentIdentifier result)
{
LockEntry kt = lockentries.get(cinfo.getParent());
if(kt!=null)
{
kt.removeLocker(lockkey);
if(kt.getLockerCount()==0)
{
lockentries.remove(cinfo.getParent());
}
}
}
public void exceptionOccurred(Exception exception)
{
LockEntry kt = lockentries.get(cinfo.getParent());
if(kt!=null)
{
kt.removeLocker(lockkey);
if(kt.getLockerCount()==0)
{
lockentries.remove(cinfo.getParent());
}
}
}
}));
final IInternalAccess pad = getParentComponent(cinfo);
IExternalAccess parent = pad.getExternalAccess();
pacid = parent.getComponentIdentifier();
String paname = pacid.getName().replace('@', '.');
cid = (BasicComponentIdentifier)generateComponentIdentifier(name!=null? name: lmodel.getName(), paname);//, addresses);
// Defer component services being found from registry
SynchronizedServiceRegistry.getRegistry(access.getInternalAccess()).addExcludedComponent(cid);
Boolean master = cinfo.getMaster()!=null? cinfo.getMaster(): lmodel.getMaster(cinfo.getConfiguration());
Boolean daemon = cinfo.getDaemon()!=null? cinfo.getDaemon(): lmodel.getDaemon(cinfo.getConfiguration());
Boolean autosd = cinfo.getAutoShutdown()!=null? cinfo.getAutoShutdown(): lmodel.getAutoShutdown(cinfo.getConfiguration());
Boolean sync = cinfo.getSynchronous()!=null? cinfo.getSynchronous(): lmodel.getSynchronous(cinfo.getConfiguration());
Boolean persistable = cinfo.getPersistable()!=null? cinfo.getPersistable(): lmodel.getPersistable(cinfo.getConfiguration());
PublishEventLevel moni = cinfo.getMonitoring()!=null? cinfo.getMonitoring(): lmodel.getMonitoring(cinfo.getConfiguration());
// Inherit monitoring from parent if null
if(moni==null && cinfo.getParent()!=null)
{
CMSComponentDescription desc = (CMSComponentDescription)getDescription(cinfo.getParent());
moni = desc.getMonitoring();
}
// Cause cause = new Cause(curcause, cid.getName());
Cause cause = curcause;
// todo: how to do platform init so that clock is always available?
IClockService cs = getClockService0();
final CMSComponentDescription ad = new CMSComponentDescription(cid, lmodel.getType(), master!=null ? master.booleanValue() : false,
daemon!=null ? daemon.booleanValue() : false, autosd!=null ? autosd.booleanValue() : false, sync!=null ? sync.booleanValue() : false,
persistable!=null ? persistable.booleanValue() : false, moni,
lmodel.getFullName(), cinfo.getLocalType(), lmodel.getResourceIdentifier(), cs!=null? cs.getTime(): System.currentTimeMillis(), creator, cause, systemcomponent);
// System.out.println("moni: "+moni+" "+lmodel.getFullName());
// Use first configuration if no config specified.
String config = cinfo.getConfiguration()!=null ? cinfo.getConfiguration()
: lmodel.getConfigurationNames().length>0 ? lmodel.getConfigurationNames()[0] : null;
final IPlatformComponentAccess component = new PlatformComponent();
ComponentCreationInfo cci = new ComponentCreationInfo(lmodel, config, cinfo.getArguments(), ad, cinfo.getProvidedServiceInfos(), cinfo.getRequiredServiceBindings());
component.create(cci, features);
if(resultlistener!=null)
{
IArgumentsResultsFeature af = component.getInternalAccess().getComponentFeature0(IArgumentsResultsFeature.class);
IResultListener>> rl = new IIntermediateResultListener>()
{
public void exceptionOccurred(final Exception exception)
{
// Wait for cleanup finished before posting results
cfs.get(cid).addResultListener(new IResultListener>()
{
public void resultAvailable(java.util.Map result)
{
resultlistener.exceptionOccurred(exception);
}
public void exceptionOccurred(Exception exception)
{
resultlistener.exceptionOccurred(exception);
}
});
}
public void finished()
{
// Wait for cleanup finished before posting results
cfs.get(cid).addResultListener(new IResultListener>()
{
public void resultAvailable(java.util.Map result)
{
Collection> results = new ArrayList>();
for(Map.Entry entry: result.entrySet())
{
results.add(new Tuple2(entry.getKey(), entry.getValue()));
}
resultlistener.resultAvailable(results);
}
public void exceptionOccurred(Exception exception)
{
resultlistener.exceptionOccurred(exception);
}
});
}
public void intermediateResultAvailable(Tuple2 result)
{
if(resultlistener instanceof IIntermediateResultListener)
{
((IIntermediateResultListener)resultlistener).intermediateResultAvailable(result);
}
}
public void resultAvailable(Collection> result)
{
// shouldn't happen...
Thread.dumpStack();
}
};
if(af!=null)
{
af.subscribeToResults().addResultListener(rl);
}
}
putInitInfo(cid, new InitInfo(component, cinfo, resfut));
// Start regular execution of inited component
// when this component is the outermost component, i.e. with no parent
// or the parent is already running
final boolean doinit = cinfo.getParent()==null || getInitInfo(cinfo.getParent())==null;
logger.info("Starting component: "+cid.getName());
// System.err.println("Pre-Init: "+cid);
resfut.addResultListener(createResultListener(new IResultListener()
{
public void resultAvailable(Void result)
{
logger.info("Started component: "+cid.getName());
SynchronizedServiceRegistry.getRegistry(access.getInternalAccess()).removeExcludedComponent(cid);
// System.out.println("created: "+ad);
// Init successfully finished. Add description and adapter.
InitInfo info = getInitInfo(cid);
// Init finished. Set to suspended until parent registration is finished.
// not set to suspend to allow other initing sibling components invoking services
// ad.setState(IComponentDescription.STATE_SUSPENDED);
// System.out.println("adding cid: "+cid);
components.put(cid, info.getComponent());
// Removed in resumeComponent()
// initinfos.remove(cid);
// Register component at parent.
addSubcomponent(pad, ad, lmodel)
.addResultListener(createResultListener(new IResultListener()
{
public void resultAvailable(Void result)
{
// System.err.println("Registered at parent: "+cid);
// Registration finished -> reactivate component.
// // Note: Must be set to suspended because otherwise
// any call to wakeup would immediately start executing the component.
// if(isInitSuspend(cinfo, lmodel))
// {
// not set to suspend to allow other initing sibling components invoking services
// ad.setState(CMSComponentDescription.STATE_SUSPENDED);
// }
// else
// {
// ad.setState(CMSComponentDescription.STATE_ACTIVE);
// }
// todo: can be called after listener has (concurrently) deregistered
// notify listeners without holding locks
notifyListenersAdded(cid, ad);
// System.out.println("created: "+cid.getLocalName());//+" "+(parent!=null?parent.getComponentIdentifier().getLocalName():"null"));
// System.out.println("added: "+descs.size()+", "+aid);
// if(modelname.indexOf("jadex.platform.service.message.transport.ssltcpmtp.ProviderAgent")!=-1)
// System.out.println("inited, return: "+cid);//+" "+info!=null? info.getResourceIdentifier(): "norid");
inited.setResult(cid);
Future> killfut;
killfut = (Future>)cfs.get(cid);
if(killfut!=null)
{
// Remove init infos otherwise done in resume()
List cids = new ArrayList();
cids.add(cid);
for(int i=0; i complete init, so parent can terminate.
if(exception instanceof ComponentTerminatedException)
{
notifyListenersAdded(cid, ad);
inited.setResult(cid);
}
else
{
logger.info("Starting component failed: "+cid+", "+exception);
}
}
}));
}
public void exceptionOccurred(final Exception exception)
{
logger.info("Starting component failed: "+cid+", "+exception);
ServiceRegistry.getRegistry(access.getInternalAccess()).removeExcludedComponent(cid);
// System.err.println("Starting component failed: "+cid+", "+exception);
// exception.printStackTrace();
// System.out.println("Ex: "+cid+" "+exception);
final Runnable cleanup = new Runnable()
{
public void run()
{
IPlatformComponentAccess comp = components.get(cid);
if(comp==null)
{
InitInfo ii = getInitInfo(cid);
assert ii!=null: "Should be either in 'components' or 'initinfos'.";
comp = ii.getComponent();
}
comp.getInternalAccess().getExternalAccess().killComponent(exception)
.addResultListener(new ExceptionDelegationResultListener, IComponentIdentifier>(inited)
{
@Override
public void customResultAvailable(Map result)
{
// Shouldn't happen.
Thread.dumpStack();
}
});
// new IResultListener>()
// {
//
// @Override
// public void exceptionOccurred(Exception exception)
// {
// components.remove(cid);
// removeInitInfo(cid);
//
// if(resultlistener!=null)
// {
// resultlistener.exceptionOccurred(exception);
// }
//
// inited.setException(exception);
// }
// });
// exitDestroy(cid, ad, exception, null);
}
};
IComponentIdentifier[] children = ad.getChildren();
if(children.length>0)
{
CounterResultListener> crl = new CounterResultListener>(children.length, true,
createResultListener(new IResultListener()
{
public void resultAvailable(Void result)
{
cleanup.run();
}
public void exceptionOccurred(Exception exception)
{
cleanup.run();
}
}
));
for(int i=0; i(resfut)));
}
}));
}
}
}));
}
}));
}
}));
}
}));
// }
// }));
}
}
return inited;
}
/**
* Find the file name and local component type name
* for a component to be started.
*/
protected IFuture resolveFilename(final String modelname, final CreationInfo cinfo, final IResourceIdentifier rid)
{
final Future ret = new Future();
try
{
// Hack for platform init
ILibraryService libservice = SServiceProvider.getLocalService(agent, ILibraryService.class, RequiredServiceInfo.SCOPE_PLATFORM);
libservice.getClassLoader(rid).addResultListener(createResultListener(new ExceptionDelegationResultListener(ret)
{
public void customResultAvailable(ClassLoader cl)
{
String filename = modelname;
if(cinfo.getParent()!=null)
{
// Try to find file for local type.
String localtype = modelname!=null ? modelname : cinfo.getLocalType();
filename = null;
IInternalAccess pad = getParentComponent(cinfo);
IExternalAccess parent = pad.getExternalAccess();
final SubcomponentTypeInfo[] subcomps = parent.getModel().getSubcomponentTypes();
for(int i=0; filename==null && i0)
{
Tuple key = new Tuple(parent.getModel().getFullName(), filename);
if(localtypes.containsKey(key))
{
cinfo.setLocalType((String)localtypes.get(key));
}
else
{
ResourceInfo info = SUtil.getResourceInfo0(filename, cl);
if(info!=null)
{
for(int i=0; cinfo.getLocalType()==null && i getComponentFactory(final String model, final CreationInfo cinfo, final IResourceIdentifier rid, final boolean searched, final boolean cachemiss)
{
final Future ret = new Future();
// Search, if no cache available or not found in cache
if((factories==null || cachemiss) && !searched)
{
// System.out.println("searching factories");
IFuture> fut = SServiceProvider.getServices(agent, IComponentFactory.class, RequiredServiceInfo.SCOPE_PLATFORM);
fut.addResultListener(createResultListener(new ExceptionDelegationResultListener, IComponentFactory>(ret)
{
public void customResultAvailable(Collection facts)
{
if(!facts.isEmpty())
{
// Reorder factories to assure that delegating multi loaders are last (if present).
if(facts.size()>1)
{
List singles = new ArrayList();
List multies = new ArrayList();
for(IComponentFactory fac: facts)
{
if(fac.toString().toLowerCase().indexOf("multi")!=-1)
{
multies.add(fac);
}
else
{
singles.add(fac);
// Remove fallback factory when first real factory is found.
componentfactory = null;
}
}
facts = singles;
facts.addAll(multies);
}
}
factories = facts.isEmpty() ? null : facts;
// Invoke again, now with up-to-date cache.
getComponentFactory(model, cinfo, rid, true, false).addResultListener(new DelegationResultListener(ret));
}
}));
}
// Cache available or recently searched.
else
{
// System.out.println("create start2: "+model+" "+cinfo.getParent());
selectComponentFactory(factories==null? null: factories.iterator(), model, cinfo, rid)
.addResultListener(createResultListener(new DelegationResultListener(ret)
{
public void exceptionOccurred(Exception exception)
{
// Todo: sometimes nullpointerexception is caused below (because agent is null???).
if(!(exception instanceof ComponentCreationException))
{
System.out.println("factory ex: "+exception+", "+agent);
}
// If not found in cache but not yet searched, invoke again to start fresh search due to cache miss.
if(!searched)
{
getComponentFactory(model, cinfo, rid, false, true)
.addResultListener(createResultListener(new DelegationResultListener(ret)));
}
// Otherwise give up.
else
{
super.exceptionOccurred(exception);
}
}
}));
}
return ret;
}
/**
* Selects a component factory from a collection of factories.
* Uses the isLoadable factory method to determine if the
* model can be loaded.
* @param factories The collection of factories.
* @param model The model file name.
* @param cinfo The creation info.
* @param cl The classloader.
* @return The component factory.
*/
protected IFuture selectComponentFactory(final Iterator factories,
final String model, final CreationInfo cinfo, final IResourceIdentifier rid)
{
// System.out.println("select factory: "+model+", "+SUtil.arrayToString(factories));
// if(model.indexOf("boken")!=-1)
// System.out.println("sdfsdf");
final Future ret = new Future();
if(factories!=null && factories.hasNext())
{
final IComponentFactory factory = factories.next();
factory.isLoadable(model, cinfo.getImports(), rid)
.addResultListener(createResultListener(new ExceptionDelegationResultListener(ret)
{
public void customResultAvailable(Boolean res)
{
if(res.booleanValue())
{
// If multi factory, clear cache and invoke again to obtain real factory.
if(factory.toString().toLowerCase().indexOf("multi")!=-1)
{
ComponentManagementService.this.factories = null;
getComponentFactory(model, cinfo, rid, false, false)
.addResultListener(new DelegationResultListener(ret));
}
else
{
ret.setResult(factory);
}
}
else if(factories.hasNext())
{
selectComponentFactory(factories, model, cinfo, rid)
.addResultListener(new DelegationResultListener(ret));
}
else
{
selectFallbackFactory(model, cinfo, rid).addResultListener(createResultListener(new DelegationResultListener(ret)));
}
}
}));
}
else
{
selectFallbackFactory(model, cinfo, rid).addResultListener(createResultListener(new DelegationResultListener(ret)));
}
return ret;
}
/**
* Select the fallback factory.
*/
protected IFuture selectFallbackFactory(final String model, final CreationInfo cinfo, final IResourceIdentifier rid)
{
// System.out.println("fallback: "+model);
final Future ret = new Future();
if(componentfactory!=null)
{
componentfactory.isLoadable(model, cinfo.getImports(), rid)
.addResultListener(createResultListener(new ExceptionDelegationResultListener(ret)
{
public void customResultAvailable(Boolean res)
{
if(res.booleanValue())
{
ret.setResult(componentfactory);
}
else
{
ret.setException(new ComponentCreationException("No factory found for: "+model, ComponentCreationException.REASON_NO_COMPONENT_FACTORY));
}
}
}));
}
else
{
ret.setException(new ComponentCreationException("No factory found for: "+model, ComponentCreationException.REASON_NO_COMPONENT_FACTORY));
}
return ret;
}
/**
* Get the info of the parent component.
*/
protected InitInfo getParentInfo(CreationInfo cinfo)
{
final IComponentIdentifier paid = getParentIdentifier(cinfo);
return getInitInfo(paid);
}
/**
* Get the parent component.
*/
protected IInternalAccess getParentComponent(CreationInfo cinfo)
{
final IComponentIdentifier paid = getParentIdentifier(cinfo);
IPlatformComponentAccess component = components.get(paid);
if(component==null)
{
InitInfo pinfo = getParentInfo(cinfo);
// Hack!!! happens when parent is killed while trying to create subcomponent (todo: integrate locking for destroy and create of component structure)
if(pinfo==null)
{
throw new ComponentTerminatedException(paid);
}
component = pinfo.getComponent();
}
return component.getInternalAccess();
}
// /**
// * Get the desc of the parent component.
// */
// protected CMSComponentDescription getParentDescription(CreationInfo cinfo)
// {
// final IComponentIdentifier paid = getParentIdentifier(cinfo);
// CMSComponentDescription desc = adapters.containsKey(paid)
// ? (CMSComponentDescription)((IComponentAdapter)adapters.get(paid)).getDescription()
// : (CMSComponentDescription)getParentInfo(cinfo).getDescription();
// return desc;
// }
/**
* Test if a component identifier is a remote component.
*/
protected boolean isRemoteComponent(IComponentIdentifier cid)
{
return !cid.getPlatformName().equals(agent.getComponentIdentifier().getName());
}
/**
* Destroy (forcefully terminate) an component on the platform.
* @param cid The component to destroy.
*/
public IFuture> destroyComponent(final IComponentIdentifier cid)
{
// if(cid.getParent()==null)
// System.out.println("---- !!!! ----- Killing platform ---- !!!! ----- "+cid.getName());
// System.out.println("Terminating component: "+cid.getName());
// ServiceCall sc = ServiceCall.getCurrentInvocation();
// System.out.println("kill compo: "+cid);//+" "+(sc!=null? sc.getCaller(): "null"));
// if(cid.toString().indexOf("MegaParallel")!=-1)
// System.out.println("destroy: "+cid.getName());
// else if(getDescription(cid)==null)
// System.out.println("destroy: null");
// if(cid.getParent()==null)
// {
// System.out.println("Platform kill called:_"+cid.getName());
// Thread.dumpStack();
// }
boolean contains = false;
boolean locked = false;
Future> tmp;
contains = cfs.containsKey(cid);
tmp = contains? (Future>)cfs.get(cid): new Future>();
// System.out.println("destroy0: "+cid+" "+cfs.containsKey(cid)+" "+tmp.isDone());
// Thread.currentThread().dumpStack();
// If destroyComponent has not been called before
if(!contains)
{
cfs.put(cid, tmp);
// if(cid.getParent()==null)
// {
// tmp.addResultListener(new IResultListener>()
// {
// public void resultAvailable(Map result)
// {
// System.out.println("res: "+result);
// }
//
// public void exceptionOccurred(Exception exception)
// {
// System.out.println("ex: "+exception);
// }
// });
// }
// ((CMSComponentDescription)getDescription(cid)).setState(IComponentDescription.STATE_TERMINATING);
}
// Is the component locked?
LockEntry kt = lockentries.get(cid);
if(kt!=null && kt.getLockerCount()>0)
{
kt.setKillFuture(tmp);
locked = true;
}
final Future> ret = tmp;
if(!contains && !locked)
{
destroyComponent(cid, ret);
}
// else //if("Application".equals(getDescription(cid).getType()))
// System.out.println("no destroy: "+contains+", "+locked);
// if(cid.getParent()==null)
// {
// ret.addResultListener(new IResultListener>()
// {
// public void resultAvailable(Map result)
// {
// System.out.println("kill platorm finished: "+cid.getName());
// }
//
// public void exceptionOccurred(Exception exception)
// {
// System.out.println("kill platform exception: "+cid.getName()+" "+exception);
// }
// });
// }
return ret;
}
/**
* Internal destroy method that performs the actual work.
* @param cid The component to destroy.
* @param ret The future to be informed.
*/
protected void destroyComponent(final IComponentIdentifier cid, final Future> ret)
{
// System.out.println("kill: "+cid);
if(isRemoteComponent(cid))
{
getRemoteCMS(cid).addResultListener(new ExceptionDelegationResultListener>(ret)
{
public void customResultAvailable(IComponentManagementService rcms)
{
// final IComponentManagementService rcms = (IComponentManagementService)result;
rcms.destroyComponent(cid).addResultListener(new DelegationResultListener>(ret));
}
});
}
else
{
InitInfo infos = getInitInfo(cid);
// IComponentAdapter adapter = infos!=null ? infos.getAdapter() : (IComponentAdapter)adapters.get(cid);
IPlatformComponentAccess comp = infos!=null ? infos.getComponent() : components.get(cid);
// if(adapter!=null && adapter.getDescription().getModelName().indexOf("Pool")==-1)
// System.out.println("Terminating component: "+cid.getName());
// Terminate component that is shut down during init.
// todo:
if(infos!=null && !infos.getInitFuture().isDone())
{
// Propagate failed component init.
// if(comp!=null && comp.getException()!=null)
// {
// infos.getInitFuture().setException(adapter.getException());
// }
// Component terminated from outside: wait for init to complete, will be removed as cleanup future is registered (cfs).
// else
{
// if(cid.toString().indexOf("Mandelbrot")!=-1)
// System.out.println("Queued component termination during init: "+cid.getName());
logger.info("Queued component termination during init: "+cid.getName());
}
}
// Terminate normally inited component.
else if(comp!=null)
{
// Kill subcomponents
logger.info("Terminating component structure: "+cid.getName());
final CMSComponentDescription desc = (CMSComponentDescription)((PlatformComponent)comp).getComponentDescription();
final IComponentIdentifier[] achildren = desc.getChildren();
// if(achildren.length>0)
// System.out.println("kill childs start: "+cid+" "+achildren.length+" "+SUtil.arrayToString(achildren));
destroyComponentLoop(cid, achildren, achildren.length-1).addResultListener(createResultListener(new IResultListener>()
{
public void resultAvailable(List result)
{
// if(achildren.length>0)
// System.out.println("kill childs end: "+cid);
// if(cid.toString().startsWith("Initiator"))
// System.out.println("Terminated component structure: "+cid.getName());
logger.info("Terminated component structure: "+cid.getName());
CleanupCommand cc = null;
IFuture fut = null;
// Fetch comp again as component may be already killed (e.g. when autoshutdown).
InitInfo infos = getInitInfo(cid);
IPlatformComponentAccess comp = infos!=null ? infos.getComponent() : components.get(cid);
if(comp!=null)
{
// if(cid.toString().indexOf("AutoTerminate")!=-1)
// System.out.println("destroy1: "+cid.getName());
//
// todo: does not work always!!! A search could be issued before components had enough time to kill itself!
// todo: killcomponent should only be called once for each component?
if(!ccs.containsKey(cid))
{
// if(cid.toString().indexOf("AutoTerminate")!=-1)
// System.out.println("killing a: "+cid);
cc = new CleanupCommand(cid);
ccs.put(cid, cc);
logger.info("Terminating component: "+cid.getName());
fut = comp.shutdown();
}
else
{
// if(cid.toString().indexOf("AutoTerminate")!=-1)
// System.out.println("killing b: "+cid);
cc = (CleanupCommand)ccs.get(cid);
}
}
// Add listener outside synchronized block to avoid deadlocks
if(fut!=null && cc!=null)
{
// Cannot use invoke later during platform shutdown
IResultListener lis = cid.getParent()==null? cc: createResultListener(cc);
fut.addResultListener(lis);
}
if(cc==null)
{
// Todo: what is this case?
exitDestroy(cid, desc, new RuntimeException("No cleanup command for component "+cid+": "+desc.getState()), null);
}
else
{
// Resume component to be killed in case it is currently suspended.
resumeComponent(cid);
}
}
public void exceptionOccurred(Exception exception)
{
// System.out.println("ex: "+exception);
exitDestroy(cid, desc, exception, null);
}
}));
}
else
{
cfs.remove(cid);
ret.setException(new ComponentTerminatedException(cid, "Cannot kill, no such component."));
}
}
}
/**
* Exit the destroy method by setting description state and resetting maps.
* @return True, when somebody was notified.
*/
protected void exitDestroy(IComponentIdentifier cid, IComponentDescription desc, Exception ex, Map results)
{
// Thread.dumpStack();
Future> ret;
ccs.remove(cid);
ret = (Future>)cfs.remove(cid);
if(desc instanceof CMSComponentDescription)
{
((CMSComponentDescription)desc).setState(IComponentDescription.STATE_TERMINATED);
}
if(ret!=null)
{
if(ex!=null)
{
ret.setExceptionIfUndone(ex);
}
else
{
ret.setResultIfUndone(results);
}
}
}
/**
* Loop for destroying subcomponents.
*/
protected IFuture> destroyComponentLoop(final IComponentIdentifier cid, final IComponentIdentifier[] achildren, final int i)
{
final Future> ret = new Future>();
// System.out.println("destroy loop: "+cid+" "+i+"/"+achildren.length);
if(achildren.length>0)
{
final List exceptions = new ArrayList();
destroyComponent(achildren[i]).addResultListener(createResultListener(new IResultListener>()
{
public void resultAvailable(Map result)
{
if(i>0)
{
destroyComponentLoop(cid, achildren, i-1).addResultListener(
createResultListener(new DelegationResultListener>(ret)));
}
else
{
ret.setResult(exceptions);
}
}
public void exceptionOccurred(Exception exception)
{
exceptions.add(exception);
resultAvailable(null);
// ret.setException(exception);
}
}));
}
else
{
ret.setResult(null);
}
return ret;
}
/**
* Suspend the execution of an component.
* @param cid The component identifier.
*/
public IFuture suspendComponent(final IComponentIdentifier cid)
{
IFuture ret;
if(isRemoteComponent(cid))
{
final Future fut = new Future();
ret = fut;
getRemoteCMS(cid).addResultListener(createResultListener(
new ExceptionDelegationResultListener(fut)
{
public void customResultAvailable(IComponentManagementService rcms)
{
rcms.suspendComponent(cid).addResultListener(createResultListener(new DelegationResultListener(fut)));
}
}));
return ret;
}
else
{
final IPlatformComponentAccess comp = components.get(cid);
if(comp!=null)
{
CMSComponentDescription desc = (CMSComponentDescription)((PlatformComponent)comp).getComponentDescription();
if(IComponentDescription.STATE_ACTIVE.equals(desc.getState()))
{
// Suspend subcomponents
IComponentIdentifier[] achildren = desc.getChildren();
for(int i=0; i(new IllegalStateException("Component not active: "+cid));
}
}
else
{
ret = new Future(new ComponentNotFoundException("Component identifier not registered: "+cid));
}
}
return ret;
}
/**
* Resume the execution of an component.
* @param componentid The component identifier.
*/
public IFuture resumeComponent(IComponentIdentifier cid)
{
return resumeComponent(cid, false);
}
/**
* Resume the execution of an component.
* @param componentid The component identifier.
*/
public IFuture resumeComponent(final IComponentIdentifier cid, final boolean initresume)
{
final Future ret = new Future();
if(isRemoteComponent(cid))
{
assert !initresume;
getRemoteCMS(cid).addResultListener(createResultListener(new ExceptionDelegationResultListener(ret)
{
public void customResultAvailable(IComponentManagementService rcms)
{
rcms.resumeComponent(cid).addResultListener(createResultListener(new DelegationResultListener(ret)));
}
}));
}
else
{
// Resume subcomponents
final CMSComponentDescription desc = (CMSComponentDescription)getDescription(cid);
IComponentIdentifier[] achildren = desc!=null ? desc.getChildren() : null;
if(desc!=null)
{
IResultListener lis = createResultListener(new CounterResultListener(achildren.length, true, new DefaultResultListener()
{
public void resultAvailable(Void result)
{
final IPlatformComponentAccess adapter = components.get(cid);
boolean changed = false;
if(adapter==null && !initresume) // Might be killed after init but before init resume
{
ret.setException(new ComponentNotFoundException("Component identifier not registered: "+cid));
}
else if(adapter!=null)
{
// Hack for startup.
if(initresume)
{
// Not killed during init.
if(!cfs.containsKey(cid))
{
InitInfo ii = removeInitInfo(cid);
// System.out.println("removed: "+cid+" "+ii);
if(ii!=null)
{
boolean suspend = isInitSuspend(ii.getInfo(), adapter.getInternalAccess().getModel());
if(suspend)
{
desc.setState(IComponentDescription.STATE_SUSPENDED);
changed = true;
}
}
adapter.body().addResultListener(adapter.getInternalAccess().getComponentFeature(IExecutionFeature.class).createResultListener(new IResultListener()
{
public void resultAvailable(Void result)
{
// Nop. keepalive is handled by component internally
}
public void exceptionOccurred(Exception exception)
{
if(!(exception instanceof ComponentTerminatedException)
|| !((ComponentTerminatedException)exception).getComponentIdentifier().equals(adapter.getInternalAccess().getComponentIdentifier()))
{
adapter.getInternalAccess().killComponent(exception);
}
}
}));
}
// Killed after init but before init resume -> execute queued destroy.
else if(getInitInfo(cid)!=null)
{
removeInitInfo(cid);
cfs.remove(cid);
}
}
else
{
boolean wakeup = false;
if(IComponentDescription.STATE_SUSPENDED.equals(desc.getState()))
{
wakeup = true;
desc.setState(IComponentDescription.STATE_ACTIVE);
changed = true;
}
if(wakeup)
{
((IInternalExecutionFeature)adapter.getInternalAccess().getComponentFeature(IExecutionFeature.class)).wakeup();
}
}
if(changed)
notifyListenersChanged(cid, desc);
ret.setResult(null);
}
}
}));
for(int i=0; i addSubcomponent(IInternalAccess pad, IComponentDescription ad, IModelInfo lmodel)
{
CMSComponentDescription padesc = (CMSComponentDescription)pad.getComponentDescription();
padesc.addChild(ad.getName());
// if(padesc.isAutoShutdown() && !ad.isDaemon())
// if(pas!=null && pas.booleanValue() && (dae==null || !dae.booleanValue()))
// cannot check parent shutdown state because could be still uninited
if(!ad.isDaemon())
{
Integer childcount = (Integer)childcounts.get(padesc.getName());
int cc = childcount!=null ? childcount.intValue()+1 : 1;
childcounts.put(padesc.getName(), Integer.valueOf(cc));
}
// Register component at parent.
return ((IInternalSubcomponentsFeature)pad.getComponentFeature(ISubcomponentsFeature.class)).componentCreated(ad);//, lmodel);
}
/**
* Execute a step of a suspended component.
* @param componentid The component identifier.
*/
public IFuture stepComponent(final IComponentIdentifier cid, final String stepinfo)
{
final Future ret = new Future();
if(isRemoteComponent(cid))
{
getRemoteCMS(cid).addResultListener(createResultListener(new ExceptionDelegationResultListener(ret)
{
public void customResultAvailable(IComponentManagementService rcms)
{
rcms.stepComponent(cid, stepinfo).addResultListener(createResultListener(new DelegationResultListener(ret)));
}
}));
}
else
{
final PlatformComponent adapter = (PlatformComponent)components.get(cid);
if(adapter!=null)
{
// if(stepinfo!=null)
// {
// CMSComponentDescription desc = (CMSComponentDescription)getDescription(cid);
// if(desc!=null)
// {
// desc.setStepInfo(stepinfo);
// }
// }
((IInternalExecutionFeature)adapter.getComponentFeature(IExecutionFeature.class)).doStep(stepinfo)
.addResultListener(agent.getComponentFeature(IExecutionFeature.class).createResultListener(new DelegationResultListener(ret)));
}
else
{
ret.setException(new ComponentNotFoundException("Component identifier not registered: "+cid));
}
}
return ret;
}
/**
* Set breakpoints for a component.
* Replaces existing breakpoints.
* To add/remove breakpoints, use current breakpoints from component description as a base.
* @param cid The component identifier.
* @param breakpoints The new breakpoints (if any).
*/
public IFuture setComponentBreakpoints(final IComponentIdentifier cid, final String[] breakpoints)
{
final Future ret = new Future();
if(isRemoteComponent(cid))
{
getRemoteCMS(cid).addResultListener(createResultListener(new ExceptionDelegationResultListener(ret)
{
public void customResultAvailable(IComponentManagementService rcms)
{
rcms.setComponentBreakpoints(cid, breakpoints).addResultListener(
createResultListener(new DelegationResultListener(ret)));
}
}));
}
else
{
CMSComponentDescription ad = (CMSComponentDescription)getDescription(cid);
ad.setBreakpoints(breakpoints);
notifyListenersChanged(cid, ad);
ret.setResult(null);
}
return ret;
}
//-------- listener methods --------
/**
* Add an component listener.
* The listener is registered for component changes.
* @param comp The component to be listened on (or null for listening on all components).
* @param listener The listener to be added.
*/
public IFuture addComponentListener(IComponentIdentifier comp, ICMSComponentListener listener)
{
listeners.add(comp, listener);
return IFuture.DONE;
}
/**
* Remove a listener.
* @param comp The component to be listened on (or null for listening on all components).
* @param listener The listener to be removed.
*/
public IFuture removeComponentListener(IComponentIdentifier comp, ICMSComponentListener listener)
{
listeners.removeObject(comp, listener);
return IFuture.DONE;
}
//-------- helper classes --------
/**
* Command that is executed on component cleanup.
*/
class CleanupCommand implements IResultListener
{
protected IComponentIdentifier cid;
public CleanupCommand(IComponentIdentifier cid)
{
// System.out.println("CleanupCommand created");
this.cid = cid;
}
public void resultAvailable(Void result)
{
doCleanup(null);
}
public void exceptionOccurred(Exception exception)
{
doCleanup(exception);
}
protected void doCleanup(Exception exception)
{
// try
// {
boolean killparent = false;
// IComponentAdapter adapter = null;
// IComponentAdapter pad = null;
CMSComponentDescription desc;
Map results = null;
logger.info("Terminated component: "+cid.getName());
// if(cid.getParent()==null)
// System.out.println("CleanupCommand: "+cid);
// boolean shutdown = false;
// System.out.println("CleanupCommand remove called for: "+cid);
IPlatformComponentAccess comp = components.remove(cid);
if(comp==null)
{
InitInfo ii = removeInitInfo(cid);
assert ii!=null: "Should be either in 'components' or 'initinfos'.";
comp = ii.getComponent();
}
PlatformComponent pad = null;
if(comp==null)
throw new ComponentNotFoundException("Component Identifier not registered: "+cid);
// if(cid.getName().indexOf("Peer")==-1)
// System.out.println("removed adapter: "+adapter.getComponentIdentifier().getLocalName()+" "+cid+" "+adapters);
desc = (CMSComponentDescription)comp.getInternalAccess().getComponentDescription();
IArgumentsResultsFeature af = comp.getInternalAccess().getComponentFeature0(IArgumentsResultsFeature.class);
results = af!=null ? af.getResults() : null;
// desc.setState(IComponentDescription.STATE_TERMINATED);
// ccs.remove(cid);
// cfs.remove(cid);
// Deregister destroyed component at parent.
if(desc.getName().getParent()!=null)
{
// Stop execution of component. When root component services are already shutdowned.
// cancel(comp);
// exeservice.cancel(adapter);
killparent = desc.isMaster();
CMSComponentDescription padesc = (CMSComponentDescription)getDescription(desc.getName().getParent());
if(padesc!=null)
{
padesc.removeChild(desc.getName());
// if(pas!=null && pas.booleanValue() && (dae==null || !dae.booleanValue()))
if(!desc.isDaemon())
// if(padesc.isAutoShutdown() && !desc.isDaemon())
{
Integer childcount = (Integer)childcounts.get(padesc.getName());
// assert childcount!=null && childcount.intValue()>0;
if(childcount!=null)
{
int cc = childcount.intValue()-1;
if(cc>0)
childcounts.put(padesc.getName(), Integer.valueOf(cc));
else
childcounts.remove(padesc.getName());
// System.out.println("childcount-: "+padesc.getName()+" "+cc);
}
// todo: could fail when parent is still in init phase.
// Should test for init phase and remember that it has to be killed.
killparent = killparent || (padesc.isAutoShutdown()
&& (childcount==null || childcount.intValue()<=1));
}
}
pad = (PlatformComponent)components.get(desc.getName().getParent());
// todo: wait for result?!
if(pad!=null)
((IInternalSubcomponentsFeature)pad.getComponentFeature(ISubcomponentsFeature.class)).componentRemoved(desc);
}
// Must be executed out of sync block due to deadlocks
// agent->cleanupcommand->space.componentRemoved (holds adapter mon -> needs space mone)
// space executor->general loop->distributed percepts->(holds space mon -> needs adapter mon for getting external access)
// todo:
// if(pad!=null)
// {
// try
// {
// pad.componentDestroyed(desc);
// }
// catch(ComponentTerminatedException cte)
// {
// // Parent just killed: ignore.
// }
// }
// else parent has just been killed.
// Use adapter exception before cleanup exception as it probably happened first.
Exception ex = comp.getInternalAccess().getException()!=null ? comp.getInternalAccess().getException() : exception;
exitDestroy(cid, desc, ex, results);
notifyListenersRemoved(cid, desc, results);
if(ex!=null)
{
// Unhandled component exception
if(af!=null && ((IInternalArgumentsResultsFeature)af).hasListener())
{
// Delegated exception to some listener, only print info.
comp.getInternalAccess().getLogger().info("Fatal error, component '"+cid+"' will be removed due to "+ex);
}
else
{
// No listener -> print exception.
comp.getInternalAccess().getLogger().severe("Fatal error, component '"+cid+"' will be removed.\n"+SUtil.getExceptionStacktrace(ex));
}
}
// System.out.println("CleanupCommand end.");
// Terminate rescue threads when platform is killed (hack, starter should use kill listener, but listener isn't registered in cms)
if(cid.getParent()==null)
{
// In case of stack compaction it has to be ensured that listeners are
// notified before the rescue thread is terminated
FutureHelper.notifyStackedListeners();
Starter.shutdownRescueThread(cid);
}
// Kill parent is autoshutdown or child was master.
else if(pad!=null && killparent)
{
// System.out.println("killparent: "+pad.getComponentIdentifier());
destroyComponent(pad.getComponentIdentifier());
}
if(cid.getRoot().equals(cid))
{
// System.out.println("removed: "+cid);
PlatformConfiguration.removePlatformMemory(cid);
}
// }
// catch(Throwable t)
// {
// t.printStackTrace();
// }
}
}
//-------- internal methods --------
/**
* Get the external access of a component.
* @param cid The component identifier.
* @param listener The result listener.
*/
public IFuture getExternalAccess(final IComponentIdentifier cid)
{
return getExternalAccess(cid, false);
}
/**
* Get the external access of a component.
* @param cid The component identifier.
* @param listener The result listener.
*/
protected IFuture getExternalAccess(final IComponentIdentifier cid, boolean internal)
{
// System.out.println("getExta: "+cid);
final Future ret = new Future();
// ret.addResultListener(new IResultListener()
// {
// public void resultAvailable(IExternalAccess result)
// {
// if(result==null)
// {
// System.err.println("ea is null in cms!!! "+cid);
// }
// }
//
// public void exceptionOccurred(Exception exception)
// {
// }
// });
if(cid==null)
{
ret.setException(new IllegalArgumentException("Identifier is null."));
return ret;
}
if(isRemoteComponent(cid))
{
// System.out.println("getExternalAccess: remote");
agent.getComponentFeature(IRequiredServicesFeature.class).searchService(IRemoteServiceManagementService.class, RequiredServiceInfo.SCOPE_PLATFORM)
.addResultListener(new ExceptionDelegationResultListener(ret)
{
public void customResultAvailable(IRemoteServiceManagementService rms)
{
rms.getExternalAccessProxy(cid).addResultListener(new DelegationResultListener(ret));
}
});
// getRemoteCMS(cid).addResultListener(new ExceptionDelegationResultListener(ret)
// {
// public void customResultAvailable(IComponentManagementService rcms)
// {
// rcms.getExternalAccess(cid).addResultListener(new DelegationResultListener(ret));
// }
// });
}
else
{
// System.out.println("getExternalAccess: local");
IPlatformComponentAccess component = null;
// System.out.println("getExternalAccess: adapters");
boolean delayed = false;
component = components.get(cid);
if(component==null)
{
// Hack? Allows components to getExternalAccess in init phase from parent but also from component itself
InitInfo ii = getInitInfo(cid);
if(ii!=null)
{
// if(!internal && (ii.getAdapter()==null || ii.getAdapter().isExternalThread())) // cannot work because of decoupling
IComponentIdentifier caller = ServiceCall.getCurrentInvocation()!=null ? ServiceCall.getCurrentInvocation().getCaller() : null;
if(internal || (caller!=null && (cid.equals(caller.getParent()) || cid.equals(caller))))
{
// System.out.println("getExternalAccess: not delayed");
component = ii.getComponent();
}
else
{
// System.out.println("getExternalAccess: delayed");
delayed = true;
IFuture fut = ii.getInitFuture();
fut.addResultListener(createResultListener(new ExceptionDelegationResultListener(ret)
{
public void customResultAvailable(Void result)
{
try
{
ret.setResult(components.get(cid).getInternalAccess().getExternalAccess());
}
catch(Exception e)
{
ret.setException(e);
}
}
}));
}
}
}
if(component!=null)
{
try
{
ret.setResult(component.getInternalAccess().getExternalAccess());
}
catch(Exception e)
{
ret.setException(e);
}
}
else if(!delayed)
{
ret.setException(new ComponentNotFoundException("No local component found for component identifier: "+cid));
}
}
ret.addResultListener(new IResultListener()
{
public void resultAvailable(IExternalAccess result)
{
}
public void exceptionOccurred(Exception exception)
{
if(cid.getName().toLowerCase().indexOf("directservice")!=-1
|| cid.getName().toLowerCase().indexOf("rawservice")!=-1
|| cid.getName().toLowerCase().indexOf("decoupledservice")!=-1)
{
System.out.println("getExternalAccess: "+agent.getComponentIdentifier()+", "+cid);
// getExternalAccess(cid);
}
}
});
return ret;
}
/**
* Find the class loader for a new (local) component.
* Use parent component class loader for local parents
* and current platform class loader for remote or no parents.
* @param cid The component id.
* @return The class loader.
*/
protected IFuture getResourceIdentifier(final CreationInfo ci)
{
final Future ret = new Future();
// User supplied resource identifier.
if(ci!=null && ci.getResourceIdentifier()!=null)
{
ret.setResult(ci.getResourceIdentifier());
}
// Local parent //(but not platform -> platform now has valid rid).
else if(ci!=null
// && !ci.getParent().equals(root.getComponentIdentifier())
&& (ci.getParent()==null || !isRemoteComponent(ci.getParent()))
// && !initinfos.containsKey(ci.getParent()) // does not work during init as external access is not available!?
// && !Boolean.TRUE.equals(ci.getPlatformloader()))
)
{
getExternalAccess(ci.getParent()==null? agent.getComponentIdentifier(): ci.getParent(), true)
.addResultListener(createResultListener(new ExceptionDelegationResultListener(ret)
{
public void customResultAvailable(IExternalAccess ea)
{
// System.err.println("Model class loader: "+ea.getModel().getName()+", "+ea.getModel().getClassLoader());
// classloadercache.put(ci.getParent(), ea.getModel().getClassLoader());
ret.setResult(ea.getModel().getResourceIdentifier());
}
public void exceptionOccurred(Exception exception)
{
// External access of parent not found, because already terminated (hack!!! fix creation/destroy structure lock)
if(ci.getParent()!=null)
{
exception = new ComponentTerminatedException(ci.getParent());
}
super.exceptionOccurred(exception);
}
}));
}
// Remote or no parent or platform as parent
else
{
// null resource identifier for searching in all current libservice resources.
ret.setResult(null);
}
return ret;
}
// /**
// * Get the component adapter for a component identifier.
// * @param aid The component identifier.
// * @param listener The result listener.
// */
// // Todo: Hack!!! remove
// @Excluded
// public IFuture getComponentAdapter(IComponentIdentifier cid)
// {
// return new Future(internalGetComponentAdapter(cid));
// }
// /**
// * Get the component adapter for a component identifier.
// * @param aid The component identifier.
// * @param listener The result listener.
// */
// // Todo: Hack!!! remove
// @Excluded
// public IComponentAdapter internalGetComponentAdapter(IComponentIdentifier cid)
// {
// IComponentAdapter ret;
// ret = (IComponentAdapter)adapters.get(cid);
// // Hack, to retrieve description from component itself in init phase
// if(ret==null)
// {
// InitInfo ii= getInitInfo(cid);
// if(ii!=null)
// ret = ii.getAdapter();
// }
// // Hack, to retrieve root adapter in bootstrapping phase.
// if(cid.equals(root.getComponentIdentifier()))
// {
// ret = root;
// }
// return ret;
// }
//-------- parent/child component accessors --------
/**
* Get the parent component of a component.
* @param cid The component identifier.
* @return The parent component identifier.
*/
public IComponentIdentifier getParentIdentifier(CreationInfo ci)
{
IComponentIdentifier ret = ci!=null && ci.getParent()!=null ? ci.getParent() : agent.getComponentIdentifier();
// System.out.println("parent id: "+ret);
return ret;
}
/**
* Get the parent component of a component.
* @param cid The component identifier.
* @return The parent component identifier.
*/
public IFuture getParent(final IComponentIdentifier cid)
{
// final Future ret = new Future();
// if(isRemoteComponent(cid))
// {
// getRemoteCMS(cid).addResultListener(createResultListener(new ExceptionDelegationResultListener(ret)
// {
// public void customResultAvailable(IComponentManagementService rcms)
// {
// rcms.getParent(cid).addResultListener(createResultListener(new DelegationResultListener(ret)));
// }
// }));
// }
// else
// {
// CMSComponentDescription desc = (CMSComponentDescription)getDescription(cid);
// ret.setResult(desc!=null? desc.getName().getParent(): null);
// }
// return ret;
return new Future(cid.getParent());
}
/**
* Get the children components of a component.
* @param cid The component identifier.
* @return The children component identifiers.
*/
public IFuture getChildren(final IComponentIdentifier cid)
{
final Future ret = new Future();
if(isRemoteComponent(cid))
{
getRemoteCMS(cid).addResultListener(createResultListener(new ExceptionDelegationResultListener(ret)
{
public void customResultAvailable(IComponentManagementService rcms)
{
rcms.getChildren(cid).addResultListener(createResultListener(new DelegationResultListener(ret)));
}
public void exceptionOccurred(Exception exception)
{
super.exceptionOccurred(exception);
}
}));
}
else
{
// if(cid.getParent()==null)
// System.out.println("getChildren: "+cid);
IComponentIdentifier[] tmp = internalGetChildren(cid);
ret.setResult(tmp);
// Nice style to check for valid?
// checkValid().addResultListener(new IResultListener()
// {
// public void resultAvailable(Object source, Object result)
// {
// CMSComponentDescription desc = (CMSComponentDescription)descs.get(cid);
// IComponentIdentifier[] tmp = desc!=null? desc.getChildren()!=null? desc.getChildren():
// IComponentIdentifier.EMPTY_COMPONENTIDENTIFIERS: IComponentIdentifier.EMPTY_COMPONENTIDENTIFIERS;
// ret.setResult(tmp);
// }
//
// public void exceptionOccurred(Object source, Exception exception)
// {
// ret.setException(exception);
// }
// });
}
return ret;
}
/**
* Get the children of a component.
*/
protected IComponentIdentifier[] internalGetChildren(final IComponentIdentifier cid)
{
IComponentIdentifier[] tmp;
CMSComponentDescription desc = (CMSComponentDescription)getDescription(cid);
// System.out.println("desc: "+desc.getName()+" "+desc.hashCode());
tmp = desc!=null? desc.getChildren()!=null? desc.getChildren():
IComponentIdentifier.EMPTY_COMPONENTIDENTIFIERS: IComponentIdentifier.EMPTY_COMPONENTIDENTIFIERS;
// System.out.println(getServiceIdentifier()+" "+desc.getName()+" "+SUtil.arrayToString(tmp));
return tmp;
}
// /**
// * Get the children components of a component.
// * @param cid The component identifier.
// * @return The children component identifiers.
// */
// public IIntermediateFuture getChildren(final IComponentIdentifier cid)
// {
// final IntermediateFuture ret = new IntermediateFuture();
//
// if(isRemoteComponent(cid))
// {
// getRemoteCMS(cid).addResultListener(createResultListener(new ExceptionDelegationResultListener>(ret)
// {
// public void customResultAvailable(IComponentManagementService rcms)
// {
// rcms.getChildren(cid).addResultListener(createResultListener(new IntermediateDelegationResultListener(ret)));
// }
//
// public void exceptionOccurred(Exception exception)
// {
// super.exceptionOccurred(exception);
// }
// }));
// }
// else
// {
// // System.out.println("getChildren: "+this+" "+isValid());
// IComponentIdentifier[] tmp;
// CMSComponentDescription desc = (CMSComponentDescription)getDescription(cid);
//// System.out.println("desc: "+desc.getName()+" "+desc.hashCode());
// tmp = desc!=null? desc.getChildren()!=null? desc.getChildren():
// IComponentIdentifier.EMPTY_COMPONENTIDENTIFIERS: IComponentIdentifier.EMPTY_COMPONENTIDENTIFIERS;
//// System.out.println(getServiceIdentifier()+" "+desc.getName()+" "+SUtil.arrayToString(tmp));
// ret.setResult(tmp);
//
// // Nice style to check for valid?
// // checkValid().addResultListener(new IResultListener()
// // {
// // public void resultAvailable(Object source, Object result)
// // {
// // CMSComponentDescription desc = (CMSComponentDescription)descs.get(cid);
// // IComponentIdentifier[] tmp = desc!=null? desc.getChildren()!=null? desc.getChildren():
// // IComponentIdentifier.EMPTY_COMPONENTIDENTIFIERS: IComponentIdentifier.EMPTY_COMPONENTIDENTIFIERS;
// // ret.setResult(tmp);
// // }
// //
// // public void exceptionOccurred(Object source, Exception exception)
// // {
// // ret.setException(exception);
// // }
// // });
// }
//
// return ret;
// }
/**
* Get the children components of a component.
* @param cid The component identifier.
* @return The children component descriptions.
*/
public IFuture getChildrenDescriptions(final IComponentIdentifier cid)
{
final Future ret = new Future();
if(isRemoteComponent(cid))
{
getRemoteCMS(cid).addResultListener(createResultListener(
new ExceptionDelegationResultListener(ret)
{
public void customResultAvailable(IComponentManagementService rcms)
{
rcms.getChildrenDescriptions(cid).addResultListener(createResultListener(new DelegationResultListener(ret)));
}
public void exceptionOccurred(Exception exception)
{
super.exceptionOccurred(exception);
}
}));
}
else
{
CMSComponentDescription desc = (CMSComponentDescription)getDescription(cid);
IComponentIdentifier[] tmp = desc!=null? desc.getChildren()!=null? desc.getChildren():
IComponentIdentifier.EMPTY_COMPONENTIDENTIFIERS: IComponentIdentifier.EMPTY_COMPONENTIDENTIFIERS;
IComponentDescription[] descs = new IComponentDescription[tmp.length];
for(int i=0; i()
// {
// public void resultAvailable(IComponentDescription[] result)
// {
// System.out.println("found childs: "+cid+" "+SUtil.arrayToString(result));
// }
// public void exceptionOccurred(Exception exception)
// {
// if(exception instanceof ClassCastException)
// exception.printStackTrace();
// System.out.println("exe: "+exception);
// }
// });
return ret;
}
//--------- information methods --------
/**
* Get the component description of a single component.
* @param cid The component identifier.
* @return The component description of this component.
*/
public IFuture getComponentDescription(final IComponentIdentifier cid)
{
final Future ret = new Future();
if(isRemoteComponent(cid))
{
getRemoteCMS(cid).addResultListener(createResultListener(new ExceptionDelegationResultListener(ret)
{
public void customResultAvailable(IComponentManagementService rcms)
{
rcms.getComponentDescription(cid).addResultListener(createResultListener(new DelegationResultListener(ret)));
}
}));
}
else
{
CMSComponentDescription desc = (CMSComponentDescription)getDescription(cid);
// Hack, to retrieve description from component itself in init phase
if(desc==null)
{
InitInfo ii= getInitInfo(cid);
if(ii!=null)
{
desc = (CMSComponentDescription)ii.getComponent().getInternalAccess().getComponentDescription();
}
}
if(desc!=null)
{
// IMessageService ms = getMessageService0();
//
// if(ms==null)
// {
ret.setResult(desc);
// }
// else
// {
// final CMSComponentDescription fdesc = desc;
// ms.updateComponentIdentifier(cid).addResultListener(new ExceptionDelegationResultListener(ret)
// {
// public void customResultAvailable(IComponentIdentifier rcid)
// {
// // addresses required for communication across platforms.
// // ret.setName(refreshComponentIdentifier(aid));
// fdesc.setName(rcid);
// ret.setResult(fdesc);
// }
// });
// }
}
else
{
ret.setException(new ComponentNotFoundException("No description available for: "+cid));
}
}
return ret;
}
/**
* Get the component descriptions.
* @return The component descriptions.
*/
public IFuture getComponentDescriptions()
{
Future fut = new Future();
IComponentDescription[] ret = new IComponentDescription[components.size()];
int i=0;
for(Iterator it=components.values().iterator(); i getComponentIdentifiers()
{
return new Future((IComponentIdentifier[])components.keySet().toArray(new IComponentIdentifier[components.size()]));
// final Future fut = new Future();
//
// getAddresses().addResultListener(createResultListener(
// new ExceptionDelegationResultListener(fut)
// {
// public void customResultAvailable(String[] addresses)
// {
// IComponentIdentifier[] ret;
//
// ret = (IComponentIdentifier[])components.keySet().toArray(new IComponentIdentifier[components.size()]);
//
// if(ret.length>0)
// {
// if(!Arrays.equals(ret[0].getAddresses(), addresses))
// {
// // addresses required for inter-platform comm.
// for(int i=0; i getRootIdentifier()
{
return new Future(agent.getComponentIdentifier());
}
/**
* Search for components matching the given description.
* @return An array of matching component descriptions.
*/
public IFuture searchComponents(IComponentDescription adesc, ISearchConstraints con)
{
return searchComponents(adesc, con, false);
}
/**
* Search for components matching the given description.
* @return An array of matching component descriptions.
*/
public IFuture searchComponents(final IComponentDescription adesc, final ISearchConstraints con, boolean remote)
{
final Future fut = new Future();
// System.out.println("search: "+components);
final List ret = new ArrayList();
// If name is supplied, just lookup description.
if(adesc!=null && adesc.getName()!=null)
{
CMSComponentDescription ad = (CMSComponentDescription)getDescription(adesc.getName());
if(ad!=null && ad.getName().equals(adesc.getName()))
{
// Todo: addresses reuqired for interplatform comm.
// ad.setName(refreshComponentIdentifier(ad.getName()));
CMSComponentDescription desc = (CMSComponentDescription)ad.clone();
ret.add(desc);
}
}
// Otherwise search for matching descriptions.
else
{
for(Iterator it=components.values().iterator(); it.hasNext(); )
{
CMSComponentDescription test = (CMSComponentDescription)it.next().getInternalAccess().getComponentDescription();
if(adesc==null ||
(adesc.getOwnership()==null || adesc.getOwnership().equals(test.getOwnership()))
// && (adesc.getName().getParent()==null || adesc.getName().getParent().equals(test.getParent()))
&& (adesc.getType()==null || adesc.getType().equals(test.getType()))
&& (adesc.getState()==null || adesc.getState().equals(test.getState()))
// && (adesc.getProcessingState()==null || adesc.getProcessingState().equals(test.getProcessingState()))
&& (adesc.getModelName()==null || adesc.getModelName().equals(test.getModelName())))
{
ret.add(test);
}
}
}
//System.out.println("searched: "+ret);
// System.out.println("Started search: "+ret);
// open.add(fut);
if(remote)
{
IFuture> futi = SServiceProvider.getServices(agent, IComponentManagementService.class, RequiredServiceInfo.SCOPE_GLOBAL);
futi.addResultListener(createResultListener(new IResultListener>()
{
public void resultAvailable(Collection result)
{
// System.out.println("cms: "+coll);
// Ignore search failures of remote dfs
IResultListener lis = createResultListener(new CollectionResultListener(result.size(), true,
new IResultListener>()
{
public void resultAvailable(Collection result)
{
// Add all services of all remote dfs
for(Iterator it=result.iterator(); it.hasNext(); )
{
IComponentDescription[] res = it.next();
if(res!=null)
{
for(int i=0; i it=result.iterator(); it.hasNext(); )
{
IComponentManagementService remotecms = it.next();
if(remotecms!=ComponentManagementService.this)
{
remotecms.searchComponents(adesc, con, false).addResultListener(lis);
}
else
{
lis.resultAvailable(null);
}
}
}
public void exceptionOccurred(Exception exception)
{
// open.remove(fut);
fut.setResult((CMSComponentDescription[])ret.toArray(new CMSComponentDescription[ret.size()]));
}
}));
}
else
{
// open.remove(fut);
// System.out.println("Local search: "+ret+" "+open);
fut.setResult((CMSComponentDescription[])ret.toArray(new CMSComponentDescription[ret.size()]));
}
return fut;
}
// /**
// * Create a component identifier that is allowed on the platform.
// * @param name The base name.
// * @return The component identifier.
// */
// public IComponentIdentifier generateComponentIdentifier(String localname, String platformname, String[] addresses)
// {
// ComponentIdentifier ret = null;
//
// if(platformname==null)
// platformname = agent.getComponentIdentifier().getName();
// ret = new ComponentIdentifier(localname+"@"+platformname, addresses);
//
// if(uniqueids || components.containsKey(ret) || initinfos.containsKey(ret))
// {
// String key = localname+"@"+platformname;
//
// do
// {
// Integer cnt = cidcounts.get(key);
// if(cnt==null)
// {
// cidcounts.put(key, Integer.valueOf(1));
// ret = new ComponentIdentifier(localname+"@"+platformname, addresses);
// }
// else
// {
// cidcounts.put(key, Integer.valueOf(cnt.intValue()+1));
// ret = new ComponentIdentifier(localname+cnt+"@"+platformname, addresses); // Hack?!
// }
// }
// while(components.containsKey(ret) || initinfos.containsKey(ret) || cfs.containsKey(ret));
// }
//
// return ret;
// }
/**
* Create a component identifier that is allowed on the platform.
* @param name The base name.
* @return The component identifier.
*/
public IComponentIdentifier generateComponentIdentifier(String localname, String platformname)
{
BasicComponentIdentifier ret = null;
if(platformname==null)
platformname = agent.getComponentIdentifier().getName();
ret = new BasicComponentIdentifier(localname+"@"+platformname);
if(uniqueids || components.containsKey(ret) || getInitInfo(ret)!=null)
{
String key = localname+"@"+platformname;
do
{
Integer cnt = cidcounts.get(key);
if(cnt==null)
{
cidcounts.put(key, Integer.valueOf(1));
ret = new BasicComponentIdentifier(localname+"@"+platformname);
}
else
{
cidcounts.put(key, Integer.valueOf(cnt.intValue()+1));
ret = new BasicComponentIdentifier(localname+cnt+"@"+platformname); // Hack?!
}
}
while(components.containsKey(ret) || getInitInfo(ret)!=null || cfs.containsKey(ret));
}
return ret;
}
/**
* Set the state of a component (i.e. update the component description).
* Currently only switching between suspended/waiting is allowed.
*/
// hack???
public void setComponentState(IComponentIdentifier comp, String state)
{
assert IComponentDescription.STATE_SUSPENDED.equals(state) : "wrong state: "+comp+", "+state;
CMSComponentDescription desc = null;
desc = (CMSComponentDescription)getDescription(comp);
desc.setState(state);
notifyListenersChanged(comp, desc);
}
//-------- IService interface --------
/**
* Start the service.
* @return A future that is done when the service has completed starting.
*/
@ServiceStart
public IFuture startService()
{
final Future ret = new Future();
if(!running)
{
// Avoid double initialization from persistence service.
running = true;
logger = agent.getLogger();
componentfactory.startService(agent, sid.getResourceIdentifier()).addResultListener(new DelegationResultListener(ret)
{
public void customResultAvailable(Void result)
{
removeInitInfo(agent.getComponentIdentifier());
components.put(agent.getComponentIdentifier(), access);
ret.setResult(null);
// SServiceProvider.getService(agent, IMessageService.class, RequiredServiceInfo.SCOPE_PLATFORM)
// .addResultListener(createResultListener(new IResultListener()
// {
// public void resultAvailable(IMessageService result)
// {
// msgservice = result;
// cont();
// }
//
// public void exceptionOccurred(Exception exception)
// {
// cont();
// }
//
// protected void cont()
// {
// SServiceProvider.getService(agent, IClockService.class, RequiredServiceInfo.SCOPE_PLATFORM)
// .addResultListener(new ExceptionDelegationResultListener