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.extension.envsupport.environment.AbstractEnvironmentSpace Maven / Gradle / Ivy
Go to download
The Jadex kernel extension envsupport allows for using 2D spaces in concert with components.
package jadex.extension.envsupport.environment;
import java.io.PrintWriter;
import java.io.StringWriter;
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 javax.swing.SwingUtilities;
import jadex.bridge.BasicComponentIdentifier;
import jadex.bridge.IComponentIdentifier;
import jadex.bridge.IComponentStep;
import jadex.bridge.IExternalAccess;
import jadex.bridge.IInternalAccess;
import jadex.bridge.component.IExecutionFeature;
import jadex.bridge.component.IMonitoringComponentFeature;
import jadex.bridge.modelinfo.SubcomponentTypeInfo;
import jadex.bridge.service.RequiredServiceInfo;
import jadex.bridge.service.search.SServiceProvider;
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.monitoring.IMonitoringEvent;
import jadex.bridge.service.types.monitoring.IMonitoringService.PublishEventLevel;
import jadex.commons.IFilter;
import jadex.commons.IPropertyObject;
import jadex.commons.IValueFetcher;
import jadex.commons.collection.MultiCollection;
import jadex.commons.future.CounterResultListener;
import jadex.commons.future.DefaultResultListener;
import jadex.commons.future.DelegationResultListener;
import jadex.commons.future.Future;
import jadex.commons.future.IFuture;
import jadex.commons.future.IIntermediateFutureCommandResultListener;
import jadex.commons.future.IResultListener;
import jadex.commons.future.ISubscriptionIntermediateFuture;
import jadex.commons.meta.IPropertyMetaDataSet;
import jadex.extension.envsupport.IObjectCreator;
import jadex.extension.envsupport.MEnvSpaceInstance;
import jadex.extension.envsupport.MEnvSpaceType;
import jadex.extension.envsupport.MObjectType;
import jadex.extension.envsupport.MObjectTypeProperty;
import jadex.extension.envsupport.dataview.IDataView;
import jadex.extension.envsupport.environment.ComponentActionList.ActionEntry;
import jadex.extension.envsupport.environment.space2d.Space2D;
import jadex.extension.envsupport.environment.space3d.Space3D;
import jadex.extension.envsupport.evaluation.DefaultDataProvider;
import jadex.extension.envsupport.evaluation.IObjectSource;
import jadex.extension.envsupport.evaluation.ITableDataConsumer;
import jadex.extension.envsupport.evaluation.ITableDataProvider;
import jadex.extension.envsupport.evaluation.SpaceObjectSource;
import jadex.extension.envsupport.math.Vector2Double;
import jadex.extension.envsupport.math.Vector3Double;
import jadex.extension.envsupport.observer.gui.IObserverCenter;
import jadex.extension.envsupport.observer.gui.ObserverCenter;
import jadex.extension.envsupport.observer.perspective.IPerspective;
import jadex.javaparser.IParsedExpression;
import jadex.javaparser.SimpleValueFetcher;
/**
* Abstract base class for environment space.
*/
public abstract class AbstractEnvironmentSpace extends SynchronizedPropertyObject implements IEnvironmentSpace
{
//-------- attributes --------
/** The context. */
protected IExternalAccess exta;
/** The space object types. */
protected Map objecttypes;
/** The space object meta data **/
protected Map objecttypesMeta;
/** The object task types. */
protected Map tasktypes;
/** The space process types. */
protected Map processtypes;
/** The percepttypes. */
protected Map percepttypes;
/** Available component actions. */
protected Map actions;
/** The percept generators. */
protected Map perceptgenerators;
/** The percept processors. */
protected MultiCollection perceptprocessors;
/** Avatar mappings. */
protected MultiCollection avatarmappings;
/** Initial avatar settings (cid -> [type, props]). */
protected Map initialavatars;
/** Data view mappings. */
protected MultiCollection dataviewmappings;
/** The environment processes. */
protected Map processes;
/** Long/ObjectIDs (keys) and environment objects (values). */
protected Map spaceobjects;
/** Types of EnvironmentObjects and lists of EnvironmentObjects of that type (typed view). */
protected Map spaceobjectsbytype;
/** Space objects by owner. */
protected Map spaceobjectsbyowner;
/** Object id counter for new ids. */
protected AtomicCounter objectidcounter;
/** Task id counter for new ids. */
protected AtomicCounter taskidcounter;
/** The list of scheduled component actions. */
protected ComponentActionList actionlist;
/** The list of scheduled percepts. */
protected PerceptList perceptlist;
/** Available views */
protected Map views;
/** The environment listeners. */
protected List listeners;
/** The fetcher. */
protected SimpleValueFetcher fetcher;
/** The data providers (name -> provider). */
protected Map dataproviders;
/** The data consumers. */
protected Map dataconsumers;
/** The zombie objects. */
protected Map zombieobjects;
/** The observers. */
protected List observercenters;
/** The class loader. */
protected ClassLoader classloader;
protected IInternalAccess ia;
protected MEnvSpaceInstance config;
protected IValueFetcher pfetcher;
//-------- constructors --------
/**
* Create an environment space
*/
public AbstractEnvironmentSpace()
{
super(null, new Object());
this.views = new HashMap();
this.avatarmappings = new MultiCollection();
this.dataviewmappings = new MultiCollection();
this.actions = new HashMap();
this.processtypes = new HashMap();
this.tasktypes = new HashMap();
this.processes = new HashMap();
this.percepttypes = new HashMap();
this.perceptgenerators = new HashMap();
this.perceptprocessors = new MultiCollection();
this.objecttypes = new HashMap();
this.objecttypesMeta = new HashMap();
this.spaceobjects = new HashMap();
this.zombieobjects = new HashMap();
this.spaceobjectsbytype = new HashMap();
this.spaceobjectsbyowner = new HashMap();
this.objectidcounter = new AtomicCounter();
this.taskidcounter = new AtomicCounter();
this.actionlist = new ComponentActionList(this);
this.perceptlist = new PerceptList(this);
this.dataproviders = new HashMap();
this.dataconsumers = new HashMap();
this.observercenters = new ArrayList();
}
public void setInitData(IInternalAccess ia, MEnvSpaceInstance config, IValueFetcher pfetcher)
{
this.ia = ia;
this.config = config;
this.pfetcher = pfetcher;
}
/**
* Create a space.
*/
public IFuture initSpace()
{
final Future ret = new Future();
// if(ia.getModel().getFullName().equals("jadex.bdibpmn.examples.marsworld.MarsWorld"))
// System.out.println("Initing space: "+this);
try
{
this.classloader = ia.getClassLoader();
final MEnvSpaceType mspacetype = (MEnvSpaceType)config.getType();
final SimpleValueFetcher fetcher = new SimpleValueFetcher(pfetcher);
fetcher.setValue("$space", this);
this.setFetcher(fetcher);
List mspaceprops = mspacetype.getPropertyList("properties");
MEnvSpaceType.setProperties(this, mspaceprops, fetcher);
List spaceprops = config.getPropertyList("properties");
MEnvSpaceType.setProperties(this, spaceprops, fetcher);
this.exta = ia.getExternalAccess();
if(this instanceof Space2D) // Hack?
{
Double width = config.getProperty("width")!=null? (Double)config.getProperty("width"): (Double)mspacetype.getProperty("width");
Double height = config.getProperty("height")!=null? (Double)config.getProperty("height"): (Double)mspacetype.getProperty("height");
((Space2D)this).setAreaSize(Vector2Double.getVector2(width, height));
}
if(this instanceof Space3D) // Hack?
{
Double width = config.getProperty("width")!=null? (Double)config.getProperty("width"): (Double)mspacetype.getProperty("width");
Double height = config.getProperty("height")!=null? (Double)config.getProperty("height"): (Double)mspacetype.getProperty("height");
Double depth = config.getProperty("depth")!=null? (Double)config.getProperty("depth"): (Double)mspacetype.getProperty("depth");
((Space3D)this).setAreaSize(Vector3Double.getVector3(width,depth, height));
}
// Create space object types.
List objecttypes = mspacetype.getPropertyList("objecttypes");
if(objecttypes!=null)
{
for(int i=0; i ocsdone = new Future();
List observers = config.getPropertyList("observers");
if(observers!=null)
{
CounterResultListener crl1 = new CounterResultListener(observers.size(), new DelegationResultListener(ocsdone));
for(int i=0; i ocdone = new Future();
ocdone.addResultListener(crl1);
List perspectives = mspacetype.getPropertyList("perspectives");
CounterResultListener crl2 = new CounterResultListener(perspectives.size(), new DelegationResultListener(ocdone));
for(int j=0; j(ret)
{
public void customResultAvailable(Void result)
{
// if(ia.getModel().getFullName().equals("jadex.bdibpmn.examples.marsworld.MarsWorld"))
// System.out.println("Inited observers: "+this);
Map mse = (Map)MEnvSpaceType.getProperty(mspacetype.getProperties(), "spaceexecutor");
if(mse!=null)
{
IParsedExpression exp = (IParsedExpression)MEnvSpaceType.getProperty(mse, "expression");
ISpaceExecutor exe = null;
if(exp!=null)
{
exe = (ISpaceExecutor)exp.getValue(fetcher); // Executor starts itself
}
else
{
try
{
exe = (ISpaceExecutor)((Class)MEnvSpaceType.getProperty(mse, "clazz")).newInstance();
List props = (List)mse.get("properties");
MEnvSpaceType.setProperties(exe, props, fetcher);
}
catch(Exception e)
{
ret.setException(e);
}
}
if(exe!=null)
exe.start();
}
ret.setResultIfUndone(result);
}
});
}
catch(Exception e)
{
ret.setException(e);
}
// In case of errors dispose observer centers if any.
ret.addResultListener(new IResultListener()
{
public void resultAvailable(Void result)
{
}
public void exceptionOccurred(Exception exception)
{
exception.printStackTrace();
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
for(int i=0; observercenters!=null && i waitForTask(Object taskid, Object objectid)
{
final Future ret = new Future();
SpaceObject so = (SpaceObject)getSpaceObject(objectid);
so.addTaskListener(taskid, new IResultListener()
{
public void resultAvailable(Object result)
{
ret.setResultIfUndone(null);
}
public void exceptionOccurred(Exception exception)
{
ret.setExceptionIfUndone(exception);
}
});
return ret;
}
/**
* Returns then names of the space processes.
* @return the names of the space processes
*/
public Set getSpaceProcessNames()
{
synchronized(monitor)
{
return new HashSet(processes.keySet());
}
}
/**
* Returns a space process.
* @param id ID of the space process
* @return the space process or null if not found
*/
public ISpaceProcess getSpaceProcess(Object id)
{
synchronized(monitor)
{
return (ISpaceProcess)processes.get(id);
}
}
/**
* Removes a space process.
* @param id ID of the space process
*/
public void removeSpaceProcess(Object id)
{
synchronized(monitor)
{
ISpaceProcess process = (ISpaceProcess)processes.remove(id);
if(process!=null)
process.shutdown(this);
}
}
/**
* Creates an object in this space.
* @param type the object's type
* @param properties initial properties (may be null)
* @param tasks initial task list (may be null)
* @return the object's ID
*/
public final ISpaceObject createSpaceObject(final String typename, Map properties, List tasks)
{
if(!objecttypes.containsKey(typename))
throw new RuntimeException("Unknown space object type: "+typename);
ISpaceObject ret;
synchronized(monitor)
{
// Generate id.
Object id;
do
{
id = objectidcounter.getNext();
}
while(spaceobjects.containsKey(id) || zombieobjects.containsKey(id));
// Prepare properties (runtime props override type props).
MObjectType mObjectType = (MObjectType)objecttypes.get(typename);
if(properties!=null)
properties = new HashMap(properties);
properties = mergeProperties(mObjectType, properties);
// Create the object.
ret = new SpaceObject(id, mObjectType, properties, tasks, monitor, this);
spaceobjects.put(id, ret);
// Store in owner objects.
if(properties!=null && properties.containsKey(ISpaceObject.PROPERTY_OWNER))
{
Object owner = properties.get(ISpaceObject.PROPERTY_OWNER);
List ownerobjects = (List)spaceobjectsbyowner.get(owner);
if(ownerobjects == null)
{
ownerobjects = new ArrayList();
spaceobjectsbyowner.put(owner, ownerobjects);
}
ownerobjects.add(ret);
}
}
initSpaceObject(ret);
return ret;
}
/**
* Creates a zombie object in this space.
* Zombies are not (yet) visible in the space and must be inited separately.
* @param type the object's type
* @param properties initial properties (may be null)
* @param tasks initial task list (may be null)
* @return the object's ID
*/
public ISpaceObject createSpaceObjectZombie(final String typename, Map properties, List tasks)
{
if(!objecttypes.containsKey(typename))
throw new RuntimeException("Unknown space object type: "+typename);
ISpaceObject ret;
synchronized(monitor)
{
// Generate id.
Object id;
do
{
id = objectidcounter.getNext();
}
while(spaceobjects.containsKey(id) || zombieobjects.containsKey(id));
// Prepare properties (runtime props override type props).
MObjectType mObjectType = (MObjectType)objecttypes.get(typename);
properties = mergeProperties(mObjectType, properties);
// Create the object.
ret = new SpaceObject(id, mObjectType, properties, tasks, monitor, this);
zombieobjects.put(id, ret);
// Store in owner objects.
if(properties!=null && properties.containsKey(ISpaceObject.PROPERTY_OWNER))
{
Object owner = properties.get(ISpaceObject.PROPERTY_OWNER);
List ownerobjects = (List)spaceobjectsbyowner.get(owner);
if(ownerobjects == null)
{
ownerobjects = new ArrayList();
spaceobjectsbyowner.put(owner, ownerobjects);
}
ownerobjects.add(ret);
}
}
return ret;
}
/**
* Creates an object in this space.
* @param type the object's type
* @param initproperties initial properties (may be null)
* @param tasks initial task list (may be null)
* @param listeners initial listeners (may be null)
*/
public void initSpaceObject(final ISpaceObject ret)
{
synchronized(monitor)
{
if(zombieobjects.containsKey(ret.getId()))
{
zombieobjects.remove(ret.getId());
spaceobjects.put(ret.getId(), ret);
}
// Store in type objects.
List typeobjects = (List)spaceobjectsbytype.get(ret.getType());
if(typeobjects == null)
{
typeobjects = new ArrayList();
spaceobjectsbytype.put(ret.getType(), typeobjects);
}
typeobjects.add(ret);
// Create view(s) for the object if any.
if(dataviewmappings!=null && dataviewmappings.get(ret.getType())!=null)
{
for(Iterator it=dataviewmappings.get(ret.getType()).iterator(); it.hasNext(); )
{
try
{
Map sourceview = (Map)it.next();
Map viewargs = new HashMap();
viewargs.put("sourceview", sourceview);
viewargs.put("space", this);
viewargs.put("object", ret);
IDataView view = (IDataView)((IObjectCreator)MEnvSpaceType.getProperty(sourceview, "creator")).createObject(viewargs);
addDataView((String)MEnvSpaceType.getProperty(sourceview, "name")+"_"+ret.getId(), view);
}
catch(Exception e)
{
if(e instanceof RuntimeException)
throw (RuntimeException)e;
throw new RuntimeException(e);
}
}
}
// Possibly create component.
for(Iterator it=avatarmappings.keySet().iterator(); it.hasNext(); )
{
String componenttype = (String)it.next();
AvatarMapping mapping = getAvatarMapping(componenttype, ret.getType());
if(mapping!=null && mapping.isCreateComponent())
{
// final Object fid = id;
// String name = null;
// if(mapping.getComponentName()!=null)
// {
//// SimpleValueFetcher fetch = new SimpleValueFetcher();
//// fetch.setValue("$space", this);
//// fetch.setValue("$object", ret);
// name = (String)mapping.getComponentName().getValue(getFetcher());
// }
final String compotype = componenttype;
getExternalAccess().getFileName(compotype).addResultListener(new DefaultResultListener()
{
public void resultAvailable(Object result)
{
final String filename = (String)result;
SServiceProvider.getService(exta, IComponentManagementService.class, RequiredServiceInfo.SCOPE_PLATFORM).addResultListener(new DefaultResultListener()
{
public void resultAvailable(Object result)
{
IComponentManagementService cms = (IComponentManagementService)result;
// cannot be dummy cid because agent calls getAvatar(cid) in init and needs its avatar
// the cid must be the final cid of the component hence it creates unique ids
/// IComponentIdentifier cid = cms.generateComponentIdentifier(SUtil.createUniqueId(compotype, 3), getExternalAccess().getComponentIdentifier().getName().replace("@", "."));
// SUtil.createUniqueId(compotype, 3) might lead to conflicts due to race conditions. Use object id as it is really unique.
// IComponentIdentifier cid = cms.generateComponentIdentifier(compotype+"_"+ret.getId(), getExternalAccess().getComponentIdentifier().getName().replace("@", "."));
// todo: can fail?
IComponentIdentifier cid = new BasicComponentIdentifier(compotype+"_"+ret.getId(), getExternalAccess().getComponentIdentifier());
// IComponentIdentifier cid = new ComponentIdentifier("dummy@hummy");
// Hack!!! Should have actual description and not just name and local type!?
CMSComponentDescription desc = new CMSComponentDescription();
desc.setName(cid);
desc.setLocalType(compotype);
setOwner(ret.getId(), desc);
// System.out.println("env create: "+cid);
IFuture future = cms.createComponent(cid.getLocalName(), filename,
new CreationInfo(null, null, getExternalAccess().getComponentIdentifier(), false, getExternalAccess().getModel().getAllImports()), null);
future.addResultListener(new IResultListener()
{
public void resultAvailable(Object result)
{
// System.out.println("env created: "+result);
// setOwner(ret.getId(), (IComponentIdentifier)result);
}
public void exceptionOccurred(final Exception exception)
{
exta.scheduleStep(new IComponentStep()
{
public IFuture execute(IInternalAccess ia)
{
// Todo: Propagate exception to kill application!
StringWriter sw = new StringWriter();
exception.printStackTrace(new PrintWriter(sw));
ia.getLogger().severe("Could not create component: "+compotype+"\n"+exception);
return IFuture.DONE;
}
});
}
});
}
});
}
});
}
}
}
if(listeners!=null)
{
EnvironmentEvent event = new EnvironmentEvent(EnvironmentEvent.OBJECT_CREATED, this, ret, null, null);
for(int i=0; i1)
throw new RuntimeException("More than one avatar for component: "+owner);
else if(ownedobjs.size()==1)
ret = (ISpaceObject)ownedobjs.get(0);
}
return ret;
}
}
/**
* Get the avatar object.
* @return The avatar object.
*/
public ISpaceObject getAvatar(IComponentDescription owner, String fullname)
{
ISpaceObject ret = getAvatar(owner);
// Create avatar on the fly if componentAdded not yet called.
if(ret==null)
{
ret = createAvatar(owner, fullname, true);
}
return ret;
}
/**
* Create an avatar.
*/
protected ISpaceObject createAvatar(IComponentDescription owner, String fullname, boolean zombie)
{
ISpaceObject ret = null;
// Possibly add or create avatar(s) if any.
if(initialavatars!=null && initialavatars.containsKey(owner))
{
Object[] ia = (Object[])initialavatars.get(owner);
String objecttype = (String)ia[0];
Map props = (Map)ia[1];
if(props==null)
props = new HashMap();
props.put(ISpaceObject.PROPERTY_OWNER, owner);
ret = zombie ? createSpaceObjectZombie(objecttype, props, null)
: createSpaceObject(objecttype, props, null);
}
else
{
String componenttype = owner.getLocalType();
if(componenttype==null && fullname!=null)
{
SubcomponentTypeInfo[] atypes = exta.getModel().getSubcomponentTypes();
for(int i=0; i it=avatarmappings.getCollection(componenttype).iterator(); mapping==null && it.hasNext(); )
{
AvatarMapping test = (AvatarMapping)it.next();
if(avatartype.equals(test.getObjectType()))
mapping = test;
}
return mapping;
}
/**
* Add a new data provider.
* @param name The name.
* @param provider The provider.
*/
public void addDataProvider(String name, ITableDataProvider provider)
{
dataproviders.put(name, provider);
}
/**
* Get a data provider.
* @param name The name.
* @return The provider.
*/
public ITableDataProvider getDataProvider(String name)
{
return (ITableDataProvider)dataproviders.get(name);
}
/**
* Add a new data consumer.
* @param consumer The consumer.
*/
public void addDataConsumer(String name, ITableDataConsumer consumer)
{
dataconsumers.put(name, consumer);
}
/**
* Get a data consumer.
* @param name The name.
* @return The consumer.
*/
public ITableDataConsumer getDataConsumer(String name)
{
return (ITableDataConsumer)dataconsumers.get(name);
}
/**
* Get the data consumers.
* @return The data consumers.
*/
public Collection getDataConsumers()
{
return dataconsumers.values();
}
/**
* Initialize the extension.
* Called once, when the extension is created.
*/
public IFuture init()
{
// space = (ISpace)getClazz().newInstance();
final Future ret = new Future();
initSpace().addResultListener(ia.getComponentFeature(IExecutionFeature.class).createResultListener(new DelegationResultListener(ret)
{
public void customResultAvailable(Void result)
{
// System.out.println("inited space");
// ia.addComponentListener(new IComponentListener()
// {
// IFilter filter = new IFilter()
// {
// public boolean filter(Object obj)
// {
// IComponentChangeEvent event = (IComponentChangeEvent)obj;
// return event.getSourceCategory().equals(StatelessAbstractInterpreter.TYPE_COMPONENT);
// }
// };
// public IFilter getFilter()
// {
// return filter;
// }
//
// public IFuture eventOccured(IComponentChangeEvent cce)
// {
// if(cce.getEventType().equals(IComponentChangeEvent.EVENT_TYPE_CREATION))
// {
//// System.out.println("add: "+cce.getDetails());
// componentAdded((IComponentDescription)cce.getDetails());
// }
// else if(cce.getEventType().equals(IComponentChangeEvent.EVENT_TYPE_DISPOSAL))
// {
//// System.out.println("rem: "+cce.getComponent());
// componentRemoved((IComponentDescription)cce.getDetails());
// }
// return IFuture.DONE;
// }
// });
final ISubscriptionIntermediateFuture sub = ia.getComponentFeature(IMonitoringComponentFeature.class).subscribeToEvents(new IFilter()
{
public boolean filter(IMonitoringEvent obj)
{
return obj.getType().endsWith(IMonitoringEvent.SOURCE_CATEGORY_COMPONENT)
|| obj.getType().equals(IMonitoringEvent.TYPE_SUBSCRIPTION_START);
}
}, false, PublishEventLevel.COARSE);
// System.out.println("sub add: "+this);
sub.addResultListener(new IIntermediateFutureCommandResultListener()
{
public void resultAvailable(Collection result)
{
}
public void intermediateResultAvailable(IMonitoringEvent result)
{
// System.out.println("rec: "+result);
if(result.getType().equals(IMonitoringEvent.TYPE_SUBSCRIPTION_START))
{
// System.out.println("space subscribed");
ret.setResult(null);
}
else if(result.getType().startsWith(IMonitoringEvent.EVENT_TYPE_CREATION))
{
// System.out.println("add: "+result);
componentAdded((IComponentDescription)result.getProperty("details"));
}
else if(result.getType().startsWith(IMonitoringEvent.EVENT_TYPE_DISPOSAL))
{
componentRemoved((IComponentDescription)result.getProperty("details"));
}
}
public void finished()
{
// System.out.println("fini");
}
public void exceptionOccurred(Exception e)
{
e.printStackTrace();
}
public void commandAvailable(Object command)
{
// ignore timer updates
}
});
}
}));
return ret;
}
/**
* Terminate the extension.
* Called once, when the extension is terminated.
*/
public IFuture terminate()
{
// System.err.println("terminate space: "+exta.getComponentIdentifier());
final Future ret = new Future();
final IObserverCenter[] ocs = (IObserverCenter[])observercenters.toArray(new IObserverCenter[observercenters.size()]);
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
try
{
for(int i=0; i