package org.jbpm.sim.jpdl;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jbpm.graph.def.Node;
import org.jbpm.graph.def.Transition;
import org.jbpm.module.def.ModuleDefinition;
import org.jbpm.module.exe.ModuleInstance;
import org.jbpm.sim.datasource.ProcessDataFilter;
import org.jbpm.sim.datasource.ProcessDataSource;
import org.jbpm.sim.def.DistributionDefinition;
import org.jbpm.sim.def.ResourceRequirement;
import org.jbpm.sim.exception.ExperimentConfigurationException;
import org.jbpm.taskmgmt.def.Task;
/**
* this object is populated during instrumentation (see SimulationTestCase)
*
* @author bernd.ruecker@camunda.com
*/
public class SimulationDefinition extends ModuleDefinition {
private static final long serialVersionUID = 1L;
private static Log log = LogFactory.getLog(SimulationDefinition.class);
// Map<Object (process elements), Object (any simulation configuration information)>
// Map simulationConfiguration;
/**
* Map containing pool definitions. The pool name is the key, the value is an Object array with
* the first element: size as Integer, and the second element: costsPerTimeUnit as Double
*/
private Map resourcePoolDefinitions = new HashMap();
private List distributions = new ArrayList();
/**
* maps for process elements which distribution to use The key is the process element, the value
* the distribution name
*/
private Map distributionMap = new HashMap();
/**
* Map which contains a list of resource requirements for process elements (for example Task's or
* State's) It is a Map<Object, List>
*/
private Map resourceRequirements = new HashMap();
/**
* Map which contains configured probabilities for Transitions It is a Map<Transition, Double>
*/
private Map transitionProbabilities = new HashMap();
private Map dataSources = new HashMap();
private Map dataFilters = new HashMap();
public ModuleInstance createInstance() {
return new SimulationInstance(this);
}
/**
* adds a resource pool. If the pool already exists, the bigger pool size is taken.
*
* @param poolName
* @param poolSize
*/
public void addResourcePool(String poolName, Integer poolSize, Double costPerTimeUnit) {
if (resourcePoolDefinitions.containsKey(poolName)) {
Integer otherPoolSize = (Integer) ((Object[]) resourcePoolDefinitions.get(poolName))[0];
if (poolSize.intValue() > otherPoolSize.intValue()) {
resourcePoolDefinitions.put(poolName, new Object[] { poolSize, costPerTimeUnit });
log.warn("resource pool '"
+ poolName
+ "' redefined in process '"
+ getProcessDefinition().getName()
+ "' with the bigger poolsize "
+ poolSize
+ ", was "
+ otherPoolSize
+ " before");
}
else if (poolSize.intValue() < otherPoolSize.intValue())
log.warn("resource pool '"
+ poolName
+ "' redefined in process '"
+ getProcessDefinition().getName()
+ "' with the smaler poolsize "
+ poolSize
+ " which is ignored. Poolsize still is "
+ otherPoolSize);
}
else
resourcePoolDefinitions.put(poolName, new Object[] { poolSize, costPerTimeUnit });
}
/**
* adds a resource pool. If the pool already exists it is overwritten
*
* @param poolName
* @param poolSize
*/
public void overwriteResourcePool(String poolName, Integer poolSize, Double costPerTimeUnit) {
resourcePoolDefinitions.put(poolName, new Object[] { poolSize, costPerTimeUnit });
}
public void addResourceRequirement(Object processElement, String poolName, int amount) {
List reqList = (List) resourceRequirements.get(processElement);
if (reqList == null) {
reqList = new ArrayList();
resourceRequirements.put(processElement, reqList);
}
reqList.add(new ResourceRequirement(poolName, amount));
}
/**
* adds a distribution.
*
* @param distDef
*/
public void addDistribution(DistributionDefinition distDef) {
distributions.add(distDef);
}
/**
* adds a distribution but delets all distribution definitions with the given name
*
* @param distDef
*/
public void overwriteDistribution(DistributionDefinition distDef) {
// delete all distributions with that name
for (Iterator iterator = new ArrayList(distributions).iterator(); iterator.hasNext();) {
DistributionDefinition dd = (DistributionDefinition) iterator.next();
if (dd.getName().equals(distDef.getName())) distributions.remove(dd);
}
// and add the new one
distributions.add(distDef);
}
public List getDistributions() {
return distributions;
}
private void addToDistributionMap(Object key, String distributionName) {
distributionMap.put(key, distributionName);
}
public void setStartDistribution(String distributionName) {
addToDistributionMap(processDefinition, distributionName);
}
public void addTaskDistribution(Task task, String distributionName) {
addToDistributionMap(task, distributionName);
}
public void addStateDistribution(Node state, String distributionName) {
addToDistributionMap(state, distributionName);
}
public Map getDistributionMap() {
return distributionMap;
}
public Map getResourceRequirements() {
return resourceRequirements;
}
public void addTransitionProbability(Transition trans, double prob) {
transitionProbabilities.put(trans, new Double(prob));
}
public Map getTransitionProbabilities() {
return transitionProbabilities;
}
public Map getResourcePoolDefinitions() {
return resourcePoolDefinitions;
}
public void setResourcePoolDefinitions(Map resourcePoolDefinitions) {
this.resourcePoolDefinitions = resourcePoolDefinitions;
}
public void addDataSource(String name, ProcessDataSource src) {
dataSources.put(name, src);
}
public ProcessDataSource getDataSource(String name) {
ProcessDataSource result = (ProcessDataSource) dataSources.get(name);
if (result == null)
throw new ExperimentConfigurationException("data source '" + name + "' not configured");
return result;
}
public void addDataFilter(String name, ProcessDataFilter filter) {
dataFilters.put(name, filter);
}
public ProcessDataFilter getDataFilter(String name) {
ProcessDataFilter result = (ProcessDataFilter) dataFilters.get(name);
if (result == null)
throw new ExperimentConfigurationException("data filter '" + name + "' not configured");
return result;
}
}