org.jbpm.context.exe.VariableContainer Maven / Gradle / Ivy
The newest version!
package org.jbpm.context.exe;
import java.io.Serializable;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Session;
import org.jbpm.JbpmContext;
import org.jbpm.JbpmException;
import org.jbpm.context.log.VariableDeleteLog;
import org.jbpm.graph.exe.ProcessInstance;
import org.jbpm.graph.exe.Token;
import org.jbpm.logging.db.DbLoggingService;
public abstract class VariableContainer implements Serializable {
protected Map variableInstances;
private static final long serialVersionUID = 520258491083406913L;
protected abstract VariableContainer getParentVariableContainer();
public abstract Token getToken();
// variables ////////////////////////////////////////////////////////////////
public Object getVariable(String name) {
Object value = null;
if (hasVariableLocally(name)) {
value = getVariableLocally(name);
}
else {
VariableContainer parent = getParentVariableContainer();
if (parent != null) {
// check upwards in the token hierarchy
value = parent.getVariable(name);
}
}
return value;
}
public void setVariable(String name, Object value) {
VariableContainer parent = getParentVariableContainer();
if (hasVariableLocally(name) || parent == null) {
setVariableLocally(name, value);
}
else {
// propagate to parent variable container
parent.setVariable(name, value);
}
}
public boolean hasVariable(String name) {
// if the variable is present in the variable instances
if (hasVariableLocally(name)) return true;
// search in parent variable container
VariableContainer parent = getParentVariableContainer();
if (parent != null) return parent.hasVariable(name);
return false;
}
public void deleteVariable(String name) {
if (name == null) throw new JbpmException("variable name is null");
if (hasVariableLocally(name)) deleteVariableLocally(name);
}
/**
* adds all the given variables to this variable container. The method
* {@link #setVariables(Map)} is the same as this method, but it was added for naming
* consistency.
*/
public void addVariables(Map variables) {
setVariables(variables);
}
/**
* adds all the given variables to this variable container. It doesn't remove any existing
* variables unless they are overwritten by the given variables. This method is the same as
* {@link #addVariables(Map)} and this method was added for naming consistency.
*/
public void setVariables(Map variables) {
if (variables != null) {
for (Iterator iter = variables.entrySet().iterator(); iter.hasNext();) {
Map.Entry entry = (Map.Entry) iter.next();
setVariable((String) entry.getKey(), entry.getValue());
}
}
}
public Map getVariables() {
Map variables = getVariablesLocally();
VariableContainer parent = getParentVariableContainer();
if (parent != null) {
Map parentVariables = parent.getVariablesLocally();
parentVariables.putAll(variables);
variables = parentVariables;
}
return variables;
}
public Map getVariablesLocally() {
Map variables = new HashMap();
if (variableInstances != null) {
for (Iterator iter = variableInstances.entrySet().iterator(); iter.hasNext();) {
Map.Entry entry = (Map.Entry) iter.next();
String name = (String) entry.getKey();
VariableInstance variableInstance = (VariableInstance) entry.getValue();
if (!variables.containsKey(name)) {
variables.put(name, variableInstance.getValue());
}
}
}
return variables;
}
// local variable methods ///////////////////////////////////////////////////
public boolean hasVariableLocally(String name) {
return variableInstances != null && variableInstances.containsKey(name);
}
public Object getVariableLocally(String name) {
Object value = null;
// if the variable is present in the variable instances
if (hasVariableLocally(name)) {
value = getVariableInstance(name).getValue();
}
return value;
}
public void deleteVariableLocally(String name) {
deleteVariableInstance(name);
}
public void setVariableLocally(String name, Object value) {
if (name == null) {
throw new IllegalArgumentException("variable name is null");
}
VariableInstance variableInstance = getVariableInstance(name);
// if variable instance already exists and it does not support the new value
if (variableInstance != null && !variableInstance.supports(value)) {
// delete the old variable instance
if (log.isDebugEnabled()) {
log.debug(variableInstance.getToken() + " unsets '" + name + "' due to type change");
}
deleteVariableInstance(name);
variableInstance = null;
}
if (variableInstance != null) {
if (log.isDebugEnabled()) {
log.debug(variableInstance.getToken() + " sets '" + name + "' to " + value);
}
variableInstance.setValue(value);
}
else {
Token token = getToken();
if (log.isDebugEnabled()) {
log.debug(token + " initializes '" + name + "' to " + value);
}
addVariableInstance(VariableInstance.create(token, name, value));
}
}
// local variable instances /////////////////////////////////////////////////
public VariableInstance getVariableInstance(String name) {
return variableInstances != null ? (VariableInstance) variableInstances.get(name) : null;
}
public Map getVariableInstances() {
return variableInstances;
}
public void addVariableInstance(VariableInstance variableInstance) {
if (variableInstances == null) variableInstances = new HashMap();
variableInstances.put(variableInstance.getName(), variableInstance);
// only register additions in the updated variable containers
// because the registry is only used to check for non-persistable variables
ContextInstance contextInstance = getContextInstance();
if (contextInstance != null) contextInstance.addUpdatedVariableContainer(this);
}
public void deleteVariableInstance(String name) {
if (variableInstances != null) {
VariableInstance variableInstance = (VariableInstance) variableInstances.remove(name);
if (variableInstance != null) {
// unlink variable
variableInstance.removeReferences();
// log variable deletion
getToken().addLog(new VariableDeleteLog(variableInstance));
// if a context is present and its logging service is not connected to the database
JbpmContext jbpmContext = JbpmContext.getCurrentJbpmContext();
if (jbpmContext != null
&& !(jbpmContext.getServices().getLoggingService() instanceof DbLoggingService)) {
// delete variable instance here before all references to it are lost
Session session = jbpmContext.getSession();
if (session != null) session.delete(variableInstance);
}
}
}
}
public ContextInstance getContextInstance() {
Token token = getToken();
return token != null ? token.getProcessInstance().getContextInstance() : null;
}
/** @deprecated call {@link ContextInstance#getUpdatedVariableContainers()} instead */
public static Collection getUpdatedVariableContainers(ProcessInstance processInstance) {
return processInstance.getContextInstance().updatedVariableContainers;
}
private static final Log log = LogFactory.getLog(VariableContainer.class);
}