JBoss JBPM SVN: r6436 - in jbpm3/branches/jbpm-3.2-soa: modules/core/src/main/java/org/jbpm/graph/exe and 1 other directory.
by do-not-reply@jboss.org
Author: alex.guizar(a)jboss.com
Date: 2010-06-24 15:31:56 -0400 (Thu, 24 Jun 2010)
New Revision: 6436
Modified:
jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/exe/ProcessInstance.java
jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/exe/Token.java
jbpm3/branches/jbpm-3.2-soa/pom.xml
Log:
improve process instance termination logic
access jboss public repositories non-securely for faster transfers
Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/exe/ProcessInstance.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/exe/ProcessInstance.java 2010-06-24 06:06:27 UTC (rev 6435)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/exe/ProcessInstance.java 2010-06-24 19:31:56 UTC (rev 6436)
@@ -47,14 +47,14 @@
import org.jbpm.module.exe.ModuleInstance;
import org.jbpm.msg.MessageService;
import org.jbpm.persistence.PersistenceService;
+import org.jbpm.scheduler.SchedulerService;
import org.jbpm.svc.Services;
import org.jbpm.taskmgmt.exe.TaskMgmtInstance;
import org.jbpm.util.Clock;
/**
- * is one execution of a {@link org.jbpm.graph.def.ProcessDefinition}. To create
- * a new process execution of a process definition, just use the
- * {@link #ProcessInstance(ProcessDefinition)}.
+ * is one execution of a {@link org.jbpm.graph.def.ProcessDefinition}. To create a new process
+ * execution of a process definition, just use the {@link #ProcessInstance(ProcessDefinition)}.
*/
public class ProcessInstance implements Identifiable, Serializable {
@@ -81,12 +81,11 @@
}
/**
- * creates a new process instance for the given process definition, puts the
- * root-token (=main path of execution) in the start state and executes the
- * initial node. In case the initial node is a start-state, it will behave as
- * a wait state. For each of the optional module definitions contained in the
- * {@link ProcessDefinition}, the corresponding module instance will be
- * created.
+ * creates a new process instance for the given process definition, puts the root-token (=main
+ * path of execution) in the start state and executes the initial node. In case the initial
+ * node is a start-state, it will behave as a wait state. For each of the optional module
+ * definitions contained in the {@link ProcessDefinition}, the corresponding module instance
+ * will be created.
*
* @throws JbpmException if processDefinition is null.
*/
@@ -95,16 +94,15 @@
}
/**
- * creates a new process instance for the given process definition, puts the
- * root-token (=main path of execution) in the start state and executes the
- * initial node. In case the initial node is a start-state, it will behave as
- * a wait state. For each of the optional module definitions contained in the
- * {@link ProcessDefinition}, the corresponding module instance will be
- * created.
+ * creates a new process instance for the given process definition, puts the root-token (=main
+ * path of execution) in the start state and executes the initial node. In case the initial
+ * node is a start-state, it will behave as a wait state. For each of the optional module
+ * definitions contained in the {@link ProcessDefinition}, the corresponding module instance
+ * will be created.
*
- * @param variables will be inserted into the context variables after the
- * context submodule has been created and before the process-start event is
- * fired, which is also before the execution of the initial node.
+ * @param variables will be inserted into the context variables after the context submodule
+ * has been created and before the process-start event is fired, which is also before the
+ * execution of the initial node.
* @throws JbpmException if processDefinition is null.
*/
public ProcessInstance(ProcessDefinition processDefinition, Map variables) {
@@ -112,16 +110,15 @@
}
/**
- * creates a new process instance for the given process definition, puts the
- * root-token (=main path of execution) in the start state and executes the
- * initial node. In case the initial node is a start-state, it will behave as
- * a wait state. For each of the optional module definitions contained in the
- * {@link ProcessDefinition}, the corresponding module instance will be
- * created.
+ * creates a new process instance for the given process definition, puts the root-token (=main
+ * path of execution) in the start state and executes the initial node. In case the initial
+ * node is a start-state, it will behave as a wait state. For each of the optional module
+ * definitions contained in the {@link ProcessDefinition}, the corresponding module instance
+ * will be created.
*
- * @param variables will be inserted into the context variables after the
- * context submodule has been created and before the process-start event is
- * fired, which is also before the execution of the initial node.
+ * @param variables will be inserted into the context variables after the context submodule
+ * has been created and before the process-start event is fired, which is also before the
+ * execution of the initial node.
* @throws JbpmException if processDefinition is null.
*/
public ProcessInstance(ProcessDefinition processDefinition, Map variables, String key) {
@@ -196,7 +193,8 @@
throw new IllegalArgumentException("module instance is null");
}
- if (instances == null) instances = new HashMap();
+ if (instances == null)
+ instances = new HashMap();
instances.put(moduleInstance.getClass().getName(), moduleInstance);
moduleInstance.setProcessInstance(this);
return moduleInstance;
@@ -232,7 +230,8 @@
}
if (moduleInstance == null) {
- if (transientInstances == null) transientInstances = new HashMap();
+ if (transientInstances == null)
+ transientInstances = new HashMap();
// client requested an instance that is not in the map of instances.
// so we can safely assume that the client wants a transient instance
@@ -270,9 +269,9 @@
}
/**
- * process instance extension for logging. Probably you don't need to access
- * the logging instance directly. Mostly, {@link Token#addLog(ProcessLog)} is
- * sufficient and more convenient.
+ * process instance extension for logging. Probably you don't need to access the logging
+ * instance directly. Mostly, {@link Token#addLog(ProcessLog)} is sufficient and more
+ * convenient.
*/
public LoggingInstance getLoggingInstance() {
return (LoggingInstance) getInstance(LoggingInstance.class);
@@ -281,8 +280,8 @@
// operations ///////////////////////////////////////////////////////////////
/**
- * instructs the main path of execution to continue by taking the default
- * transition on the current node.
+ * instructs the main path of execution to continue by taking the default transition on the
+ * current node.
*
* @throws IllegalStateException if the token is not active.
*/
@@ -294,8 +293,8 @@
}
/**
- * instructs the main path of execution to continue by taking the specified
- * transition on the current node.
+ * instructs the main path of execution to continue by taking the specified transition on the
+ * current node.
*
* @throws IllegalStateException if the token is not active.
*/
@@ -307,8 +306,8 @@
}
/**
- * instructs the main path of execution to continue by taking the specified
- * transition on the current node.
+ * instructs the main path of execution to continue by taking the specified transition on the
+ * current node.
*
* @throws IllegalStateException if the token is not active.
*/
@@ -323,50 +322,60 @@
* ends (=cancels) this process instance and all the tokens in it.
*/
public void end() {
+ // if already ended, do nothing
+ if (end != null)
+ return;
+
+ // record the end time
+ // the end time also indicates that this process instance has ended
+ end = Clock.getCurrentTime();
+
// end the main path of execution
rootToken.end();
- if (end == null) {
- // mark this process instance as ended
- end = Clock.getCurrentTime();
+ // fire the process-end event
+ ExecutionContext executionContext = new ExecutionContext(rootToken);
+ processDefinition.fireEvent(Event.EVENTTYPE_PROCESS_END, executionContext);
- // fire the process-end event
- ExecutionContext executionContext = new ExecutionContext(rootToken);
- processDefinition.fireEvent(Event.EVENTTYPE_PROCESS_END, executionContext);
+ // add the process instance end log
+ rootToken.addLog(new ProcessInstanceEndLog());
- // add the process instance end log
- rootToken.addLog(new ProcessInstanceEndLog());
+ // check if this process was started as a subprocess of a super process
+ if (superProcessToken != null && !superProcessToken.hasEnded()) {
+ addCascadeProcessInstance(superProcessToken.getProcessInstance());
- // check if this process was started as a subprocess of a super process
- if (superProcessToken != null && !superProcessToken.hasEnded()) {
- addCascadeProcessInstance(superProcessToken.getProcessInstance());
+ ExecutionContext superExecutionContext = new ExecutionContext(superProcessToken);
+ superExecutionContext.setSubProcessInstance(this);
+ superProcessToken.signal(superExecutionContext);
+ }
- ExecutionContext superExecutionContext = new ExecutionContext(superProcessToken);
- superExecutionContext.setSubProcessInstance(this);
- superProcessToken.signal(superExecutionContext);
- }
-
- // make sure jobs for this process instance are canceled
- // after the process end updates are posted to the database
- JbpmContext jbpmContext = JbpmContext.getCurrentJbpmContext();
- if (jbpmContext != null) {
- Services services = jbpmContext.getServices();
+ // make sure jobs for this process instance are canceled
+ // after the process end updates are posted to the database
+ JbpmContext jbpmContext = JbpmContext.getCurrentJbpmContext();
+ if (jbpmContext != null) {
+ Services services = jbpmContext.getServices();
+ PersistenceService persistenceService = services.getPersistenceService();
+ if (persistenceService != null
+ && persistenceService.getJobSession().countDeletableJobsForProcessInstance(this) > 0) {
MessageService messageService = services.getMessageService();
- PersistenceService persistenceService = services.getPersistenceService();
- if (messageService != null && persistenceService != null
- && persistenceService.getJobSession().countDeletableJobsForProcessInstance(this) > 0) {
+ if (messageService != null) {
CleanUpProcessJob job = new CleanUpProcessJob(rootToken);
job.setDueDate(new Date());
messageService.send(job);
}
+ else {
+ SchedulerService schedulerService = services.getSchedulerService();
+ if (schedulerService != null) {
+ schedulerService.deleteTimersByProcessInstance(this);
+ }
+ }
}
}
}
/**
- * suspends this execution. This will make sure that tasks, timers and
- * messages related to this process instance will not show up in database
- * queries.
+ * suspends this execution. This will make sure that tasks, timers and messages related to
+ * this process instance will not show up in database queries.
*
* @see #resume()
*/
@@ -376,10 +385,10 @@
}
/**
- * resumes a suspended execution. All timers that have been suspended might
- * fire if the duedate has been passed. If an admin resumes a process
- * instance, the option should be offered to update, remove and create the
- * timers and messages related to this process instance.
+ * resumes a suspended execution. All timers that have been suspended might fire if the
+ * duedate has been passed. If an admin resumes a process instance, the option should be
+ * offered to update, remove and create the timers and messages related to this process
+ * instance.
*
* @see #suspend()
*/
@@ -397,7 +406,8 @@
if (runtimeAction == null) {
throw new IllegalArgumentException("runtime action is null");
}
- if (runtimeActions == null) runtimeActions = new ArrayList();
+ if (runtimeActions == null)
+ runtimeActions = new ArrayList();
runtimeActions.add(runtimeAction);
runtimeAction.processInstance = this;
return runtimeAction;
@@ -448,11 +458,9 @@
}
/**
- * looks up the token in the tree, specified by the slash-separated token
- * path.
+ * looks up the token in the tree, specified by the slash-separated token path.
*
- * @param tokenPath is a slash-separated name that specifies a token in the
- * tree.
+ * @param tokenPath is a slash-separated name that specifies a token in the tree.
* @return the specified token or null if the token is not found.
*/
public Token findToken(String tokenPath) {
@@ -485,18 +493,22 @@
// equals ///////////////////////////////////////////////////////////////////
public boolean equals(Object o) {
- if (o == this) return true;
- if (!(o instanceof ProcessInstance)) return false;
+ if (o == this)
+ return true;
+ if (!(o instanceof ProcessInstance))
+ return false;
ProcessInstance other = (ProcessInstance) o;
- if (id != 0 && id == other.getId()) return true;
+ if (id != 0 && id == other.getId())
+ return true;
return key != null && key.equals(other.getKey())
&& processDefinition.equals(other.getProcessDefinition());
}
public int hashCode() {
- if (key == null) return super.hashCode();
+ if (key == null)
+ return super.hashCode();
int result = 295436291 + key.hashCode();
result = 1367411281 * result + processDefinition.hashCode();
Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/exe/Token.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/exe/Token.java 2010-06-24 06:06:27 UTC (rev 6435)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/exe/Token.java 2010-06-24 19:31:56 UTC (rev 6436)
@@ -224,7 +224,8 @@
* resolves to true.
*/
public Set getAvailableTransitions() {
- if (node == null) return Collections.EMPTY_SET;
+ if (node == null)
+ return Collections.EMPTY_SET;
Set availableTransitions = new HashSet();
addAvailableTransitionsOfNode(node, availableTransitions);
@@ -244,7 +245,8 @@
if (conditionExpression != null) {
Boolean result = (Boolean) JbpmExpressionEvaluator.evaluate(conditionExpression,
new ExecutionContext(this), Boolean.class);
- if (Boolean.TRUE.equals(result)) availableTransitions.add(transition);
+ if (Boolean.TRUE.equals(result))
+ availableTransitions.add(transition);
}
else {
availableTransitions.add(transition);
@@ -276,22 +278,24 @@
public void end(boolean verifyParentTermination) {
// if already ended, do nothing
if (end != null) {
- if (parent != null) log.warn(this + " has ended already");
+ if (parent != null)
+ log.warn(this + " has ended already");
return;
}
+ // record the end date
+ // the end date also indicates that this token has ended
+ end = Clock.getCurrentTime();
+
// ended tokens cannot reactivate parents
isAbleToReactivateParent = false;
- // set the end date
- // the end date also indicates that this token has ended
- end = Clock.getCurrentTime();
-
// end all this token's children
if (children != null) {
for (Iterator iter = children.values().iterator(); iter.hasNext();) {
Token child = (Token) iter.next();
- if (!child.hasEnded()) child.end();
+ if (!child.hasEnded())
+ child.end();
}
}
@@ -309,7 +313,8 @@
// if there are tasks associated to this token,
// remove signaling capabilities
TaskMgmtInstance taskMgmtInstance = processInstance.getTaskMgmtInstance();
- if (taskMgmtInstance != null) taskMgmtInstance.removeSignalling(this);
+ if (taskMgmtInstance != null)
+ taskMgmtInstance.removeSignalling(this);
if (verifyParentTermination) {
// if this is the last active token of the parent,
@@ -325,7 +330,8 @@
}
public void addComment(Comment comment) {
- if (comments == null) comments = new ArrayList();
+ if (comments == null)
+ comments = new ArrayList();
comments.add(comment);
comment.setToken(this);
}
@@ -356,7 +362,8 @@
if (children != null) {
for (Iterator iter = children.values().iterator(); iter.hasNext();) {
Token child = (Token) iter.next();
- if (!child.hasEnded()) return true;
+ if (!child.hasEnded())
+ return true;
}
}
return false;
@@ -392,7 +399,8 @@
*/
public void endCompositeLog() {
LoggingInstance loggingInstance = processInstance.getLoggingInstance();
- if (loggingInstance != null) loggingInstance.endCompositeLog();
+ if (loggingInstance != null)
+ loggingInstance.endCompositeLog();
}
// various information extraction methods ///////////////////////////////////
@@ -418,8 +426,10 @@
}
public String getFullName() {
- if (parent == null) return "/";
- if (parent.getParent() == null) return "/" + name;
+ if (parent == null)
+ return "/";
+ if (parent.getParent() == null)
+ return "/" + name;
return parent.getFullName() + "/" + name;
}
@@ -452,7 +462,8 @@
}
public Token findToken(String relativeTokenPath) {
- if (relativeTokenPath == null) return null;
+ if (relativeTokenPath == null)
+ return null;
String path = relativeTokenPath.trim();
if (("".equals(path)) || (".".equals(path))) {
return this;
@@ -504,12 +515,14 @@
public void checkImplicitTermination() {
if (isTerminationImplicit && node.hasNoLeavingTransitions()) {
end();
- if (processInstance.isTerminatedImplicitly()) processInstance.end();
+ if (processInstance.isTerminatedImplicitly())
+ processInstance.end();
}
}
public boolean isTerminatedImplicitly() {
- if (end != null) return true;
+ if (end != null)
+ return true;
Map leavingTransitions = node.getLeavingTransitionsMap();
if (leavingTransitions != null && !leavingTransitions.isEmpty()) {
@@ -520,7 +533,8 @@
// loop over all active child tokens
for (Iterator iter = getActiveChildren().values().iterator(); iter.hasNext();) {
Token child = (Token) iter.next();
- if (!child.isTerminatedImplicitly()) return false;
+ if (!child.isTerminatedImplicitly())
+ return false;
}
// if none of the above, this token is terminated implicitly
return true;
@@ -552,13 +566,15 @@
JbpmContext jbpmContext = JbpmContext.getCurrentJbpmContext();
if (jbpmContext != null) {
JobSession jobSession = jbpmContext.getJobSession();
- if (jobSession != null) jobSession.suspendJobs(this);
+ if (jobSession != null)
+ jobSession.suspendJobs(this);
}
}
void suspendTaskInstances() {
TaskMgmtInstance taskMgmtInstance = processInstance.getTaskMgmtInstance();
- if (taskMgmtInstance != null) taskMgmtInstance.suspend(this);
+ if (taskMgmtInstance != null)
+ taskMgmtInstance.suspend(this);
}
/**
@@ -583,23 +599,28 @@
JbpmContext jbpmContext = JbpmContext.getCurrentJbpmContext();
if (jbpmContext != null) {
JobSession jobSession = jbpmContext.getJobSession();
- if (jobSession != null) jobSession.resumeJobs(this);
+ if (jobSession != null)
+ jobSession.resumeJobs(this);
}
}
void resumeTaskInstances() {
TaskMgmtInstance taskMgmtInstance = processInstance.getTaskMgmtInstance();
- if (taskMgmtInstance != null) taskMgmtInstance.resume(this);
+ if (taskMgmtInstance != null)
+ taskMgmtInstance.resume(this);
}
// equals ///////////////////////////////////////////////////////////////////
public boolean equals(Object o) {
- if (o == this) return true;
- if (!(o instanceof Token)) return false;
+ if (o == this)
+ return true;
+ if (!(o instanceof Token))
+ return false;
Token other = (Token) o;
- if (id != 0 && id == other.getId()) return true;
+ if (id != 0 && id == other.getId())
+ return true;
return (name != null ? name.equals(other.getName()) : other.getName() == null)
&& (parent != null ? parent.equals(other.getParent())
@@ -636,11 +657,13 @@
* @see #unlock(String)
*/
public void lock(String lockOwner) {
- if (lockOwner == null) throw new JbpmException("lock owner is null");
+ if (lockOwner == null)
+ throw new JbpmException("lock owner is null");
if (lock == null) {
lock = lockOwner;
- if (log.isDebugEnabled()) log.debug('\'' + lockOwner + "' locked " + this);
+ if (log.isDebugEnabled())
+ log.debug('\'' + lockOwner + "' locked " + this);
}
else if (!lock.equals(lockOwner)) {
throw new JbpmException('\'' + lockOwner + "' cannot lock " + this + " because '" + lock
@@ -659,7 +682,8 @@
}
lock = null;
- if (log.isDebugEnabled()) log.debug('\'' + lockOwner + "' unlocked " + this);
+ if (log.isDebugEnabled())
+ log.debug('\'' + lockOwner + "' unlocked " + this);
}
else {
log.warn(this + " was already unlocked");
@@ -688,7 +712,8 @@
public void forceUnlock() {
if (lock != null) {
lock = null;
- if (log.isDebugEnabled()) log.debug("forcefully unlocked " + this);
+ if (log.isDebugEnabled())
+ log.debug("forcefully unlocked " + this);
}
else {
log.warn(this + " was unlocked already");
Modified: jbpm3/branches/jbpm-3.2-soa/pom.xml
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/pom.xml 2010-06-24 06:06:27 UTC (rev 6435)
+++ jbpm3/branches/jbpm-3.2-soa/pom.xml 2010-06-24 19:31:56 UTC (rev 6436)
@@ -415,7 +415,7 @@
<repository>
<id>jboss-public-repository-group</id>
<name>JBoss Public Maven Repository Group</name>
- <url>https://repository.jboss.org/nexus/content/groups/public/</url>
+ <url>http://repository.jboss.org/nexus/content/groups/public/</url>
<releases>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
@@ -430,7 +430,7 @@
<pluginRepository>
<id>jboss-public-repository-group</id>
<name>JBoss Public Maven Repository Group</name>
- <url>https://repository.jboss.org/nexus/content/groups/public/</url>
+ <url>http://repository.jboss.org/nexus/content/groups/public/</url>
<releases>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
15 years, 10 months
JBoss JBPM SVN: r6435 - in jbpm4/trunk/modules: api/src/main/java/org/jbpm/api/history and 36 other directories.
by do-not-reply@jboss.org
Author: alex.guizar(a)jboss.com
Date: 2010-06-24 02:06:27 -0400 (Thu, 24 Jun 2010)
New Revision: 6435
Added:
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/util/CollectionUtil.java
Removed:
jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/examples/goup/
Modified:
jbpm4/trunk/modules/api/src/main/java/org/jbpm/api/JobQuery.java
jbpm4/trunk/modules/api/src/main/java/org/jbpm/api/history/HistoryComment.java
jbpm4/trunk/modules/api/src/main/java/org/jbpm/api/job/Job.java
jbpm4/trunk/modules/examples/src/test/resources/org/jbpm/examples/mail/inline/process.jpdl.xml
jbpm4/trunk/modules/examples/src/test/resources/org/jbpm/examples/mail/template/process.jpdl.xml
jbpm4/trunk/modules/integration/console/src/main/java/org/jbpm/integration/console/ProcessEngineUtil.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/ant/JbpmDeployTask.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cal/CronExpression.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cal/Duration.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cmd/CompositeCmd.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cmd/CreateDeploymentQueryCmd.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cmd/CreateHistoryDetailQueryCmd.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cmd/DeleteDeploymentCmd.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cmd/DeleteJobCmd.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cmd/ExecuteJobCmd.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cmd/GetParticipantsCmd.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cmd/GetStartActivityNamesCmd.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cmd/GetSubTasksCmd.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cmd/GetTaskCommentsCmd.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cmd/GetTaskVariableNamesCmd.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JstlFunction.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/env/EnvironmentFactory.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/env/EnvironmentImpl.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/env/ExecutionContext.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/env/JobContext.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/env/TaskContext.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/hibernate/ConverterType.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/hibernate/DbSessionImpl.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/history/events/ProcessInstanceCreate.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/history/model/HistoryCommentImpl.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/history/model/HistoryTaskImpl.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/identity/impl/IdentitySessionImpl.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/job/CommandMessage.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/job/JobImpl.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/job/MessageImpl.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/job/StartProcessTimer.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/job/TimerImpl.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/jobexecutor/AcquireJobsCmd.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/jobexecutor/GetNextDueDateCmd.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/jobexecutor/JobExceptionHandler.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/jobexecutor/JobExecutor.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/jobexecutor/JobExecutorServlet.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/jobexecutor/JobExecutorTimerSession.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/EventImpl.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/ExecutionImpl.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/ObservableElementImpl.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/ProcessElementImpl.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/ScopeInstanceImpl.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/VariableOutDefinitionSet.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/WireProperties.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/AtomicOperation.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/ExecuteActivity.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/ExecuteActivityMessage.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/ExecuteEventListener.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/ExecuteEventListenerMessage.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/MoveToChildActivity.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/MoveToParentActivity.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/Signal.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/SignalMessage.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/TransitionEndActivity.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/TransitionStartActivity.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/TransitionStartActivityMessage.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/TransitionTake.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/processengine/SpringProcessEngine.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/query/DeploymentQueryImpl.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/query/HistoryActivityInstanceQueryImpl.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/query/HistoryDetailQueryImpl.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/query/HistoryProcessInstanceQueryImpl.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/query/HistoryTaskQueryImpl.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/query/JobQueryImpl.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/query/ProcessDefinitionQueryImpl.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/query/ProcessInstanceQueryImpl.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/query/TaskQueryImpl.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/repository/RepositoryServiceImpl.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/repository/RepositorySessionImpl.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/script/BshScriptEngine.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/script/GroovyScriptEngine.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/script/JuelScriptEngine.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/script/ScriptContextEngineView.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/script/XPathScriptEngine.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/session/DbSession.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/svc/AsyncCommandMessage.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/svc/SerializeInterceptor.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/task/SwimlaneDefinitionImpl.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/task/TaskDefinitionImpl.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/tx/SpringCommandCallback.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/tx/SpringTransaction.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/tx/SpringTransactionFactory.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/tx/StandardTransaction.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/tx/StandardTransactionInterceptor.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/type/converter/SerializableToBytesConverter.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/util/EqualsUtil.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/util/StringUtil.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/wire/WireContext.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/wire/binding/ListBinding.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/wire/descriptor/HibernateSessionFactoryDescriptor.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/wire/descriptor/ShortDescriptor.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/wire/descriptor/StringDescriptor.java
jbpm4/trunk/modules/pvm/src/main/resources/jbpm.execution.hbm.xml
jbpm4/trunk/modules/pvm/src/main/resources/jbpm.identity.hbm.xml
jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/bpmn/test/intermediatecatch/IntermediateCatchTimerEventTest.java
jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/bpmn/test/startevent/TimerStartEventTest.java
jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/identity/IdentityTest.java
jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/task/AssignmentHandlerTest.java
jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/task/TaskCommentsTest.java
Log:
JBPM-2893: remove type parameter from JobImpl
fix many raw type warnings
Modified: jbpm4/trunk/modules/api/src/main/java/org/jbpm/api/JobQuery.java
===================================================================
--- jbpm4/trunk/modules/api/src/main/java/org/jbpm/api/JobQuery.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/api/src/main/java/org/jbpm/api/JobQuery.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -37,7 +37,7 @@
public interface JobQuery {
/** duedate property to be used as property in {@link #orderAsc(String)} and {@link #orderDesc(String)} */
- public static final String PROPERTY_DUEDATE = "duedate";
+ public static final String PROPERTY_DUEDATE = "dueDate";
/** state property to be used as property in {@link #orderAsc(String)} and {@link #orderDesc(String)} */
public static final String PROPERTY_STATE = "state";
Modified: jbpm4/trunk/modules/api/src/main/java/org/jbpm/api/history/HistoryComment.java
===================================================================
--- jbpm4/trunk/modules/api/src/main/java/org/jbpm/api/history/HistoryComment.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/api/src/main/java/org/jbpm/api/history/HistoryComment.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -40,5 +40,5 @@
String getMessage();
/** threaded replies to this comment */
- List<HistoryComment> getReplies();
+ List<? extends HistoryComment> getReplies();
}
\ No newline at end of file
Modified: jbpm4/trunk/modules/api/src/main/java/org/jbpm/api/job/Job.java
===================================================================
--- jbpm4/trunk/modules/api/src/main/java/org/jbpm/api/job/Job.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/api/src/main/java/org/jbpm/api/job/Job.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -42,7 +42,8 @@
Date getDueDate();
/** in case this is a timer, it is the time that the timer should fire, in case this
- * is a message, it is null. */
+ * is a message, it is null.
+ * @deprecated call {@link #getDueDate()} instead */
@Deprecated
Date getDuedate();
Modified: jbpm4/trunk/modules/examples/src/test/resources/org/jbpm/examples/mail/inline/process.jpdl.xml
===================================================================
--- jbpm4/trunk/modules/examples/src/test/resources/org/jbpm/examples/mail/inline/process.jpdl.xml 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/examples/src/test/resources/org/jbpm/examples/mail/inline/process.jpdl.xml 2010-06-24 06:06:27 UTC (rev 6435)
@@ -3,13 +3,13 @@
<process name="InlineMail" xmlns="http://jbpm.org/4.3/jpdl">
<start g="20,25,80,40">
- <transition to="send rectify note" />
+ <transition to="send rectify note"/>
</start>
- <mail name="send rectify note" language="juel" g="99,25,115,45">
- <to addresses="winston@minitrue" />
- <cc users="bb" groups="innerparty" />
- <bcc groups="thinkpol" />
+ <mail g="99,25,115,45" language="juel" name="send rectify note">
+ <to addresses="winston@minitrue"/>
+ <cc groups="innerparty" users="bb"/>
+ <bcc groups="thinkpol"/>
<subject>rectify ${newspaper}</subject>
<text>${newspaper} ${date} reporting bb dayorder doubleplusungood
refs unpersons rewrite fullwise upsub antefiling</text>
@@ -24,9 +24,9 @@
<attachment file='${user.home}/.face' />
</attachments>
-->
- <transition to="end" />
+ <transition to="wait"/>
</mail>
- <state name="end" g="240,25,98,45"/>
+ <state g="240,25,98,45" name="wait"/>
</process>
\ No newline at end of file
Modified: jbpm4/trunk/modules/examples/src/test/resources/org/jbpm/examples/mail/template/process.jpdl.xml
===================================================================
--- jbpm4/trunk/modules/examples/src/test/resources/org/jbpm/examples/mail/template/process.jpdl.xml 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/examples/src/test/resources/org/jbpm/examples/mail/template/process.jpdl.xml 2010-06-24 06:06:27 UTC (rev 6435)
@@ -1,17 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
-<process name="TemplateMail" xmlns="http://jbpm.org/4.3/jpdl">
-
- <start g="20,25,80,40">
- <transition to="send rectify note"/>
- </start>
-
- <mail name="send rectify note"
- template="rectify-template"
- g="99,25,115,45">
- <transition to="end"/>
- </mail>
-
- <state name="end" g="240,25,98,45"/>
-
+<process name="TemplateMail" xmlns="http://jbpm.org/4.3/jpdl">
+
+ <start g="20,25,80,40">
+ <transition to="send rectify note"/>
+ </start>
+
+ <mail g="99,25,115,45" name="send rectify note" template="rectify-template">
+ <transition to="wait"/>
+ </mail>
+
+ <state g="240,25,98,45" name="wait"/>
+
</process>
\ No newline at end of file
Modified: jbpm4/trunk/modules/integration/console/src/main/java/org/jbpm/integration/console/ProcessEngineUtil.java
===================================================================
--- jbpm4/trunk/modules/integration/console/src/main/java/org/jbpm/integration/console/ProcessEngineUtil.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/integration/console/src/main/java/org/jbpm/integration/console/ProcessEngineUtil.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -1,6 +1,7 @@
package org.jbpm.integration.console;
import javax.naming.InitialContext;
+import javax.naming.NamingException;
import org.jbpm.api.Configuration;
import org.jbpm.api.ProcessEngine;
@@ -13,25 +14,27 @@
public final class ProcessEngineUtil {
private static ProcessEngine processEngine;
-
- private static final String PROCESS_ENGINE_JNDI_NAME = "java:/ProcessEngine";
+ private static final String PROCESS_ENGINE_JNDI_NAME = "java:ProcessEngine";
+
public static ProcessEngine retrieveProcessEngine() {
if (processEngine == null) {
synchronized (ProcessEngine.class) {
-
if (processEngine == null) {
-
try {
InitialContext ctx = new InitialContext();
- processEngine = (ProcessEngine) ctx.lookup(PROCESS_ENGINE_JNDI_NAME);
- } catch (Exception e) {
- // Fall back to default mechanism which build a procEngine from a default jbpm.cfg.xml
+ try {
+ processEngine = (ProcessEngine) ctx.lookup(PROCESS_ENGINE_JNDI_NAME);
+ }
+ finally {
+ ctx.close();
+ }
+ }
+ catch (NamingException e) {
+ // build a process engine from a default jbpm.cfg.xml
processEngine = Configuration.getProcessEngine();
}
-
}
-
}
}
return processEngine;
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/ant/JbpmDeployTask.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/ant/JbpmDeployTask.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/ant/JbpmDeployTask.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -23,9 +23,10 @@
import java.io.File;
import java.io.FileInputStream;
+import java.io.IOException;
+import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Iterator;
import java.util.List;
import java.util.zip.ZipInputStream;
@@ -42,10 +43,9 @@
*/
public class JbpmDeployTask extends MatchingTask {
- String jbpmCfg = null;
- File file = null;
- List fileSets = new ArrayList();
- boolean failOnError = true;
+ private String jbpmCfg;
+ private File file;
+ private List<FileSet> fileSets = new ArrayList<FileSet>();
public void execute() throws BuildException {
Thread currentThread = Thread.currentThread();
@@ -54,31 +54,30 @@
try {
// get the ProcessEngineImpl
ProcessEngine processEngine = AntHelper.getProcessEngine(jbpmCfg);
-
+
// if attribute process is set, deploy that process file
- if (file!=null) {
+ if (file != null) {
deployFile(processEngine, file);
}
-
+
// loop over all files that are specified in the filesets
- Iterator iter = fileSets.iterator();
- while (iter.hasNext()) {
- FileSet fileSet = (FileSet) iter.next();
+ for (FileSet fileSet : fileSets) {
DirectoryScanner dirScanner = fileSet.getDirectoryScanner(getProject());
File baseDir = dirScanner.getBasedir();
- String[] includedFiles = dirScanner.getIncludedFiles();
- List excludedFiles = Arrays.asList(dirScanner.getExcludedFiles());
- for (int i = 0; i < includedFiles.length; i++) {
- String fileName = includedFiles[i];
- if (!excludedFiles.contains(fileName)) {
+ String[] excludedFiles = dirScanner.getExcludedFiles();
+ // sort excluded files in preparation for binary search
+ Arrays.sort(excludedFiles);
+
+ for (String fileName : dirScanner.getIncludedFiles()) {
+ if (Arrays.binarySearch(excludedFiles, fileName) < 0) {
File file = new File(baseDir, fileName);
deployFile(processEngine, file);
}
}
}
-
- } finally {
+ }
+ finally {
currentThread.setContextClassLoader(originalClassLoader);
}
}
@@ -88,30 +87,32 @@
NewDeployment deployment = repositoryService.createDeployment();
deployment.setName(processFile.getName());
deployment.setTimestamp(System.currentTimeMillis());
-
- if (processFile.getName().endsWith(".xml")) {
- log("deploying process file "+processFile.getName());
+
+ String contentType = URLConnection.guessContentTypeFromName(processFile.getName());
+ if (contentType.contains("xml")) {
+ log("deploying process file " + processFile.getName());
deployment.addResourceFromFile(processFile);
-
- } else if (processFile.getName().endsWith("ar")) {
- log("deploying business archive "+processFile.getName());
+ }
+ else if (contentType.contains("zip")) {
+ log("deploying business archive " + processFile.getName());
try {
FileInputStream fileInputStream = new FileInputStream(processFile);
ZipInputStream zipInputStream = new ZipInputStream(fileInputStream);
deployment.addResourcesFromZipInputStream(zipInputStream);
- } catch (Exception e) {
- throw new BuildException("couldn't read business archive "+processFile, e);
}
-
- } else {
- throw new BuildException("unsupported extension: "+processFile+" Only .xml files and .*ar archives are supported");
+ catch (IOException e) {
+ throw new BuildException("failed to read process archive " + processFile, e);
+ }
}
-
+ else {
+ throw new BuildException("unsupported extension: " + processFile
+ + " Only .xml files and .*ar archives are supported");
+ }
deployment.deploy();
}
public void addFileset(FileSet fileSet) {
- this.fileSets.add(fileSet);
+ fileSets.add(fileSet);
}
public void setJbpmCfg(String jbpmCfg) {
this.jbpmCfg = jbpmCfg;
@@ -119,7 +120,4 @@
public void setFile(File file) {
this.file = file;
}
- public void setFailOnError(boolean failOnError) {
- this.failOnError = failOnError;
- }
}
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cal/CronExpression.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cal/CronExpression.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cal/CronExpression.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -5,7 +5,6 @@
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.SortedSet;
@@ -187,8 +186,8 @@
protected static final Integer ALL_SPEC = new Integer(ALL_SPEC_INT);
protected static final Integer NO_SPEC = new Integer(NO_SPEC_INT);
- protected static Map monthMap = new HashMap(20);
- protected static Map dayMap = new HashMap(60);
+ protected static Map<String, Integer> monthMap = new HashMap<String, Integer>(20);
+ protected static Map<String, Integer> dayMap = new HashMap<String, Integer>(60);
static {
monthMap.put("JAN", new Integer(0));
monthMap.put("FEB", new Integer(1));
@@ -212,21 +211,21 @@
dayMap.put("SAT", new Integer(7));
}
- private String cronExpression = null;
- private TimeZone timeZone = null;
- protected transient TreeSet seconds;
- protected transient TreeSet minutes;
- protected transient TreeSet hours;
- protected transient TreeSet daysOfMonth;
- protected transient TreeSet months;
- protected transient TreeSet daysOfWeek;
- protected transient TreeSet years;
+ private String cronExpression;
+ private TimeZone timeZone;
+ protected transient TreeSet<Integer> seconds;
+ protected transient TreeSet<Integer> minutes;
+ protected transient TreeSet<Integer> hours;
+ protected transient TreeSet<Integer> daysOfMonth;
+ protected transient TreeSet<Integer> months;
+ protected transient TreeSet<Integer> daysOfWeek;
+ protected transient TreeSet<Integer> years;
- protected transient boolean lastdayOfWeek = false;
- protected transient int nthdayOfWeek = 0;
- protected transient boolean lastdayOfMonth = false;
- protected transient boolean nearestWeekday = false;
- protected transient boolean expressionParsed = false;
+ protected transient boolean lastdayOfWeek;
+ protected transient int nthdayOfWeek;
+ protected transient boolean lastdayOfMonth;
+ protected transient boolean nearestWeekday;
+ protected transient boolean expressionParsed;
/**
* Constructs a new <CODE>CronExpression</CODE> based on the specified
@@ -377,27 +376,26 @@
expressionParsed = true;
try {
-
if (seconds == null) {
- seconds = new TreeSet();
+ seconds = new TreeSet<Integer>();
}
if (minutes == null) {
- minutes = new TreeSet();
+ minutes = new TreeSet<Integer>();
}
if (hours == null) {
- hours = new TreeSet();
+ hours = new TreeSet<Integer>();
}
if (daysOfMonth == null) {
- daysOfMonth = new TreeSet();
+ daysOfMonth = new TreeSet<Integer>();
}
if (months == null) {
- months = new TreeSet();
+ months = new TreeSet<Integer>();
}
if (daysOfWeek == null) {
- daysOfWeek = new TreeSet();
+ daysOfWeek = new TreeSet<Integer>();
}
if (years == null) {
- years = new TreeSet();
+ years = new TreeSet<Integer>();
}
int exprOn = SECOND;
@@ -527,7 +525,7 @@
i);
}
if (type == DAY_OF_WEEK && !lastdayOfMonth) {
- int val = ((Integer) daysOfMonth.last()).intValue();
+ int val = daysOfMonth.last().intValue();
if (val == NO_SPEC_INT) {
throw new ParseException(
"'?' can only be specfied for Day-of-Month -OR- Day-of-Week.",
@@ -637,7 +635,7 @@
} else {
throw new ParseException("'L' option is not valid here. (pos=" + i + ")", i);
}
- TreeSet set = getSet(type);
+ TreeSet<Integer> set = getSet(type);
set.add(new Integer(val));
i++;
return i;
@@ -649,7 +647,7 @@
} else {
throw new ParseException("'W' option is not valid here. (pos=" + i + ")", i);
}
- TreeSet set = getSet(type);
+ TreeSet<Integer> set = getSet(type);
set.add(new Integer(val));
i++;
return i;
@@ -671,7 +669,7 @@
i);
}
- TreeSet set = getSet(type);
+ TreeSet<Integer> set = getSet(type);
set.add(new Integer(val));
i++;
return i;
@@ -790,7 +788,7 @@
return summary.toString();
}
- protected String getExpressionSetSummary(java.util.Set set) {
+ protected String getExpressionSetSummary(java.util.Set<Integer> set) {
if (set.contains(NO_SPEC)) {
return "?";
@@ -801,10 +799,8 @@
StringBuilder summary = new StringBuilder();
- Iterator itr = set.iterator();
boolean first = true;
- while (itr.hasNext()) {
- Integer iVal = (Integer) itr.next();
+ for (Integer iVal : set) {
String val = iVal.toString();
if (!first) {
summary.append(",");
@@ -816,7 +812,7 @@
return summary.toString();
}
- protected String getExpressionSetSummary(java.util.List list) {
+ protected String getExpressionSetSummary(java.util.List<Integer> list) {
if (list.contains(NO_SPEC)) {
return "?";
@@ -827,10 +823,8 @@
StringBuilder summary = new StringBuilder();
- Iterator itr = list.iterator();
boolean first = true;
- while (itr.hasNext()) {
- Integer iVal = (Integer) itr.next();
+ for (Integer iVal : list) {
String val = iVal.toString();
if (!first) {
summary.append(",");
@@ -861,7 +855,7 @@
protected void addToSet(int val, int end, int incr, int type)
throws ParseException {
- TreeSet set = getSet(type);
+ TreeSet<Integer> set = getSet(type);
if (type == SECOND || type == MINUTE) {
if ((val < 0 || val > 59 || end > 59) && (val != ALL_SPEC_INT)) {
@@ -960,7 +954,7 @@
}
}
- protected TreeSet getSet(int type) {
+ protected TreeSet<Integer> getSet(int type) {
switch (type) {
case SECOND:
return seconds;
@@ -1006,7 +1000,7 @@
}
protected int getMonthNumber(String s) {
- Integer integer = (Integer) monthMap.get(s);
+ Integer integer = monthMap.get(s);
if (integer == null) {
return -1;
@@ -1016,7 +1010,7 @@
}
protected int getDayOfWeekNumber(String s) {
- Integer integer = (Integer) dayMap.get(s);
+ Integer integer = dayMap.get(s);
if (integer == null) {
return -1;
@@ -1052,7 +1046,7 @@
if(cl.get(Calendar.YEAR) > 2999) // prevent endless loop...
return null;
- SortedSet st = null;
+ SortedSet<Integer> st = null;
int t = 0;
int sec = cl.get(Calendar.SECOND);
@@ -1061,9 +1055,9 @@
// get second.................................................
st = seconds.tailSet(new Integer(sec));
if (st != null && st.size() != 0) {
- sec = ((Integer) st.first()).intValue();
+ sec = st.first().intValue();
} else {
- sec = ((Integer) seconds.first()).intValue();
+ sec = seconds.first().intValue();
min++;
cl.set(Calendar.MINUTE, min);
}
@@ -1077,9 +1071,9 @@
st = minutes.tailSet(new Integer(min));
if (st != null && st.size() != 0) {
t = min;
- min = ((Integer) st.first()).intValue();
+ min = st.first().intValue();
} else {
- min = ((Integer) minutes.first()).intValue();
+ min = minutes.first().intValue();
hr++;
}
if (min != t) {
@@ -1098,9 +1092,9 @@
st = hours.tailSet(new Integer(hr));
if (st != null && st.size() != 0) {
t = hr;
- hr = ((Integer) st.first()).intValue();
+ hr = st.first().intValue();
} else {
- hr = ((Integer) hours.first()).intValue();
+ hr = hours.first().intValue();
day++;
}
if (hr != t) {
@@ -1166,7 +1160,7 @@
}
} else if(nearestWeekday) {
t = day;
- day = ((Integer) daysOfMonth.first()).intValue();
+ day = daysOfMonth.first().intValue();
java.util.Calendar tcal = java.util.Calendar.getInstance();
tcal.set(Calendar.SECOND, 0);
@@ -1197,14 +1191,14 @@
tcal.set(Calendar.MONTH, mon - 1);
Date nTime = tcal.getTime();
if(nTime.before(afterTime)) {
- day = ((Integer) daysOfMonth.first()).intValue();;
+ day = daysOfMonth.first().intValue();;
mon++;
}
} else if (st != null && st.size() != 0) {
t = day;
- day = ((Integer) st.first()).intValue();
+ day = st.first().intValue();
} else {
- day = ((Integer) daysOfMonth.first()).intValue();
+ day = daysOfMonth.first().intValue();
mon++;
}
@@ -1221,7 +1215,7 @@
} else if (dayOfWSpec && !dayOfMSpec) { // get day by day of week rule
if (lastdayOfWeek) { // are we looking for the last XXX day of
// the month?
- int dow = ((Integer) daysOfWeek.first()).intValue(); // desired
+ int dow = daysOfWeek.first().intValue(); // desired
// d-o-w
int cDow = cl.get(Calendar.DAY_OF_WEEK); // current d-o-w
int daysToAdd = 0;
@@ -1245,7 +1239,7 @@
continue;
}
- // find date of last occurance of this day in this month...
+ // find date of last occurrence of this day in this month...
while ((day + daysToAdd + 7) <= lDay) {
daysToAdd += 7;
}
@@ -1264,7 +1258,7 @@
} else if (nthdayOfWeek != 0) {
// are we looking for the Nth XXX day in the month?
- int dow = ((Integer) daysOfWeek.first()).intValue(); // desired
+ int dow = daysOfWeek.first().intValue(); // desired
// d-o-w
int cDow = cl.get(Calendar.DAY_OF_WEEK); // current d-o-w
int daysToAdd = 0;
@@ -1308,11 +1302,11 @@
}
} else {
int cDow = cl.get(Calendar.DAY_OF_WEEK); // current d-o-w
- int dow = ((Integer) daysOfWeek.first()).intValue(); // desired
+ int dow = daysOfWeek.first().intValue(); // desired
// d-o-w
st = daysOfWeek.tailSet(new Integer(cDow));
if (st != null && st.size() > 0) {
- dow = ((Integer) st.first()).intValue();
+ dow = st.first().intValue();
}
int daysToAdd = 0;
@@ -1334,7 +1328,7 @@
cl.set(Calendar.MONTH, mon);
// no '- 1' here because we are promoting the month
continue;
- } else if (daysToAdd > 0) { // are we swithing days?
+ } else if (daysToAdd > 0) { // are we switching days?
cl.set(Calendar.SECOND, 0);
cl.set(Calendar.MINUTE, 0);
cl.set(Calendar.HOUR_OF_DAY, 0);
@@ -1368,9 +1362,9 @@
st = months.tailSet(new Integer(mon));
if (st != null && st.size() != 0) {
t = mon;
- mon = ((Integer) st.first()).intValue();
+ mon = st.first().intValue();
} else {
- mon = ((Integer) months.first()).intValue();
+ mon = months.first().intValue();
year++;
}
if (mon != t) {
@@ -1395,7 +1389,7 @@
st = years.tailSet(new Integer(year));
if (st != null && st.size() != 0) {
t = year;
- year = ((Integer) st.first()).intValue();
+ year = st.first().intValue();
} else {
return null; // ran out of years...
}
@@ -1508,11 +1502,10 @@
throw new IncompatibleClassChangeError("Not Cloneable.");
}
return copy;
- }
-}
+ }
-class ValueSet {
- public int value;
-
- public int pos;
+ static class ValueSet {
+ int value;
+ int pos;
+ }
}
\ No newline at end of file
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cal/Duration.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cal/Duration.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cal/Duration.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -22,15 +22,12 @@
package org.jbpm.pvm.internal.cal;
import java.io.Serializable;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.jbpm.api.JbpmException;
@@ -241,45 +238,45 @@
fieldSetter.set(this, quantity);
}
- private interface FieldSetter {
+ interface FieldSetter {
void set(Duration duration, int quantity);
}
- private static class MillisSetter implements FieldSetter {
+ static class MillisSetter implements FieldSetter {
public void set(Duration duration, int quantity) {
duration.millis = quantity;
}
}
- private static class SecondSetter implements FieldSetter {
+ static class SecondSetter implements FieldSetter {
public void set(Duration duration, int quantity) {
duration.seconds = quantity;
}
}
- private static class MinuteSetter implements FieldSetter {
+ static class MinuteSetter implements FieldSetter {
public void set(Duration duration, int quantity) {
duration.minutes = quantity;
}
}
- private static class HourSetter implements FieldSetter {
+ static class HourSetter implements FieldSetter {
public void set(Duration duration, int quantity) {
duration.hours = quantity;
}
}
- private static class DaySetter implements FieldSetter {
+ static class DaySetter implements FieldSetter {
public void set(Duration duration, int quantity) {
duration.days = quantity;
}
}
- private static class WeekSetter implements FieldSetter {
+ static class WeekSetter implements FieldSetter {
public void set(Duration duration, int quantity) {
duration.weeks = quantity;
}
}
- private static class MonthSetter implements FieldSetter {
+ static class MonthSetter implements FieldSetter {
public void set(Duration duration, int quantity) {
duration.months = quantity;
}
}
- private static class YearSetter implements FieldSetter {
+ static class YearSetter implements FieldSetter {
public void set(Duration duration, int quantity) {
duration.years = quantity;
}
@@ -288,7 +285,7 @@
private static final Map<String, FieldSetter> fieldSetters = new HashMap<String, FieldSetter>();
static {
FieldSetter fieldSetter = new MillisSetter();
- fieldSetters.put("milli", fieldSetter);
+ fieldSetters.put("ms", fieldSetter);
fieldSetters.put("millis", fieldSetter);
fieldSetters.put("millisecond", fieldSetter);
fieldSetters.put("milliseconds", fieldSetter);
@@ -333,42 +330,34 @@
return days;
}
-
public int getHours() {
return hours;
}
-
public boolean isBusinessTime() {
return isBusinessTime;
}
-
public int getMillis() {
return millis;
}
-
public int getMinutes() {
return minutes;
}
-
public int getMonths() {
return months;
}
-
public int getSeconds() {
return seconds;
}
-
public int getWeeks() {
return weeks;
}
-
public int getYears() {
return years;
}
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cmd/CompositeCmd.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cmd/CompositeCmd.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cmd/CompositeCmd.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -27,7 +27,6 @@
import org.jbpm.api.cmd.Command;
import org.jbpm.api.cmd.Environment;
-
/** container for executing multiple commands in one transaction.
*
* @author Tom Baeyens
@@ -39,7 +38,7 @@
protected List<Command<?>> commands = new ArrayList<Command<?>>();
public Void execute(Environment environment) throws Exception {
- for (Command command: commands) {
+ for (Command<?> command: commands) {
command.execute(environment);
}
return null;
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cmd/CreateDeploymentQueryCmd.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cmd/CreateDeploymentQueryCmd.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cmd/CreateDeploymentQueryCmd.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -24,10 +24,8 @@
import org.jbpm.api.cmd.Command;
import org.jbpm.api.cmd.Environment;
import org.jbpm.pvm.internal.query.DeploymentQueryImpl;
-import org.jbpm.pvm.internal.query.JobQueryImpl;
import org.jbpm.pvm.internal.session.DbSession;
-
/**
* @author Tom Baeyens
*/
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cmd/CreateHistoryDetailQueryCmd.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cmd/CreateHistoryDetailQueryCmd.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cmd/CreateHistoryDetailQueryCmd.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -24,10 +24,8 @@
import org.jbpm.api.cmd.Command;
import org.jbpm.api.cmd.Environment;
import org.jbpm.pvm.internal.query.HistoryDetailQueryImpl;
-import org.jbpm.pvm.internal.query.HistoryProcessInstanceQueryImpl;
import org.jbpm.pvm.internal.session.DbSession;
-
/**
* @author Tom Baeyens
*/
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cmd/DeleteDeploymentCmd.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cmd/DeleteDeploymentCmd.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cmd/DeleteDeploymentCmd.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -24,19 +24,17 @@
import java.util.List;
import org.hibernate.Session;
+
import org.jbpm.api.JbpmException;
import org.jbpm.api.ProcessDefinition;
-import org.jbpm.api.ProcessInstance;
import org.jbpm.api.cmd.Command;
import org.jbpm.api.cmd.Environment;
import org.jbpm.internal.log.Log;
-import org.jbpm.pvm.internal.model.ExecutionImpl;
import org.jbpm.pvm.internal.repository.DeploymentImpl;
import org.jbpm.pvm.internal.repository.RepositoryCache;
import org.jbpm.pvm.internal.session.DbSession;
import org.jbpm.pvm.internal.session.RepositorySession;
-
/**
* @author Tom Baeyens
*/
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cmd/DeleteJobCmd.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cmd/DeleteJobCmd.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cmd/DeleteJobCmd.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -26,7 +26,6 @@
import org.jbpm.pvm.internal.job.JobImpl;
import org.jbpm.pvm.internal.session.DbSession;
-
/**
* @author Joram Barrez
*/
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cmd/ExecuteJobCmd.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cmd/ExecuteJobCmd.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cmd/ExecuteJobCmd.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -34,8 +34,6 @@
import org.jbpm.pvm.internal.session.DbSession;
import org.jbpm.pvm.internal.tx.Transaction;
-
-
/**
* @author Tom Baeyens
*/
@@ -64,7 +62,7 @@
if (dbSession==null) {
throw new JbpmException("no db-session configured");
}
- JobImpl<?> job = dbSession.get(JobImpl.class, jobDbid);
+ JobImpl job = dbSession.get(JobImpl.class, jobDbid);
// in case of decision jobs, the job might have been deleted
// before we execute it (they are in a list)
@@ -73,8 +71,11 @@
environment.setContext(jobContext);
try {
log.debug("executing job "+job+"...");
- job.execute(environment);
+ Boolean deleteJob = job.execute(environment);
log.debug("executed job "+job);
+ if (deleteJob) {
+ dbSession.delete(job);
+ }
// if this job is locked too long, it could be unlocked by the lockmonitor and
// executed by another thread.
@@ -104,7 +105,7 @@
* Transaction.EVENT_AFTERCOMPLETION (after the job locks of the current transaction are
* released). Then the command will update the job with the exception details in a separate
* transaction. */
- protected void handleJobExecutionException(Environment environment, JobImpl<?> job, Exception exception) {
+ protected void handleJobExecutionException(Environment environment, JobImpl job, Exception exception) {
Transaction transaction = environment.get(Transaction.class);
CommandService commandService = (CommandService) environment.get(CommandService.NAME_NEW_TX_REQUIRED_COMMAND_SERVICE);
JobExceptionHandler jobExceptionHandler = new JobExceptionHandler(job.getDbid(), exception, commandService);
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cmd/GetParticipantsCmd.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cmd/GetParticipantsCmd.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cmd/GetParticipantsCmd.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -23,14 +23,16 @@
import java.util.List;
-import org.hibernate.Query;
+import org.hibernate.Criteria;
import org.hibernate.Session;
+import org.hibernate.criterion.Restrictions;
+
import org.jbpm.api.JbpmException;
import org.jbpm.api.cmd.Environment;
import org.jbpm.api.task.Participation;
import org.jbpm.pvm.internal.task.ParticipationImpl;
+import org.jbpm.pvm.internal.util.CollectionUtil;
-
/**
* @author Tom Baeyens
*/
@@ -50,25 +52,17 @@
}
public List<Participation> execute(Environment environment) throws Exception {
- StringBuilder hql = new StringBuilder();
- hql.append("select role from ");
- hql.append(ParticipationImpl.class.getName());
- hql.append(" as role where ");
+ Criteria criteria = environment.get(Session.class).createCriteria(ParticipationImpl.class);
if (taskId!=null) {
- hql.append(" role.task.dbid = "+taskId+" ");
-
+ criteria.add(Restrictions.eq("task.dbid", Long.parseLong(taskId)));
} else if (swimlaneId!=null) {
- hql.append(" role.swimlane.dbid = "+swimlaneId+" ");
-
+ criteria.add(Restrictions.eq("swimlane.dbid", Long.parseLong(swimlaneId)));
} else {
throw new JbpmException("no task nor swimlane specified");
}
- Session session = environment.get(Session.class);
- Query query = session.createQuery(hql.toString());
-
- List<Participation> participations = query.list();
- return participations;
+ List<?> participations = criteria.list();
+ return CollectionUtil.checkList(participations, Participation.class);
}
}
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cmd/GetStartActivityNamesCmd.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cmd/GetStartActivityNamesCmd.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cmd/GetStartActivityNamesCmd.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -26,11 +26,10 @@
import org.jbpm.api.cmd.Command;
import org.jbpm.api.cmd.Environment;
-import org.jbpm.pvm.internal.model.ActivityImpl;
+import org.jbpm.api.model.Activity;
import org.jbpm.pvm.internal.model.ProcessDefinitionImpl;
import org.jbpm.pvm.internal.session.RepositorySession;
-
/**
* @author Tom Baeyens
*/
@@ -50,7 +49,7 @@
RepositorySession repositorySession = environment.get(RepositorySession.class);
ProcessDefinitionImpl processDefinition = repositorySession.findProcessDefinitionById(processDefinitionId);
- for (ActivityImpl activity: (List<ActivityImpl>) processDefinition.getActivities()) {
+ for (Activity activity: processDefinition.getActivities()) {
if (activity.getIncomingTransitions().isEmpty()) {
activityNames.add(activity.getName());
}
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cmd/GetSubTasksCmd.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cmd/GetSubTasksCmd.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cmd/GetSubTasksCmd.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -23,13 +23,14 @@
import java.util.List;
-import org.hibernate.Query;
import org.hibernate.Session;
+import org.hibernate.criterion.Restrictions;
+
import org.jbpm.api.cmd.Environment;
import org.jbpm.api.task.Task;
import org.jbpm.pvm.internal.task.TaskImpl;
+import org.jbpm.pvm.internal.util.CollectionUtil;
-
/**
* @author Tom Baeyens
*/
@@ -44,14 +45,10 @@
}
public List<Task> execute(Environment environment) throws Exception {
- Session session = environment.get(Session.class);
-
- Query query = session.createQuery(
- "select task " +
- "from "+TaskImpl.class.getName()+" as task " +
- "where task.superTask.dbid = "+parentTaskId+" "
- );
-
- return query.list();
+ List<?> tasks = environment.get(Session.class).createCriteria(TaskImpl.class)
+ .createAlias("superTask", "super")
+ .add(Restrictions.eq("super.dbid", Long.parseLong(parentTaskId)))
+ .list();
+ return CollectionUtil.checkList(tasks, Task.class);
}
}
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cmd/GetTaskCommentsCmd.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cmd/GetTaskCommentsCmd.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cmd/GetTaskCommentsCmd.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -22,16 +22,12 @@
package org.jbpm.pvm.internal.cmd;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.List;
import org.jbpm.api.cmd.Environment;
import org.jbpm.api.history.HistoryComment;
-import org.jbpm.pvm.internal.history.model.HistoryDetailImpl;
-import org.jbpm.pvm.internal.history.model.HistoryTaskImpl;
import org.jbpm.pvm.internal.session.DbSession;
-
/**
* @author Tom Baeyens
*/
@@ -53,7 +49,7 @@
return comments;
}
- protected void forceInitializationAndClean(List<HistoryComment> comments) {
+ protected void forceInitializationAndClean(List<? extends HistoryComment> comments) {
if (comments!=null) {
comments.size();
List<HistoryComment> copy = new ArrayList<HistoryComment>(comments);
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cmd/GetTaskVariableNamesCmd.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cmd/GetTaskVariableNamesCmd.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cmd/GetTaskVariableNamesCmd.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -25,11 +25,9 @@
import org.jbpm.api.JbpmException;
import org.jbpm.api.cmd.Environment;
-import org.jbpm.pvm.internal.client.ClientExecution;
import org.jbpm.pvm.internal.session.DbSession;
import org.jbpm.pvm.internal.task.TaskImpl;
-
/**
* @author Tom Baeyens
*/
@@ -37,7 +35,7 @@
private static final long serialVersionUID = 1L;
- String taskId;
+ private String taskId;
public GetTaskVariableNamesCmd(String taskId) {
if (taskId==null) {
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JstlFunction.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JstlFunction.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JstlFunction.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -168,8 +168,8 @@
if (obj == null) {
return 0;
}
- if (obj instanceof Collection) {
- return ((Collection) obj).size();
+ if (obj instanceof Collection<?>) {
+ return ((Collection<?>) obj).size();
}
if (obj.getClass().isArray()) {
return Array.getLength(obj);
@@ -177,23 +177,23 @@
if (obj instanceof String) {
return ((String) obj).length();
}
- if (obj instanceof Map) {
- return ((Map) obj).size();
+ if (obj instanceof Map<?, ?>) {
+ return ((Map<?, ?>) obj).size();
}
- if (obj instanceof Enumeration) {
- Enumeration e = (Enumeration) obj;
+ if (obj instanceof Iterator<?>) {
+ Iterator<?> i = (Iterator<?>) obj;
int count = 0;
- while (e.hasMoreElements()) {
- e.nextElement();
+ while (i.hasNext()) {
+ i.next();
count++;
}
return count;
}
- if (obj instanceof Iterator) {
- Iterator i = (Iterator) obj;
+ if (obj instanceof Enumeration<?>) {
+ Enumeration<?> e = (Enumeration<?>) obj;
int count = 0;
- while (i.hasNext()) {
- i.next();
+ while (e.hasMoreElements()) {
+ e.nextElement();
count++;
}
return count;
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/env/EnvironmentFactory.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/env/EnvironmentFactory.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/env/EnvironmentFactory.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -23,7 +23,6 @@
import java.io.InputStream;
import java.io.Serializable;
-import java.util.List;
import org.xml.sax.InputSource;
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/env/EnvironmentImpl.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/env/EnvironmentImpl.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/env/EnvironmentImpl.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -127,6 +127,8 @@
*/
public abstract class EnvironmentImpl implements Serializable, Environment {
+ private static final long serialVersionUID = 1L;
+
/**
* searches a named object in all the contexts in the default search order.
* @return the object if it exists in the environment, <code>null</code> if there is no object with the given name in the environment.
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/env/ExecutionContext.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/env/ExecutionContext.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/env/ExecutionContext.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -24,10 +24,8 @@
import java.util.HashSet;
import java.util.Set;
-import org.jbpm.api.Execution;
import org.jbpm.api.JbpmException;
import org.jbpm.pvm.internal.model.ExecutionImpl;
-import org.jbpm.pvm.internal.model.ScopeInstanceImpl;
public class ExecutionContext implements Context {
@@ -70,8 +68,8 @@
}
public <T> T get(Class<T> type) {
- if (Execution.class.isAssignableFrom(type.getClass())) {
- return (T) execution;
+ if (type.isAssignableFrom(ExecutionImpl.class)) {
+ return type.cast(execution);
}
return null;
}
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/env/JobContext.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/env/JobContext.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/env/JobContext.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -25,7 +25,6 @@
import java.util.HashSet;
import java.util.Set;
-import org.jbpm.api.job.Job;
import org.jbpm.pvm.internal.job.JobImpl;
public class JobContext implements Context {
@@ -39,9 +38,9 @@
return keys;
}
- JobImpl<?> job;
+ JobImpl job;
- public JobContext(JobImpl<?> job) {
+ public JobContext(JobImpl job) {
this.job = job;
}
@@ -65,8 +64,8 @@
}
public <T> T get(Class<T> type) {
- if (Job.class.isAssignableFrom(type)) {
- return (T) job;
+ if (type.isAssignableFrom(JobImpl.class)) {
+ return type.cast(job);
}
return null;
}
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/env/TaskContext.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/env/TaskContext.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/env/TaskContext.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -25,10 +25,8 @@
import java.util.HashSet;
import java.util.Set;
-import org.jbpm.api.job.Job;
import org.jbpm.pvm.internal.task.TaskImpl;
-
/**
* @author Tom Baeyens
*/
@@ -36,15 +34,15 @@
private static final String KEY_TASK = "task";
- static final Set<String> keys = Collections.unmodifiableSet(getKeys());
+ private static final Set<String> keys = Collections.unmodifiableSet(getKeys());
- static Set<String> getKeys() {
+ private static Set<String> getKeys() {
Set<String> keys = new HashSet<String>();
keys.add(KEY_TASK);
return keys;
}
- TaskImpl task;
+ private TaskImpl task;
public TaskContext(TaskImpl task) {
this.task = task;
@@ -71,8 +69,8 @@
}
public <T> T get(Class<T> type) {
- if (Job.class.isAssignableFrom(type)) {
- return (T) task;
+ if (type.isAssignableFrom(TaskImpl.class)) {
+ return type.cast(task);
}
return null;
}
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/hibernate/ConverterType.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/hibernate/ConverterType.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/hibernate/ConverterType.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -71,7 +71,7 @@
return "converter";
}
- public Class getReturnedClass() {
+ public Class<?> getReturnedClass() {
return Converter.class;
}
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/hibernate/DbSessionImpl.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/hibernate/DbSessionImpl.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/hibernate/DbSessionImpl.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -26,14 +26,14 @@
import java.util.List;
import org.hibernate.LockMode;
-import org.hibernate.Query;
import org.hibernate.Session;
+import org.hibernate.criterion.Order;
+import org.hibernate.criterion.Restrictions;
import org.hibernate.metadata.ClassMetadata;
import org.jbpm.api.Execution;
import org.jbpm.api.JbpmException;
import org.jbpm.api.history.HistoryComment;
-import org.jbpm.api.history.HistoryProcessInstance;
import org.jbpm.api.task.Task;
import org.jbpm.internal.log.Log;
import org.jbpm.pvm.internal.client.ClientExecution;
@@ -54,12 +54,13 @@
import org.jbpm.pvm.internal.session.DbSession;
import org.jbpm.pvm.internal.task.TaskImpl;
import org.jbpm.pvm.internal.util.Clock;
+import org.jbpm.pvm.internal.util.CollectionUtil;
/**
* @author Tom Baeyens
*/
public class DbSessionImpl implements DbSession {
-
+
private static Log log = Log.getLog(DbSessionImpl.class.getName());
protected Session session;
@@ -109,104 +110,93 @@
}
public void deleteProcessDefinitionHistory(String processDefinitionId) {
- List<HistoryProcessInstanceImpl> historyProcessInstances =
- session.createQuery(
- "select hpi " +
- "from "+HistoryProcessInstanceImpl.class.getName()+" hpi "+
- "where hpi.processDefinitionId = :processDefinitionId "
- )
- .setString("processDefinitionId", processDefinitionId)
- .list();
-
- for (HistoryProcessInstanceImpl hpi: historyProcessInstances) {
+ List<?> historyProcessInstances = session.createCriteria(HistoryProcessInstanceImpl.class)
+ .add(Restrictions.eq("processDefinitionId", processDefinitionId))
+ .list();
+
+ for (Object hpi : historyProcessInstances) {
session.delete(hpi);
}
}
public boolean isHistoryEnabled() {
- ClassMetadata historyHibernateMetadata = session.getSessionFactory().getClassMetadata(HistoryProcessInstanceImpl.class);
- return historyHibernateMetadata!=null;
+ ClassMetadata historyHibernateMetadata = session.getSessionFactory()
+ .getClassMetadata(HistoryProcessInstanceImpl.class);
+ return historyHibernateMetadata != null;
}
-
// process execution queries ////////////////////////////////////////////////
public ClientExecution findExecutionById(String executionId) {
- // query definition can be found at the bottom of resource jbpm.pvm.execution.hbm.xml
- Query query = session.getNamedQuery("findExecutionById");
- query.setString("id", executionId);
- query.setMaxResults(1);
- return (ClientExecution) query.uniqueResult();
+ // query definition can be found at the bottom of resource jbpm.execution.hbm.xml
+ return (ClientExecution) session.getNamedQuery("findExecutionById")
+ .setString("id", executionId)
+ .setMaxResults(1)
+ .uniqueResult();
}
public ClientExecution findProcessInstanceById(String processInstanceId) {
- // query definition can be found at the bottom of resource jbpm.pvm.execution.hbm.xml
- Query query = session.getNamedQuery("findProcessInstanceById");
- query.setString("processInstanceId", processInstanceId);
- query.setMaxResults(1);
- return (ClientExecution) query.uniqueResult();
+ // query definition can be found at the bottom of resource jbpm.execution.hbm.xml
+ return (ClientExecution) session.getNamedQuery("findProcessInstanceById")
+ .setString("processInstanceId", processInstanceId)
+ .setMaxResults(1)
+ .uniqueResult();
}
public ClientExecution findProcessInstanceByIdIgnoreSuspended(String processInstanceId) {
- // query definition can be found at the bottom of resource jbpm.pvm.execution.hbm.xml
- Query query = session.getNamedQuery("findProcessInstanceByIdIgnoreSuspended");
- query.setString("processInstanceId", processInstanceId);
- query.setMaxResults(1);
- return (ClientExecution) query.uniqueResult();
+ // query definition can be found at the bottom of resource jbpm.execution.hbm.xml
+ return (ClientExecution) session.getNamedQuery("findProcessInstanceByIdIgnoreSuspended")
+ .setString("processInstanceId", processInstanceId)
+ .setMaxResults(1)
+ .uniqueResult();
}
-
+
public List<String> findProcessInstanceIds(String processDefinitionId) {
- // query definition can be found at the bottom of resource jbpm.pvm.job.hbm.xml
- Query query = session.createQuery(
- "select processInstance.id " +
- "from org.jbpm.pvm.internal.model.ExecutionImpl as processInstance " +
- "where processInstance.processDefinitionId = :processDefinitionId " +
- " and processInstance.parent is null"
- );
- query.setString("processDefinitionId", processDefinitionId);
- return query.list();
+ // query definition can be found at the bottom of resource jbpm.execution.hbm.xml
+ List<?> processInstanceIds = session.getNamedQuery("findProcessInstanceIds")
+ .setString("processDefinitionId", processDefinitionId)
+ .list();
+ return CollectionUtil.checkList(processInstanceIds, String.class);
}
-
+
public void deleteProcessInstance(String processInstanceId) {
deleteProcessInstance(processInstanceId, true);
}
public void deleteProcessInstance(String processInstanceId, boolean deleteHistory) {
- if (processInstanceId==null) {
+ if (processInstanceId == null) {
throw new JbpmException("processInstanceId is null");
}
-
- // if history should be deleted
- if ( deleteHistory
- && (isHistoryEnabled())
- ) {
- // try to get the history
+
+ // if history should be deleted
+ if (deleteHistory && (isHistoryEnabled())) {
+ // try to get the history
HistoryProcessInstanceImpl historyProcessInstance = findHistoryProcessInstanceById(processInstanceId);
-
+
// if there is a history process instance in the db
- if (historyProcessInstance!=null) {
+ if (historyProcessInstance != null) {
if (log.isDebugEnabled()) {
- log.debug("deleting history process instance "+processInstanceId);
+ log.debug("deleting history process instance " + processInstanceId);
}
session.delete(historyProcessInstance);
}
}
-
+
ExecutionImpl processInstance = (ExecutionImpl) findProcessInstanceByIdIgnoreSuspended(processInstanceId);
- if (processInstance!=null) {
+ if (processInstance != null) {
deleteSubProcesses(processInstance, deleteHistory);
-
+
// delete remaining tasks for this process instance
List<TaskImpl> tasks = findTasks(processInstanceId);
- for (TaskImpl task: tasks) {
+ for (TaskImpl task : tasks) {
session.delete(task);
}
// delete remaining jobs for this process instance
JobImpl currentJob = EnvironmentImpl.getFromCurrent(JobImpl.class, false);
List<JobImpl> jobs = findJobs(processInstanceId);
- for (JobImpl job: jobs) {
- if (job!=currentJob){
+ for (JobImpl job : jobs) {
+ if (job != currentJob) {
session.delete(job);
}
}
@@ -215,109 +205,86 @@
log.debug("Deleting process instance " + processInstanceId);
}
session.delete(processInstance);
-
- } else {
- throw new JbpmException("Can't delete processInstance " + processInstanceId
- + ": no processInstance found for the given id");
}
+ else {
+ throw new JbpmException("Can't delete processInstance " + processInstanceId
+ + ": no processInstance found for the given id");
+ }
}
private void deleteSubProcesses(ExecutionImpl execution, boolean deleteHistory) {
ExecutionImpl subProcessInstance = execution.getSubProcessInstance();
- if (subProcessInstance!=null) {
+ if (subProcessInstance != null) {
subProcessInstance.setSuperProcessExecution(null);
execution.setSubProcessInstance(null);
deleteProcessInstance(subProcessInstance.getId(), deleteHistory);
}
Collection<ExecutionImpl> childExecutions = execution.getExecutions();
- if (childExecutions!=null) {
- for (ExecutionImpl childExecution: childExecutions) {
+ if (childExecutions != null) {
+ for (ExecutionImpl childExecution : childExecutions) {
deleteSubProcesses(childExecution, deleteHistory);
}
}
}
public HistoryProcessInstanceImpl findHistoryProcessInstanceById(String processInstanceId) {
- return (HistoryProcessInstanceImpl) session
- .createQuery(
- "select hpi " +
- "from "+HistoryProcessInstance.class.getName()+" as hpi " +
- "where hpi.processInstanceId = '"+processInstanceId+"'"
- ).uniqueResult();
+ return (HistoryProcessInstanceImpl) session.createCriteria(HistoryProcessInstanceImpl.class)
+ .add(Restrictions.eq("processInstanceId", processInstanceId))
+ .uniqueResult();
}
List<TaskImpl> findTasks(String processInstanceId) {
- Query query = session.createQuery(
- "select task " +
- "from "+TaskImpl.class.getName()+" as task " +
- "where task.processInstance.id = :processInstanceId"
- );
- query.setString("processInstanceId", processInstanceId);
- return query.list();
+ List<?> tasks = session.createCriteria(TaskImpl.class)
+ .createAlias("processInstance", "pi")
+ .add(Restrictions.eq("pi.id", processInstanceId))
+ .list();
+ return CollectionUtil.checkList(tasks, TaskImpl.class);
}
List<JobImpl> findJobs(String processInstanceId) {
- Query query = session.createQuery(
- "select job " +
- "from "+JobImpl.class.getName()+" as job " +
- "where job.processInstance.id = :processInstanceId"
- );
- query.setString("processInstanceId", processInstanceId);
- return query.list();
+ List<?> jobs = session.createCriteria(JobImpl.class)
+ .createAlias("processInstance", "pi")
+ .add(Restrictions.eq("pi.id", processInstanceId))
+ .list();
+ return CollectionUtil.checkList(jobs, JobImpl.class);
}
-
+
public void cascadeExecutionSuspend(ExecutionImpl execution) {
// cascade suspend to jobs
- Query query = session.createQuery(
- "select job " +
- "from "+JobImpl.class.getName()+" as job " +
- "where job.execution = :execution " +
- " and job.state != '"+JobImpl.STATE_SUSPENDED+"' "
- );
- query.setEntity("execution", execution);
- List<JobImpl> jobs = query.list();
- for (JobImpl job: jobs) {
+ List<?> jobs = session.createCriteria(JobImpl.class)
+ .add(Restrictions.eq("execution", execution))
+ .add(Restrictions.ne("state", JobImpl.STATE_SUSPENDED))
+ .list();
+ for (JobImpl job : CollectionUtil.checkList(jobs, JobImpl.class)) {
job.suspend();
}
// cascade suspend to tasks
- query = session.createQuery(
- "select task " +
- "from "+TaskImpl.class.getName()+" as task " +
- "where task.execution = :execution " +
- " and task.state != '"+Task.STATE_SUSPENDED+"' "
- );
- query.setEntity("execution", execution);
- List<TaskImpl> tasks = query.list();
- for (TaskImpl task: tasks) {
+ List<?> tasks = session.createCriteria(TaskImpl.class)
+ .add(Restrictions.eq("execution", execution))
+ .add(Restrictions.ne("state", Task.STATE_SUSPENDED))
+ .list();
+ for (TaskImpl task : CollectionUtil.checkList(tasks, TaskImpl.class)) {
task.suspend();
}
}
public void cascadeExecutionResume(ExecutionImpl execution) {
- // cascade suspend to jobs
- Query query = session.createQuery(
- "select job " +
- "from "+JobImpl.class.getName()+" as job " +
- "where job.execution = :execution " +
- " and job.state = '"+Task.STATE_SUSPENDED+"' "
- );
- query.setEntity("execution", execution);
- List<JobImpl> jobs = query.list();
- for (JobImpl job: jobs) {
+ // cascade resume to jobs
+ List<?> jobs = session.createCriteria(JobImpl.class)
+ .add(Restrictions.eq("execution", execution))
+ .add(Restrictions.eq("state", JobImpl.STATE_SUSPENDED))
+ .list();
+ for (JobImpl job : CollectionUtil.checkList(jobs, JobImpl.class)) {
job.resume();
}
- // cascade suspend to tasks
- query = session.createQuery(
- "select task " +
- "from "+TaskImpl.class.getName()+" as task " +
- "where task.execution = :execution " +
- " and task.state = '"+Task.STATE_SUSPENDED+"' "
- );
- query.setEntity("execution", execution);
- List<TaskImpl> tasks = query.list();
- for (TaskImpl task: tasks) {
+ // cascade resume to tasks
+ List<?> tasks = session.createCriteria(TaskImpl.class)
+ .add(Restrictions.eq("execution", execution))
+ .add(Restrictions.eq("state", Task.STATE_SUSPENDED))
+ .list();
+ for (TaskImpl task : CollectionUtil.checkList(tasks, TaskImpl.class)) {
task.resume();
}
}
@@ -340,45 +307,40 @@
return (TaskImpl) session.get(TaskImpl.class, taskDbid);
}
-
public TaskImpl findTaskByExecution(Execution execution) {
- Query query = session.createQuery(
- "select task " +
- "from "+TaskImpl.class.getName()+" as task " +
- "where task.execution = :execution"
- );
- query.setEntity("execution", execution);
- return (TaskImpl) query.uniqueResult();
+ return (TaskImpl) session.createCriteria(TaskImpl.class)
+ .add(Restrictions.eq("execution", execution))
+ .uniqueResult();
}
-
- public JobImpl<?> findFirstAcquirableJob() {
- Query query = session.getNamedQuery("findFirstAcquirableJob");
- query.setTimestamp("now", Clock.getTime());
- query.setMaxResults(1);
- return (JobImpl<?>) query.uniqueResult();
+
+ public JobImpl findFirstAcquirableJob() {
+ return (JobImpl) session.getNamedQuery("findFirstAcquirableJob")
+ .setTimestamp("now", Clock.getTime())
+ .setMaxResults(1)
+ .uniqueResult();
}
- public List<JobImpl<?>> findExclusiveJobs(Execution processInstance) {
- Query query = session.getNamedQuery("findExclusiveJobs");
- query.setTimestamp("now", Clock.getTime());
- query.setEntity("processInstance", processInstance);
- return query.list();
+ public List<JobImpl> findExclusiveJobs(Execution processInstance) {
+ List<?> exclusiveJobs = session.getNamedQuery("findExclusiveJobs")
+ .setTimestamp("now", Clock.getTime())
+ .setEntity("processInstance", processInstance)
+ .list();
+ return CollectionUtil.checkList(exclusiveJobs, JobImpl.class);
}
- public JobImpl<?> findFirstDueJob() {
- Query query = session.getNamedQuery("findFirstDueJob");
- query.setMaxResults(1);
- return (JobImpl<?>) query.uniqueResult();
+ public JobImpl findFirstDueJob() {
+ return (JobImpl) session.getNamedQuery("findFirstDueJob")
+ .setMaxResults(1)
+ .uniqueResult();
}
-
+
public List<StartProcessTimer> findStartProcessTimers(String processDefinitionName) {
- Query query = session.createQuery(
- "select spt from " + StartProcessTimer.class.getName() + " as spt " +
- "where spt.signalName = :procDefName");
- query.setString("procDefName", processDefinitionName);
- return query.list();
+ List<?> timers = session.createCriteria(StartProcessTimer.class)
+ .add(Restrictions.eq("signalName", processDefinitionName))
+ .list();
+ return CollectionUtil.checkList(timers, StartProcessTimer.class);
}
-
+
public ProcessInstanceQueryImpl createProcessInstanceQuery() {
return new ProcessInstanceQueryImpl();
}
@@ -394,11 +356,11 @@
public HistoryActivityInstanceQueryImpl createHistoryActivityInstanceQuery() {
return new HistoryActivityInstanceQueryImpl();
}
-
+
public HistoryDetailQueryImpl createHistoryDetailQuery() {
return new HistoryDetailQueryImpl();
}
-
+
public JobQueryImpl createJobQuery() {
return new JobQueryImpl();
}
@@ -408,18 +370,11 @@
}
public List<HistoryComment> findCommentsByTaskId(String taskId) {
- Long taskDbid = null;
- try {
- taskDbid = Long.parseLong(taskId);
- } catch (Exception e) {
- throw new JbpmException("invalid taskId: "+taskId);
- }
- return session.createQuery(
- "select hc " +
- "from "+HistoryCommentImpl.class.getName()+" as hc " +
- "where hc.historyTask.dbid = :taskDbid " +
- "order by hc.historyTaskIndex asc "
- ).setLong("taskDbid", taskDbid)
- .list();
+ List<?> comments = session.createCriteria(HistoryCommentImpl.class)
+ .createAlias("historyTask", "task")
+ .add(Restrictions.eq("task.dbid", Long.parseLong(taskId)))
+ .addOrder(Order.asc("historyTaskIndex"))
+ .list();
+ return CollectionUtil.checkList(comments, HistoryComment.class);
}
}
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/history/events/ProcessInstanceCreate.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/history/events/ProcessInstanceCreate.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/history/events/ProcessInstanceCreate.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -21,19 +21,17 @@
*/
package org.jbpm.pvm.internal.history.events;
-import java.io.Serializable;
-
import org.hibernate.Session;
+
import org.jbpm.api.history.HistoryProcessInstance;
import org.jbpm.pvm.internal.env.EnvironmentImpl;
import org.jbpm.pvm.internal.history.HistoryEvent;
import org.jbpm.pvm.internal.history.model.HistoryProcessInstanceImpl;
-
/**
* @author Tom Baeyens
*/
-public class ProcessInstanceCreate extends HistoryEvent implements Serializable {
+public class ProcessInstanceCreate extends HistoryEvent {
private static final long serialVersionUID = 1L;
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/history/model/HistoryCommentImpl.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/history/model/HistoryCommentImpl.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/history/model/HistoryCommentImpl.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -63,8 +63,8 @@
return reply;
}
- public List<HistoryComment> getReplies() {
- return (List) replies;
+ public List<? extends HistoryComment> getReplies() {
+ return replies;
}
// getters and setters //////////////////////////////////////////////////////
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/history/model/HistoryTaskImpl.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/history/model/HistoryTaskImpl.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/history/model/HistoryTaskImpl.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -22,10 +22,8 @@
package org.jbpm.pvm.internal.history.model;
import java.io.Serializable;
-import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
-import java.util.List;
import java.util.Set;
import org.jbpm.api.history.HistoryTask;
@@ -33,7 +31,6 @@
import org.jbpm.pvm.internal.util.Clock;
import org.jbpm.pvm.internal.util.EqualsUtil;
-
/**
* @author Tom Baeyens
*/
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/identity/impl/IdentitySessionImpl.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/identity/impl/IdentitySessionImpl.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/identity/impl/IdentitySessionImpl.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -27,12 +27,14 @@
import org.hibernate.Session;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
+
import org.jbpm.api.JbpmException;
import org.jbpm.api.identity.Group;
import org.jbpm.api.identity.User;
import org.jbpm.pvm.internal.env.EnvironmentImpl;
import org.jbpm.pvm.internal.id.DbidGenerator;
import org.jbpm.pvm.internal.identity.spi.IdentitySession;
+import org.jbpm.pvm.internal.util.CollectionUtil;
/**
* @author Tom Baeyens
@@ -41,13 +43,14 @@
protected Session session;
- public String createUser(String userName, String givenName, String familyName, String businessEmail) {
+ public String createUser(String userName, String givenName, String familyName,
+ String businessEmail) {
UserImpl user = new UserImpl(userName, givenName, familyName);
user.setBusinessEmail(businessEmail);
-
+
long dbid = EnvironmentImpl.getFromCurrent(DbidGenerator.class).getNextId();
user.setDbid(dbid);
-
+
session.save(user);
return user.getId();
@@ -55,35 +58,36 @@
public User findUserById(String userId) {
return (User) session.createCriteria(UserImpl.class)
- .add(Restrictions.eq("id", userId))
- .uniqueResult();
+ .add(Restrictions.eq("id", userId))
+ .uniqueResult();
}
public List<User> findUsersById(String... userIds) {
- List<User> users = session.createCriteria(UserImpl.class)
- .add(Restrictions.in("id", userIds))
- .list();
+ List<?> users = session.createCriteria(UserImpl.class)
+ .add(Restrictions.in("id", userIds))
+ .list();
if (userIds.length != users.size()) {
throw new JbpmException("not all users were found: " + Arrays.toString(userIds));
}
- return users;
+ return CollectionUtil.checkList(users, User.class);
}
public List<User> findUsers() {
- return session.createCriteria(UserImpl.class).list();
+ List<?> users = session.createCriteria(UserImpl.class).list();
+ return CollectionUtil.checkList(users, User.class);
}
public void deleteUser(String userId) {
// lookup the user
User user = findUserById(userId);
- // cascade the deletion to the memberships
- List<MembershipImpl> memberships = session.createCriteria(MembershipImpl.class)
- .add(Restrictions.eq("user", user))
- .list();
+ // cascade the deletion to the memberships
+ List<?> memberships = session.createCriteria(MembershipImpl.class)
+ .add(Restrictions.eq("user", user))
+ .list();
- // delete the related memberships
- for (MembershipImpl membership : memberships) {
+ // delete the related memberships
+ for (Object membership : memberships) {
session.delete(membership);
}
@@ -106,63 +110,62 @@
GroupImpl parentGroup = findGroupById(parentGroupId);
group.setParent(parentGroup);
}
-
+
session.save(group);
return group.getId();
}
public List<User> findUsersByGroup(String groupId) {
- return session.createCriteria(MembershipImpl.class)
- .createAlias("group", "g")
- .add(Restrictions.eq("g.id", groupId))
- .setProjection(Projections.property("user"))
- .list();
+ List<?> users = session.createCriteria(MembershipImpl.class)
+ .createAlias("group", "g")
+ .add(Restrictions.eq("g.id", groupId))
+ .setProjection(Projections.property("user"))
+ .list();
+ return CollectionUtil.checkList(users, User.class);
}
public GroupImpl findGroupById(String groupId) {
return (GroupImpl) session.createCriteria(GroupImpl.class)
- .add(Restrictions.eq("id", groupId))
- .uniqueResult();
+ .add(Restrictions.eq("id", groupId))
+ .uniqueResult();
}
public List<Group> findGroupsByUserAndGroupType(String userId, String groupType) {
- return session.createQuery("select distinct m.group"
- + " from "
- + MembershipImpl.class.getName()
- + " as m where m.user.id = :userId"
- + " and m.group.type = :groupType")
- .setString("userId", userId)
- .setString("groupType", groupType)
- .list();
+ List<?> groups = session.getNamedQuery("findGroupsByUserAndGroupType")
+ .setString("userId", userId)
+ .setString("groupType", groupType)
+ .list();
+ return CollectionUtil.checkList(groups, Group.class);
}
public List<Group> findGroupsByUser(String userId) {
- return session.createQuery("select distinct m.group"
- + " from "
- + MembershipImpl.class.getName()
- + " as m where m.user.id = :userId").setString("userId", userId).list();
+ List<?> groups = session.getNamedQuery("findGroupsByUser")
+ .setParameter("userId", userId)
+ .list();
+ return CollectionUtil.checkList(groups, Group.class);
}
public List<Group> findGroups() {
- return session.createCriteria(GroupImpl.class).list();
+ List<?> groups = session.createCriteria(GroupImpl.class).list();
+ return CollectionUtil.checkList(groups, Group.class);
}
public void deleteGroup(String groupId) {
// look up the group
GroupImpl group = findGroupById(groupId);
- // cascade the deletion to the memberships
- List<MembershipImpl> memberships = session.createCriteria(MembershipImpl.class)
- .add(Restrictions.eq("group", group))
- .list();
+ // cascade the deletion to the memberships
+ List<?> memberships = session.createCriteria(MembershipImpl.class)
+ .add(Restrictions.eq("group", group))
+ .list();
- // delete the related memberships
- for (MembershipImpl membership : memberships) {
+ // delete the related memberships
+ for (Object membership : memberships) {
session.delete(membership);
}
- // delete the group
+ // delete the group
session.delete(group);
}
@@ -189,11 +192,11 @@
public void deleteMembership(String userId, String groupId, String role) {
MembershipImpl membership = (MembershipImpl) session.createCriteria(MembershipImpl.class)
- .createAlias("user", "u")
- .createAlias("group", "g")
- .add(Restrictions.eq("u.id", userId))
- .add(Restrictions.eq("g.id", groupId))
- .uniqueResult();
+ .createAlias("user", "u")
+ .createAlias("group", "g")
+ .add(Restrictions.eq("u.id", userId))
+ .add(Restrictions.eq("g.id", groupId))
+ .uniqueResult();
session.delete(membership);
}
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/job/CommandMessage.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/job/CommandMessage.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/job/CommandMessage.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -24,14 +24,12 @@
import org.jbpm.api.JbpmException;
import org.jbpm.api.cmd.Command;
import org.jbpm.api.cmd.Environment;
-import org.jbpm.pvm.internal.session.DbSession;
import org.jbpm.pvm.internal.wire.Descriptor;
-
/**
* @author Tom Baeyens
*/
-public class CommandMessage extends MessageImpl<Object> {
+public class CommandMessage extends MessageImpl {
private static final long serialVersionUID = 1L;
@@ -46,14 +44,9 @@
setConfiguration(command);
}
- public Object execute(Environment environment) throws Exception {
+ protected void executeVoid(Environment environment) throws Exception {
Command<?> command = (Command<?>) getConfiguration();
command.execute(environment);
-
- DbSession dbSession = environment.get(DbSession.class);
- dbSession.delete(this);
-
- return null;
}
}
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/job/JobImpl.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/job/JobImpl.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/job/JobImpl.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -14,7 +14,7 @@
import org.jbpm.pvm.internal.model.ExecutionImpl;
import org.jbpm.pvm.internal.wire.Descriptor;
-public abstract class JobImpl<T> implements Command<T>, Serializable, Job {
+public abstract class JobImpl implements Command<Boolean>, Serializable, Job {
private static final long serialVersionUID = 1L;
// private static final DateFormat dateFormat = new SimpleDateFormat("dd-MMM-yyyy HH:mm:ss,SSS");
@@ -28,8 +28,8 @@
protected int dbversion;
/** date until which the command should not be executed
- * for async messages, this duedate should be set to null. */
- protected Date duedate = null;
+ * for async messages, this due date should be set to null. */
+ protected Date dueDate;
/** job state. */
protected String state = STATE_WAITING;
@@ -148,16 +148,20 @@
public String getLockOwner() {
return lockOwner;
}
- /** @deprecated */
- @Deprecated
public Date getDueDate() {
- return getDuedate();
+ return dueDate;
}
+ public void setDueDate(Date dueDate) {
+ this.dueDate = dueDate;
+ }
+ @Deprecated
public Date getDuedate() {
- return duedate;
+ return getDueDate();
}
+ /** @deprecated call {@link #setDueDate(Date)} instead */
+ @Deprecated
public void setDuedate(Date duedate) {
- this.duedate = duedate;
+ setDueDate(duedate);
}
public String getException() {
return exception;
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/job/MessageImpl.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/job/MessageImpl.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/job/MessageImpl.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -21,6 +21,7 @@
*/
package org.jbpm.pvm.internal.job;
+import org.jbpm.api.cmd.Environment;
import org.jbpm.api.job.Message;
import org.jbpm.pvm.internal.id.DbidGenerator;
import org.jbpm.pvm.internal.model.ExecutionImpl;
@@ -28,20 +29,28 @@
/**
* @author Tom Baeyens
*/
-public abstract class MessageImpl<T> extends JobImpl<T> implements Message {
+public abstract class MessageImpl extends JobImpl implements Message {
private static final long serialVersionUID = 1L;
public MessageImpl() {
}
-
+
public String toString() {
- return "message["+dbid+"]";
+ return "message[" + dbid + "]";
}
-
+
public MessageImpl(ExecutionImpl execution) {
this.execution = execution;
this.processInstance = execution.getProcessInstance();
- this.dbid = DbidGenerator.getDbidGenerator().getNextId();
+ this.dbid = DbidGenerator.getDbidGenerator().getNextId();
}
+
+ public Boolean execute(Environment environment) throws Exception {
+ executeVoid(environment);
+ // always delete this message
+ return true;
+ }
+
+ protected abstract void executeVoid(Environment environment) throws Exception;
}
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/job/StartProcessTimer.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/job/StartProcessTimer.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/job/StartProcessTimer.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -32,11 +32,9 @@
import org.jbpm.pvm.internal.cal.CronExpression;
import org.jbpm.pvm.internal.cal.Duration;
import org.jbpm.pvm.internal.env.EnvironmentImpl;
-import org.jbpm.pvm.internal.session.DbSession;
import org.jbpm.pvm.internal.session.RepositorySession;
import org.jbpm.pvm.internal.util.Clock;
-
/**
* Job that starts a new process instance of a given process definition
* on a fixed duedate/periodic time.
@@ -51,26 +49,22 @@
// Override execution logic of regular timer
public Boolean execute(Environment environment) throws Exception {
-
if (LOG.isDebugEnabled()) {
LOG.debug("Periodic start process triggered at " + Clock.getTime());
}
-
- boolean processDefinitionExists = processDefinitionExists(environment);
- boolean newDueDateCalculated = false;
-
- if (processDefinitionExists) {
+
+ // if process definition exists
+ if (processDefinitionExists(environment)) {
startProcessInstance(environment);
- newDueDateCalculated = calculateDueDate(environment);
- }
-
- if (!processDefinitionExists || !newDueDateCalculated) {
- deleteThisJob(environment);
- } else {
- saveThisJob(environment);
+ // and a new date is appointed
+ if (calculateDueDate(environment)) {
+ // do not delete this timer
+ return false;
+ }
}
-
- return null;
+
+ // delete timer otherwise
+ return true;
}
protected boolean processDefinitionExists(Environment environment) {
@@ -107,9 +101,9 @@
protected boolean calculateDueDate(Environment environment) throws ParseException {
if (getIntervalExpression() != null && Duration.isValidExpression(getIntervalExpression())) {
- duedate = Duration.calculateDueDate(getIntervalExpression());
+ dueDate = Duration.calculateDueDate(getIntervalExpression());
} else if (getIntervalExpression() != null && CronExpression.isValidExpression(getIntervalExpression())) {
- duedate = new CronExpression(getIntervalExpression()).getNextValidTimeAfter(Clock.getTime());
+ dueDate = new CronExpression(getIntervalExpression()).getNextValidTimeAfter(Clock.getTime());
} else {
if (LOG.isDebugEnabled()) {
LOG.debug("No next duedate calculated for start process job " +
@@ -119,41 +113,21 @@
}
if (LOG.isDebugEnabled()) {
- LOG.debug("Next process start duedate: " + duedate);
+ LOG.debug("Next process start duedate: " + dueDate);
}
return true;
}
- protected void saveThisJob(Environment environment) {
- DbSession dbSession = environment.get(DbSession.class);
- if (dbSession == null) {
- throw new JbpmException("no " + DbSession.class.getName() + " in environment");
- }
- dbSession.save(this);
- }
-
- protected void deleteThisJob(Environment environment) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("Deleting start process job for process definition with name " + getProcessDefinitionName());
- }
-
- DbSession dbSession = environment.get(DbSession.class);
- if (dbSession == null) {
- throw new JbpmException("no " + DbSession.class.getName() + " in environment");
- }
- dbSession.delete(this);
- }
-
@Override
public void schedule() {
- if (duedate == null && getIntervalExpression() != null) {
+ if (dueDate == null && getIntervalExpression() != null) {
try {
calculateDueDate(EnvironmentImpl.getCurrent());
} catch (ParseException e) {
throw new JbpmException("Cannot parse intervalExpression", e);
}
- } else if (duedate == null) {
+ } else if (dueDate == null) {
throw new JbpmException("Cannot schedule start process timer: " +
"no duedate or intervalExpression set");
}
@@ -165,7 +139,7 @@
if (getProcessDefinitionName() == null) {
throw new JbpmException("No process definition name set for start process timer");
}
- if (duedate == null && getIntervalExpression() == null) {
+ if (dueDate == null && getIntervalExpression() == null) {
throw new JbpmException("No duedate or intervalExpression found for start process timer");
}
}
@@ -199,8 +173,8 @@
if (getProcessDefinitionName() != null) {
strb.append(getProcessDefinitionName());
}
- if (duedate != null) {
- strb.append("| " + duedate);
+ if (dueDate != null) {
+ strb.append("| " + dueDate);
}
if (getIntervalExpression() != null) {
strb.append("| " + getIntervalExpression());
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/job/TimerImpl.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/job/TimerImpl.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/job/TimerImpl.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -34,7 +34,6 @@
import org.jbpm.pvm.internal.jobexecutor.JobAddedNotification;
import org.jbpm.pvm.internal.jobexecutor.JobExecutor;
import org.jbpm.pvm.internal.model.ObservableElement;
-import org.jbpm.pvm.internal.session.DbSession;
import org.jbpm.pvm.internal.session.TimerSession;
import org.jbpm.pvm.internal.tx.Transaction;
import org.jbpm.pvm.internal.util.Clock;
@@ -48,7 +47,7 @@
* @author Ronald Van Kuijk
* @author Maciej Swiderski
*/
-public class TimerImpl extends JobImpl<Boolean> implements Timer {
+public class TimerImpl extends JobImpl implements Timer {
private static final long serialVersionUID = 1L;
private static final Log log = Log.getLog(TimerImpl.class.getName());
@@ -58,91 +57,88 @@
protected String signalName;
protected String eventName;
protected String repeat;
-
+
public static final String EVENT_TIMER = "timer";
public TimerImpl() {
}
-
+
public void schedule() {
- this.dbid = DbidGenerator.getDbidGenerator().getNextId();
+ this.dbid = DbidGenerator.getDbidGenerator().getNextId();
TimerSession timerSession = EnvironmentImpl.getFromCurrent(TimerSession.class);
timerSession.schedule(this);
}
public void setDueDateDescription(String dueDateDescription) {
if (dueDateDescription != null) {
- duedate = Duration.calculateDueDate(dueDateDescription);
+ dueDate = Duration.calculateDueDate(dueDateDescription);
}
}
public Boolean execute(Environment environment) throws Exception {
- if (log.isDebugEnabled()) log.debug("executing " + this);
-
- if (environment==null) {
+ if (log.isDebugEnabled())
+ log.debug("executing " + this);
+
+ if (environment == null) {
throw new JbpmException("environment is null");
}
-
- if (signalName!=null) {
- if (log.isDebugEnabled()) log.debug("feeding timer signal "+signalName+" into "+execution);
-
+
+ if (signalName != null) {
+ if (log.isDebugEnabled()) {
+ log.debug("feeding timer signal " + signalName + " into " + execution);
+ }
+
// feed expiration signal
execution.signal(signalName);
}
-
- if (eventName!=null) {
+
+ if (eventName != null) {
ObservableElement eventSource = execution.getActivity();
- if (log.isDebugEnabled()) log.debug("firing event "+eventName+" into "+eventSource);
+ if (log.isDebugEnabled())
+ log.debug("firing event " + eventName + " into " + eventSource);
execution.fire(eventName, eventSource);
}
-
- boolean deleteThisJob = true;
+
// if there is no repeat on this timer
- if (repeat==null) {
- // delete the job
- if (log.isDebugEnabled()) log.debug("deleting " + this);
- DbSession dbSession = environment.get(DbSession.class);
- if (dbSession==null) {
- throw new JbpmException("no "+DbSession.class.getName()+" in environment");
- }
- dbSession.delete(this);
+ if (repeat == null) {
+ // have the timer deleted
+ return true;
+ }
- } else { // there is a repeat on this timer
- deleteThisJob = false;
- // suppose that it took the timer runner thread a very long time to execute the timers
- // then the repeat action duedate could already have passed
- do {
- setDueDateDescription(repeat);
- } while (duedate.getTime() <= Clock.getTime().getTime());
+ // suppose that it took the timer runner thread a very long time to execute the timers
+ // then the repeat action duedate could already have passed
+ do {
+ setDueDateDescription(repeat);
+ } while (dueDate.getTime() <= Clock.getTime().getTime());
- if (log.isDebugEnabled()) log.debug("rescheduled "+this+" for "+formatDueDate(duedate));
-
- // release the lock on the timer
- release();
-
- // notify the jobExecutor at the end of the transaction
- JobExecutor jobExecutor = environment.get(JobExecutor.class);
- if (jobExecutor!=null) {
- Transaction transaction = environment.get(Transaction.class);
- if (transaction==null) {
- throw new JbpmException("no transaction in environment");
- }
- JobAddedNotification jobNotificator = new JobAddedNotification(jobExecutor);
- transaction.registerSynchronization(jobNotificator);
+ if (log.isDebugEnabled())
+ log.debug("rescheduled " + this + " for " + formatDueDate(dueDate));
+
+ // release the lock on the timer
+ release();
+
+ // notify the jobExecutor at the end of the transaction
+ JobExecutor jobExecutor = environment.get(JobExecutor.class);
+ if (jobExecutor != null) {
+ Transaction transaction = environment.get(Transaction.class);
+ if (transaction == null) {
+ throw new JbpmException("no transaction in environment");
}
+ JobAddedNotification jobNotificator = new JobAddedNotification(jobExecutor);
+ transaction.registerSynchronization(jobNotificator);
}
-
- return deleteThisJob;
+ // do not delete this timer
+ return false;
}
-
+
public void validate() {
if (getExecution() == null) {
throw new JbpmException("timer has no execution specified");
}
- if ((getSignalName() == null) && (getEventName() == null)) {
+ if (getSignalName() == null && getEventName() == null) {
throw new JbpmException("timer has no signalName or eventName specified");
}
- if (getDuedate() == null) {
+ if (getDueDate() == null) {
throw new JbpmException("timer scheduled at null date");
}
}
@@ -152,8 +148,8 @@
StringBuilder text = new StringBuilder();
text.append("timer[");
text.append(dbid);
- if (duedate != null) {
- text.append('|').append(formatDueDate(duedate));
+ if (dueDate != null) {
+ text.append('|').append(formatDueDate(dueDate));
}
if (signalName != null) {
text.append('|').append(signalName);
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/jobexecutor/AcquireJobsCmd.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/jobexecutor/AcquireJobsCmd.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/jobexecutor/AcquireJobsCmd.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -34,7 +34,6 @@
import org.jbpm.pvm.internal.job.JobImpl;
import org.jbpm.pvm.internal.session.DbSession;
-
/**
* @author Tom Baeyens
*/
@@ -45,7 +44,7 @@
private static final Log log = Log.getLog(AcquireJobsCmd.class.getName());
private static final DateFormat timeFormat = new SimpleDateFormat("HH:mm:ss,SSS");
- JobExecutor jobExecutor;
+ private JobExecutor jobExecutor;
public AcquireJobsCmd(JobExecutor jobExecutor) {
this.jobExecutor = jobExecutor;
@@ -55,23 +54,23 @@
Collection<Long> acquiredJobDbids = new ArrayList<Long>();
try {
- Collection<JobImpl<?>> acquiredJobs = new ArrayList<JobImpl<?>>();
+ Collection<JobImpl> acquiredJobs = new ArrayList<JobImpl>();
DbSession dbSession = environment.get(DbSession.class);
if (log.isTraceEnabled()) log.trace("start querying first acquirable job...");
- JobImpl<?> job = dbSession.findFirstAcquirableJob();
+ JobImpl job = dbSession.findFirstAcquirableJob();
if (job!=null) {
if (job.isExclusive()) {
if (log.isTraceEnabled()) log.trace("exclusive acquirable job found ("+job+"). querying for other exclusive jobs to lock them all in one tx...");
- List<JobImpl<?>> otherExclusiveJobs = dbSession.findExclusiveJobs(job.getProcessInstance());
+ List<JobImpl> otherExclusiveJobs = dbSession.findExclusiveJobs(job.getProcessInstance());
acquiredJobs.addAll(otherExclusiveJobs);
} else {
acquiredJobs.add(job);
}
- for (JobImpl<?> acquiredJob: acquiredJobs) {
+ for (JobImpl acquiredJob: acquiredJobs) {
long lockExpirationTime = System.currentTimeMillis()+jobExecutor.getLockMillis();
if (log.isTraceEnabled()) log.trace("trying to obtain a lock for '"+acquiredJob+"' with exp "+timeFormat.format(new Date(lockExpirationTime)));
acquiredJob.acquire(jobExecutor.getName(), new Date(lockExpirationTime));
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/jobexecutor/GetNextDueDateCmd.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/jobexecutor/GetNextDueDateCmd.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/jobexecutor/GetNextDueDateCmd.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -29,8 +29,6 @@
import org.jbpm.pvm.internal.job.JobImpl;
import org.jbpm.pvm.internal.session.DbSession;
-
-
/**
* @author Tom Baeyens
*/
@@ -40,17 +38,11 @@
private static final Log log = Log.getLog(GetNextDueDateCmd.class.getName());
- JobExecutor jobExecutor;
-
- public GetNextDueDateCmd(JobExecutor jobExecutor) {
- this.jobExecutor = jobExecutor;
- }
-
public Date execute(Environment environment) throws Exception {
Date nextDueDate = null;
if (log.isTraceEnabled()) log.trace("getting next due date...");
DbSession dbSession = environment.get(DbSession.class);
- JobImpl<?> job = dbSession.findFirstDueJob();
+ JobImpl job = dbSession.findFirstDueJob();
if (job!=null) {
nextDueDate = job.getDueDate();
}
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/jobexecutor/JobExceptionHandler.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/jobexecutor/JobExceptionHandler.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/jobexecutor/JobExceptionHandler.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -75,7 +75,7 @@
if (dbSession==null) {
throw new JbpmException("no job-session configured to handle job");
}
- JobImpl<?> job = dbSession.get(JobImpl.class, jobDbid);
+ JobImpl job = dbSession.get(JobImpl.class, jobDbid);
// serialize the stack trace
StringWriter sw = new StringWriter();
exception.printStackTrace(new PrintWriter(sw));
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/jobexecutor/JobExecutor.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/jobexecutor/JobExecutor.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/jobexecutor/JobExecutor.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -52,25 +52,25 @@
// configuration parameters
- CommandService commandService;
- String name = "JobExecutor-"+getHostName();
- int nbrOfThreads = 3;
- int idleMillis = 5*1000; // default normal poll interval is 5 seconds
- int idleMillisMax = 5*60*1000; // default max poll interval in case of continuous exceptions is 5 minutes
- int historySize = 200;
- int lockMillis = 30*60*1000; // default max lock time is 30 minutes
+ private CommandService commandService;
+ private String name = "JobExecutor-"+getHostName();
+ private int nbrOfThreads = 3;
+ private int idleMillis = 5*1000; // default normal poll interval is 5 seconds
+ private int idleMillisMax = 5*60*1000; // default max poll interval in case of continuous exceptions is 5 minutes
+ private int historySize = 200;
+ private int lockMillis = 30*60*1000; // default max lock time is 30 minutes
// runtime state
- Command<Collection<Long>> acquireJobsCommand;
- Command<Date> nextDueDateCommand;
+ private Command<Collection<Long>> acquireJobsCommand;
+ private Command<Date> nextDueDateCommand;
- boolean isActive;
+ private boolean isActive;
- ExecutorService threadPool;
- DispatcherThread dispatcherThread;
+ private ExecutorService threadPool;
+ private DispatcherThread dispatcherThread;
- List<JobHistoryEntry> history = new ArrayList<JobHistoryEntry>();
+ private List<JobHistoryEntry> history = new ArrayList<JobHistoryEntry>();
/** starts the {@link DispatcherThread} and {@link JobExecutorThread}s for this job executor */
public synchronized void start() {
@@ -79,7 +79,7 @@
}
if (! isActive) {
acquireJobsCommand = new AcquireJobsCmd(this);
- nextDueDateCommand = new GetNextDueDateCmd(this);
+ nextDueDateCommand = new GetNextDueDateCmd();
isActive = true;
log.trace("starting thread pool for job executor '"+name+"'...");
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/jobexecutor/JobExecutorServlet.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/jobexecutor/JobExecutorServlet.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/jobexecutor/JobExecutorServlet.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -32,7 +32,6 @@
import org.jbpm.api.Configuration;
import org.jbpm.api.JbpmException;
import org.jbpm.pvm.internal.env.EnvironmentFactory;
-import org.jbpm.pvm.internal.processengine.ProcessEngineImpl;
/**
* starts the job executor on init and closes the
@@ -79,8 +78,9 @@
private static final long serialVersionUID = 1L;
- JobExecutor jobExecutor;
+ private JobExecutor jobExecutor;
+ @Override
public void init() throws ServletException {
String configurationResource = getInitParameter("jbpm.configuration.resource", "jbpm.cfg.xml");
EnvironmentFactory environmentFactory = (EnvironmentFactory) new Configuration().setResource(configurationResource).buildProcessEngine();
@@ -91,6 +91,14 @@
jobExecutor.start();
}
+ @Override
+ public void destroy() {
+ if (jobExecutor != null) {
+ jobExecutor.stop(true);
+ }
+ }
+
+ @Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter out = response.getWriter();
out.println("<html>");
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/jobexecutor/JobExecutorTimerSession.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/jobexecutor/JobExecutorTimerSession.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/jobexecutor/JobExecutorTimerSession.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -15,8 +15,9 @@
import java.util.List;
-import org.hibernate.Query;
import org.hibernate.Session;
+import org.hibernate.criterion.Restrictions;
+
import org.jbpm.api.Execution;
import org.jbpm.api.JbpmException;
import org.jbpm.api.job.Timer;
@@ -24,6 +25,7 @@
import org.jbpm.pvm.internal.job.TimerImpl;
import org.jbpm.pvm.internal.session.TimerSession;
import org.jbpm.pvm.internal.tx.Transaction;
+import org.jbpm.pvm.internal.util.CollectionUtil;
/**
* Timers created with this service are committed at the end of the transaction,
@@ -77,12 +79,9 @@
}
public List<Timer> findTimersByExecution(Execution execution) {
- Query query = session.createQuery(
- "select timer " +
- "from "+TimerImpl.class.getName()+" timer " +
- "where timer.execution = :execution"
- );
- query.setEntity("execution", execution);
- return query.list();
+ List<?> timers = session.createCriteria(TimerImpl.class)
+ .add(Restrictions.eq("execution", execution))
+ .list();
+ return CollectionUtil.checkList(timers, Timer.class);
}
}
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/EventImpl.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/EventImpl.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/EventImpl.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -21,7 +21,6 @@
*/
package org.jbpm.pvm.internal.model;
-import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
@@ -32,7 +31,7 @@
/**
* @author Tom Baeyens
*/
-public class EventImpl extends ProcessElementImpl implements Serializable, Event {
+public class EventImpl extends ProcessElementImpl implements Event {
private static final long serialVersionUID = 1L;
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/ExecutionImpl.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/ExecutionImpl.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/ExecutionImpl.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -639,7 +639,7 @@
if (messageSession==null) {
throw new JbpmException("no message-session configured to send asynchronous continuation message");
}
- MessageImpl<?> asyncMessage = operation.createAsyncMessage(this);
+ MessageImpl asyncMessage = operation.createAsyncMessage(this);
setState(Execution.STATE_ASYNC);
messageSession.send(asyncMessage);
}
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/ObservableElementImpl.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/ObservableElementImpl.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/ObservableElementImpl.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -90,10 +90,7 @@
public void setDescription(String description) {
this.description = description;
}
- public Map<String, Event> getEvents() {
- return (Map) events;
+ public Map<String, ? extends Event> getEvents() {
+ return events;
}
- public void setEvents(Map<String, EventImpl> events) {
- this.events = events;
- }
}
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/ProcessElementImpl.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/ProcessElementImpl.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/ProcessElementImpl.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -27,7 +27,6 @@
import java.util.List;
import java.util.Set;
-import org.jbpm.internal.log.Log;
import org.jbpm.pvm.internal.wire.Descriptor;
/**
@@ -39,7 +38,6 @@
public class ProcessElementImpl implements Serializable {
private static final long serialVersionUID = 1L;
- private static final Log log = Log.getLog(ProcessElementImpl.class.getName());
protected long dbid;
protected int dbversion;
@@ -81,7 +79,7 @@
public Set<String> getPropertyKeys() {
if (properties==null) {
- return Collections.EMPTY_SET;
+ return Collections.emptySet();
}
return properties.keys();
}
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/ScopeInstanceImpl.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/ScopeInstanceImpl.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/ScopeInstanceImpl.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -101,21 +101,8 @@
protected Variable createVariableObject(String key, Object value, String typeName, boolean isHistoryEnabled) {
log.debug("create variable '"+key+"' in '"+this+"' with value '"+value+"'");
- Type type = null;
-
- if (type==null) {
- TypeSet typeSet = EnvironmentImpl.getFromCurrent(TypeSet.class, false);
- if (typeSet!=null) {
- if (typeName!=null) {
- type = typeSet.findTypeByName(typeName);
- }
- if (type==null) {
- type = typeSet.findTypeByMatch(key, value);
- }
- }
- }
-
- Variable variable = null;
+ Type type = findType(key, value, typeName);
+ Variable variable;
if (type!=null) {
Class<?> variableClass = type.getVariableClass();
@@ -154,6 +141,17 @@
return variable;
}
+ private static Type findType(String key, Object value, String typeName) {
+ TypeSet typeSet = EnvironmentImpl.getFromCurrent(TypeSet.class, false);
+ if (typeSet == null) return null;
+
+ Type type;
+ if (typeName == null || (type = typeSet.findTypeByName(typeName)) == null) {
+ type = typeSet.findTypeByMatch(key, value);
+ }
+ return type;
+ }
+
public void setVariable(String key, Object value) {
if (key==null) {
throw new JbpmException("variableName is null");
@@ -301,12 +299,12 @@
if (timerDefinition!=null) {
timer.setEventName(timerDefinition.getEventName());
timer.setSignalName(timerDefinition.getSignalName());
- timer.setDuedate(timerDefinition.getDueDate());
+ timer.setDueDate(timerDefinition.getDueDate());
timer.setDueDateDescription(timerDefinition.getDueDateDescription());
- if (timer.getDuedate() == null && timerDefinition.getCronExpression() != null) {
+ if (timer.getDueDate() == null && timerDefinition.getCronExpression() != null) {
try {
- timer.setDuedate(new CronExpression(timerDefinition.getCronExpression()).getNextValidTimeAfter(Clock.getTime()));
+ timer.setDueDate(new CronExpression(timerDefinition.getCronExpression()).getNextValidTimeAfter(Clock.getTime()));
} catch (ParseException pe) {
throw new JbpmException("Can't parse cron expression " + timerDefinition.getCronExpression(), pe);
}
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/VariableOutDefinitionSet.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/VariableOutDefinitionSet.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/VariableOutDefinitionSet.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -65,7 +65,7 @@
public List<VariableOutDefinitionImpl> getVariableOutDefinitions() {
if (variableOutDefinitions==null) {
- return Collections.EMPTY_LIST;
+ return Collections.emptyList();
}
return variableOutDefinitions;
}
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/WireProperties.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/WireProperties.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/WireProperties.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -49,7 +49,7 @@
public Set<String> keys() {
if (wireContext==null) {
- return Collections.EMPTY_SET;
+ return Collections.emptySet();
}
return wireContext.keys();
}
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/AtomicOperation.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/AtomicOperation.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/AtomicOperation.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -41,7 +41,7 @@
public static final AtomicOperation TRANSITION_END_ACTIVITY = new TransitionEndActivity();
public abstract boolean isAsync(ExecutionImpl execution);
- public abstract MessageImpl<?> createAsyncMessage(ExecutionImpl execution);
+ public abstract MessageImpl createAsyncMessage(ExecutionImpl execution);
public abstract void perform(ExecutionImpl execution);
public static AtomicOperation parseAtomicOperation(String text) {
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/ExecuteActivity.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/ExecuteActivity.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/ExecuteActivity.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -34,7 +34,7 @@
private static final long serialVersionUID = 1L;
- private static Log log = Log.getLog(ExecuteActivity.class.getName());
+ private static final Log log = Log.getLog(ExecuteActivity.class.getName());
public boolean isAsync(ExecutionImpl execution) {
return execution.getActivity().isAsync();
@@ -72,7 +72,7 @@
return "ExecuteActivity";
}
- public MessageImpl<?> createAsyncMessage(ExecutionImpl execution) {
+ public MessageImpl createAsyncMessage(ExecutionImpl execution) {
ExecuteActivityMessage executeActivityMessage = new ExecuteActivityMessage(execution);
if (execution.getActivity().getContinuation()==Continuation.EXCLUSIVE) {
executeActivityMessage.setExclusive(true);
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/ExecuteActivityMessage.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/ExecuteActivityMessage.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/ExecuteActivityMessage.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -24,12 +24,11 @@
import org.jbpm.api.cmd.Environment;
import org.jbpm.pvm.internal.job.MessageImpl;
import org.jbpm.pvm.internal.model.ExecutionImpl;
-import org.jbpm.pvm.internal.session.DbSession;
/**
* @author Tom Baeyens
*/
-public class ExecuteActivityMessage extends MessageImpl<Object> {
+public class ExecuteActivityMessage extends MessageImpl {
private static final long serialVersionUID = 1L;
@@ -40,15 +39,10 @@
super(execution);
}
- public Object execute(Environment environment) throws Exception {
+ protected void executeVoid(Environment environment) throws Exception {
AsyncContinuations.restoreState(execution);
execution.performAtomicOperationSync(AtomicOperation.EXECUTE_ACTIVITY);
-
- DbSession dbSession = environment.get(DbSession.class);
- dbSession.delete(this);
-
- return null;
}
public String toString() {
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/ExecuteEventListener.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/ExecuteEventListener.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/ExecuteEventListener.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -32,7 +32,6 @@
import org.jbpm.pvm.internal.model.ObservableElement;
import org.jbpm.pvm.internal.model.ObservableElementImpl;
-
/**
* @author Tom Baeyens
*/
@@ -126,7 +125,7 @@
}
}
- public MessageImpl< ? > createAsyncMessage(ExecutionImpl execution) {
+ public MessageImpl createAsyncMessage(ExecutionImpl execution) {
return new ExecuteEventListenerMessage(execution);
}
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/ExecuteEventListenerMessage.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/ExecuteEventListenerMessage.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/ExecuteEventListenerMessage.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -32,12 +32,11 @@
import org.jbpm.pvm.internal.model.ObservableElementImpl;
import org.jbpm.pvm.internal.model.ProcessDefinitionImpl;
import org.jbpm.pvm.internal.model.TransitionImpl;
-import org.jbpm.pvm.internal.session.DbSession;
/**
* @author Tom Baeyens
*/
-public class ExecuteEventListenerMessage extends MessageImpl<Object> {
+public class ExecuteEventListenerMessage extends MessageImpl {
private static final String KEY_EVENT_COMPLETED_OPERATION = "ECO";
private static final String KEY_EVENT_LISTENER_INDEX = "ELI";
@@ -105,7 +104,7 @@
return parentLevel;
}
- public Object execute(Environment environment) throws Exception {
+ protected void executeVoid(Environment environment) throws Exception {
Map<?, ?> asyncExecutionInfo = (Map<?, ?>) getConfiguration();
String transitionSourceName = (String) asyncExecutionInfo.get(KEY_TRANSITION_SOURCE);
@@ -152,10 +151,5 @@
execution.setState((String) asyncExecutionInfo.get(KEY_STATE));
execution.performAtomicOperationSync(AtomicOperation.EXECUTE_EVENT_LISTENER);
-
- DbSession dbSession = environment.get(DbSession.class);
- dbSession.delete(this);
-
- return null;
}
}
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/MoveToChildActivity.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/MoveToChildActivity.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/MoveToChildActivity.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -25,7 +25,6 @@
import org.jbpm.pvm.internal.model.ExecutionImpl;
import org.jbpm.pvm.internal.model.ActivityImpl;
-
/**
* @author Tom Baeyens
*/
@@ -33,7 +32,7 @@
private static final long serialVersionUID = 1L;
- ActivityImpl activity;
+ private ActivityImpl activity;
public MoveToChildActivity(ActivityImpl activity) {
this.activity = activity;
@@ -49,7 +48,7 @@
return false;
}
- public MessageImpl<?> createAsyncMessage(ExecutionImpl execution) {
+ public MessageImpl createAsyncMessage(ExecutionImpl execution) {
return null;
}
}
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/MoveToParentActivity.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/MoveToParentActivity.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/MoveToParentActivity.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -41,7 +41,7 @@
propagatingExecution.performAtomicOperation(new Signal(null, null));
}
- public MessageImpl<?> createAsyncMessage(ExecutionImpl execution) {
+ public MessageImpl createAsyncMessage(ExecutionImpl execution) {
return null;
}
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/Signal.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/Signal.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/Signal.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -87,7 +87,7 @@
}
@Override
- public MessageImpl<?> createAsyncMessage(ExecutionImpl execution) {
+ public MessageImpl createAsyncMessage(ExecutionImpl execution) {
return null;
}
}
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/SignalMessage.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/SignalMessage.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/SignalMessage.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -27,12 +27,11 @@
import org.jbpm.api.cmd.Environment;
import org.jbpm.pvm.internal.job.MessageImpl;
import org.jbpm.pvm.internal.model.ExecutionImpl;
-import org.jbpm.pvm.internal.session.DbSession;
/**
* @author Tom Baeyens
*/
-public class SignalMessage extends MessageImpl<Object> {
+public class SignalMessage extends MessageImpl {
private static final long serialVersionUID = 1L;
@@ -48,16 +47,11 @@
this.parameters = parameters;
}
- public Object execute(Environment environment) throws Exception {
+ protected void executeVoid(Environment environment) throws Exception {
execution.setState(Execution.STATE_ACTIVE_ROOT);
Signal signal = new Signal(signalName, parameters);
execution.performAtomicOperationSync(signal);
-
- DbSession dbSession = environment.get(DbSession.class);
- dbSession.delete(this);
-
- return null;
}
public String toString() {
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/TransitionEndActivity.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/TransitionEndActivity.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/TransitionEndActivity.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -25,9 +25,7 @@
import org.jbpm.pvm.internal.job.MessageImpl;
import org.jbpm.pvm.internal.model.ActivityImpl;
import org.jbpm.pvm.internal.model.ExecutionImpl;
-import org.jbpm.pvm.internal.model.ObservableElementImpl;
-
/**
* @author Tom Baeyens
*/
@@ -59,7 +57,7 @@
}
}
- public MessageImpl< ? > createAsyncMessage(ExecutionImpl execution) {
+ public MessageImpl createAsyncMessage(ExecutionImpl execution) {
throw new UnsupportedOperationException("please implement me");
}
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/TransitionStartActivity.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/TransitionStartActivity.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/TransitionStartActivity.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -86,7 +86,7 @@
}
}
- public MessageImpl<?> createAsyncMessage(ExecutionImpl execution) {
+ public MessageImpl createAsyncMessage(ExecutionImpl execution) {
throw new UnsupportedOperationException("please implement me");
}
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/TransitionStartActivityMessage.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/TransitionStartActivityMessage.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/TransitionStartActivityMessage.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -24,12 +24,11 @@
import org.jbpm.api.cmd.Environment;
import org.jbpm.pvm.internal.job.MessageImpl;
import org.jbpm.pvm.internal.model.ExecutionImpl;
-import org.jbpm.pvm.internal.session.DbSession;
/**
* @author Tom Baeyens
*/
-public class TransitionStartActivityMessage extends MessageImpl<Object> {
+public class TransitionStartActivityMessage extends MessageImpl {
private static final long serialVersionUID = 1L;
@@ -40,15 +39,10 @@
super(execution);
}
- public Object execute(Environment environment) throws Exception {
+ protected void executeVoid(Environment environment) throws Exception {
AsyncContinuations.restoreState(execution);
execution.performAtomicOperationSync(AtomicOperation.TRANSITION_START_ACTIVITY);
-
- DbSession dbSession = environment.get(DbSession.class);
- dbSession.delete(this);
-
- return null;
}
public String toString() {
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/TransitionTake.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/TransitionTake.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/TransitionTake.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -44,7 +44,7 @@
execution.fire(Event.TAKE, transition, AtomicOperation.TRANSITION_START_ACTIVITY);
}
- public MessageImpl< ? > createAsyncMessage(ExecutionImpl execution) {
+ public MessageImpl createAsyncMessage(ExecutionImpl execution) {
return null;
}
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/processengine/SpringProcessEngine.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/processengine/SpringProcessEngine.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/processengine/SpringProcessEngine.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -22,17 +22,17 @@
package org.jbpm.pvm.internal.processengine;
import org.hibernate.cfg.Configuration;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+import org.springframework.orm.hibernate3.LocalSessionFactoryBean;
+
import org.jbpm.api.ProcessEngine;
import org.jbpm.internal.log.Log;
import org.jbpm.pvm.internal.cfg.ConfigurationImpl;
-import org.jbpm.pvm.internal.env.EnvironmentFactory;
import org.jbpm.pvm.internal.env.EnvironmentImpl;
import org.jbpm.pvm.internal.env.PvmEnvironment;
import org.jbpm.pvm.internal.env.SpringContext;
import org.jbpm.pvm.internal.wire.descriptor.ProvidedObjectDescriptor;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.support.ClassPathXmlApplicationContext;
-import org.springframework.orm.hibernate3.LocalSessionFactoryBean;
/**
* this environment factory will see only the singleton beans.
@@ -42,7 +42,7 @@
*
* @author Andries Inze
*/
-public class SpringProcessEngine extends ProcessEngineImpl implements EnvironmentFactory, ProcessEngine {
+public class SpringProcessEngine extends ProcessEngineImpl {
private static final Log log = Log.getLog(SpringProcessEngine.class.getName());
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/query/DeploymentQueryImpl.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/query/DeploymentQueryImpl.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/query/DeploymentQueryImpl.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -27,6 +27,7 @@
import org.jbpm.api.Deployment;
import org.jbpm.api.DeploymentQuery;
import org.jbpm.pvm.internal.repository.DeploymentImpl;
+import org.jbpm.pvm.internal.util.CollectionUtil;
/**
@@ -102,7 +103,7 @@
}
public List<Deployment> list() {
- return (List<Deployment>) untypedList();
+ return CollectionUtil.checkList(untypedList(), Deployment.class);
}
public Deployment uniqueResult() {
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/query/HistoryActivityInstanceQueryImpl.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/query/HistoryActivityInstanceQueryImpl.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/query/HistoryActivityInstanceQueryImpl.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -29,6 +29,7 @@
import org.jbpm.api.history.HistoryActivityInstance;
import org.jbpm.api.history.HistoryActivityInstanceQuery;
import org.jbpm.pvm.internal.history.model.HistoryActivityInstanceImpl;
+import org.jbpm.pvm.internal.util.CollectionUtil;
/**
@@ -117,7 +118,7 @@
}
public List<HistoryActivityInstance> list() {
- return (List) untypedList();
+ return CollectionUtil.checkList(untypedList(), HistoryActivityInstance.class);
}
public HistoryActivityInstance uniqueResult() {
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/query/HistoryDetailQueryImpl.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/query/HistoryDetailQueryImpl.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/query/HistoryDetailQueryImpl.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -29,6 +29,7 @@
import org.jbpm.api.history.HistoryDetailQuery;
import org.jbpm.pvm.internal.history.model.HistoryCommentImpl;
import org.jbpm.pvm.internal.history.model.HistoryDetailImpl;
+import org.jbpm.pvm.internal.util.CollectionUtil;
/**
@@ -88,7 +89,7 @@
}
public List<HistoryDetail> list() {
- return (List) untypedList();
+ return CollectionUtil.checkList(untypedList(), HistoryDetail.class);
}
public HistoryDetail uniqueResult() {
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/query/HistoryProcessInstanceQueryImpl.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/query/HistoryProcessInstanceQueryImpl.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/query/HistoryProcessInstanceQueryImpl.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -28,6 +28,7 @@
import org.jbpm.api.history.HistoryProcessInstance;
import org.jbpm.api.history.HistoryProcessInstanceQuery;
import org.jbpm.pvm.internal.history.model.HistoryProcessInstanceImpl;
+import org.jbpm.pvm.internal.util.CollectionUtil;
/**
* @author Tom Baeyens
@@ -101,7 +102,7 @@
}
public List<HistoryProcessInstance> list() {
- return (List) untypedList();
+ return CollectionUtil.checkList(untypedList(), HistoryProcessInstance.class);
}
public HistoryProcessInstance uniqueResult() {
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/query/HistoryTaskQueryImpl.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/query/HistoryTaskQueryImpl.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/query/HistoryTaskQueryImpl.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -25,12 +25,12 @@
import java.util.List;
import org.hibernate.Query;
+
import org.jbpm.api.history.HistoryTask;
import org.jbpm.api.history.HistoryTaskQuery;
import org.jbpm.pvm.internal.history.model.HistoryTaskImpl;
-import org.jbpm.pvm.internal.util.Clock;
+import org.jbpm.pvm.internal.util.CollectionUtil;
-
/**
* @author Tom Baeyens
*/
@@ -120,7 +120,7 @@
}
public List<HistoryTask> list() {
- return (List) untypedList();
+ return CollectionUtil.checkList(untypedList(), HistoryTask.class);
}
public HistoryTask uniqueResult() {
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/query/JobQueryImpl.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/query/JobQueryImpl.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/query/JobQueryImpl.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -29,6 +29,7 @@
import org.jbpm.pvm.internal.job.JobImpl;
import org.jbpm.pvm.internal.job.MessageImpl;
import org.jbpm.pvm.internal.job.TimerImpl;
+import org.jbpm.pvm.internal.util.CollectionUtil;
/**
@@ -84,7 +85,7 @@
}
public List<Job> list() {
- return (List<Job>) untypedList();
+ return CollectionUtil.checkList(untypedList(), Job.class);
}
public Job uniqueResult() {
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/query/ProcessDefinitionQueryImpl.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/query/ProcessDefinitionQueryImpl.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/query/ProcessDefinitionQueryImpl.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -36,6 +36,7 @@
import org.jbpm.pvm.internal.repository.DeploymentImpl;
import org.jbpm.pvm.internal.repository.DeploymentProperty;
import org.jbpm.pvm.internal.session.RepositorySession;
+import org.jbpm.pvm.internal.util.CollectionUtil;
/** returns partially initialized ProcessDefinitionImpl's that can only be exposed
@@ -153,7 +154,7 @@
}
public List<ProcessDefinition> list() {
- return (List<ProcessDefinition>) untypedList();
+ return CollectionUtil.checkList(untypedList(), ProcessDefinition.class);
}
public ProcessDefinition uniqueResult() {
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/query/ProcessInstanceQueryImpl.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/query/ProcessInstanceQueryImpl.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/query/ProcessInstanceQueryImpl.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -27,6 +27,7 @@
import org.jbpm.api.ProcessInstance;
import org.jbpm.api.ProcessInstanceQuery;
import org.jbpm.pvm.internal.model.ExecutionImpl;
+import org.jbpm.pvm.internal.util.CollectionUtil;
/**
* @author Tom Baeyens
@@ -45,7 +46,7 @@
}
public List<ProcessInstance> list() {
- return (List<ProcessInstance>) untypedList();
+ return CollectionUtil.checkList(untypedList(), ProcessInstance.class);
}
public String hql() {
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/query/TaskQueryImpl.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/query/TaskQueryImpl.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/query/TaskQueryImpl.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -39,6 +39,7 @@
import org.jbpm.pvm.internal.model.ExecutionImpl;
import org.jbpm.pvm.internal.task.ParticipationImpl;
import org.jbpm.pvm.internal.task.TaskImpl;
+import org.jbpm.pvm.internal.util.CollectionUtil;
/**
* @author Tom Baeyens
@@ -241,9 +242,9 @@
}
public List<Task> list() {
- return (List<Task>) commandService.execute(this);
+ return CollectionUtil.checkList(untypedList(), Task.class);
}
-
+
public Task uniqueResult() {
return (Task) untypedUniqueResult();
}
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/repository/RepositoryServiceImpl.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/repository/RepositoryServiceImpl.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/repository/RepositoryServiceImpl.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -31,7 +31,6 @@
import org.jbpm.api.ProcessDefinitionQuery;
import org.jbpm.api.RepositoryService;
import org.jbpm.api.model.ActivityCoordinates;
-import org.jbpm.pvm.internal.cmd.CommandService;
import org.jbpm.pvm.internal.cmd.CreateDeploymentQueryCmd;
import org.jbpm.pvm.internal.cmd.CreateProcessDefinitionQueryCmd;
import org.jbpm.pvm.internal.cmd.DeleteDeploymentCmd;
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/repository/RepositorySessionImpl.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/repository/RepositorySessionImpl.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/repository/RepositorySessionImpl.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -27,6 +27,7 @@
import org.hibernate.Query;
import org.hibernate.Session;
+
import org.jbpm.api.JbpmException;
import org.jbpm.api.NewDeployment;
import org.jbpm.api.ProcessDefinition;
@@ -37,6 +38,7 @@
import org.jbpm.pvm.internal.model.ProcessDefinitionImpl;
import org.jbpm.pvm.internal.query.ProcessDefinitionQueryImpl;
import org.jbpm.pvm.internal.session.RepositorySession;
+import org.jbpm.pvm.internal.util.CollectionUtil;
/**
* @author Tom Baeyens
@@ -78,8 +80,8 @@
" and execution.state != '"+ExecutionImpl.STATE_SUSPENDED+"'"
);
query.setParameterList("processDefinitionIds", processDefinitionIds);
- List<ExecutionImpl> executions = query.list();
- for (ExecutionImpl execution: executions) {
+ List<?> executions = query.list();
+ for (ExecutionImpl execution: CollectionUtil.checkList(executions, ExecutionImpl.class)) {
execution.suspend();
}
}
@@ -103,8 +105,8 @@
" and execution.state = '"+ExecutionImpl.STATE_SUSPENDED+"'"
);
query.setParameterList("processDefinitionIds", processDefinitionIds);
- List<ExecutionImpl> executions = query.list();
- for (ExecutionImpl execution: executions) {
+ List<?> executions = query.list();
+ for (ExecutionImpl execution: CollectionUtil.checkList(executions, ExecutionImpl.class)) {
execution.resume();
}
}
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/script/BshScriptEngine.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/script/BshScriptEngine.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/script/BshScriptEngine.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -112,7 +112,7 @@
if ( ns == null )
{
// Create a global namespace for the interpreter
- Map engineView = new ScriptContextEngineView( scriptContext );
+ Map<String, Object> engineView = new ScriptContextEngineView( scriptContext );
ns = new ExternalNameSpace(
null/*parent*/, "javax_script_context", engineView );
@@ -263,7 +263,7 @@
public <T> T getInterface( Class<T> clasz )
{
try {
- return (T) getGlobal().getInterface( clasz );
+ return clasz.cast(getGlobal().getInterface( clasz ));
} catch ( UtilEvalError utilEvalError ) {
utilEvalError.printStackTrace();
return null;
@@ -296,7 +296,7 @@
try {
bsh.This bshThis = (bsh.This)thiz;
- return (T) bshThis.getInterface( clasz );
+ return clasz.cast(bshThis.getInterface( clasz ));
} catch ( UtilEvalError utilEvalError ) {
utilEvalError.printStackTrace( System.err );
return null;
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/script/GroovyScriptEngine.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/script/GroovyScriptEngine.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/script/GroovyScriptEngine.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -31,6 +31,7 @@
package org.jbpm.pvm.internal.script;
import java.io.*;
import java.util.*;
+
import javax.script.*;
import groovy.lang.*;
import org.codehaus.groovy.syntax.SyntaxException;
@@ -47,7 +48,7 @@
private static boolean DEBUG = false;
// script-string-to-generated Class map
- private Map<String, Class> classMap;
+ private Map<String, Class<?>> classMap;
// global closures map - this is used to simulate a single
// global functions namespace
private Map<String, Closure> globalClosures;
@@ -64,8 +65,8 @@
}
public GroovyScriptEngine() {
- classMap = Collections.synchronizedMap(new HashMap<String, Class>());
- globalClosures = Collections.synchronizedMap(new HashMap<String, Closure>());
+ classMap = new Hashtable<String, Class<?>>();
+ globalClosures = new Hashtable<String, Closure>();
loader = new GroovyClassLoader(getParentLoader(),
new CompilerConfiguration());
}
@@ -148,7 +149,7 @@
}
// package-privates
- Object eval(Class scriptClass, final ScriptContext ctx) throws ScriptException {
+ Object eval(Class<?> scriptClass, final ScriptContext ctx) throws ScriptException {
//add context to bindings
ctx.setAttribute("context", ctx, ScriptContext.ENGINE_SCOPE);
@@ -246,11 +247,11 @@
}
}
- Class getScriptClass(String script)
+ Class<?> getScriptClass(String script)
throws SyntaxException,
CompilationFailedException,
IOException {
- Class clazz = classMap.get(script);
+ Class<?> clazz = classMap.get(script);
if (clazz != null) {
return clazz;
}
@@ -261,10 +262,7 @@
return clazz;
}
- //-- Internals only below this point
-
- // invokes the specified method/function on the given object.
- private Object invokeImpl(Object thiz, String name, Object... args)
+ Object invokeImpl(Object thiz, String name, Object... args)
throws ScriptException, NoSuchMethodException {
if (name == null) {
throw new NullPointerException("method name is null");
@@ -288,7 +286,7 @@
return callGlobal(name, args, context);
}
- private Object callGlobal(String name, Object[] args, ScriptContext ctx) {
+ Object callGlobal(String name, Object[] args, ScriptContext ctx) {
Closure closure = globalClosures.get(name);
if (closure != null) {
return closure.call(args);
@@ -313,7 +311,7 @@
if (clazz == null || !clazz.isInterface()) {
throw new IllegalArgumentException("interface Class expected");
}
- return (T) Proxy.newProxyInstance(
+ return clazz.cast(Proxy.newProxyInstance(
clazz.getClassLoader(),
new Class[] { clazz },
new InvocationHandler() {
@@ -321,7 +319,7 @@
throws Throwable {
return invokeImpl(thiz, m.getName(), args);
}
- });
+ }));
}
// determine appropriate class loader to serve as parent loader
@@ -330,7 +328,7 @@
// check whether thread context loader can "see" Groovy Script class
ClassLoader ctxtLoader = Thread.currentThread().getContextClassLoader();
try {
- Class c = ctxtLoader.loadClass("org.codehaus.groovy.Script");
+ Class<?> c = ctxtLoader.loadClass("org.codehaus.groovy.Script");
if (c == Script.class) {
return ctxtLoader;
}
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/script/JuelScriptEngine.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/script/JuelScriptEngine.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/script/JuelScriptEngine.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -25,7 +25,6 @@
import java.io.Reader;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
-import java.util.Properties;
import javax.el.ArrayELResolver;
import javax.el.BeanELResolver;
@@ -59,7 +58,7 @@
implements Compilable
{
private ScriptEngineFactory factory;
- private ExpressionFactory exprFactory;
+ ExpressionFactory exprFactory;
public JuelScriptEngine(ScriptEngineFactory factory)
{
@@ -162,7 +161,7 @@
return elContext;
}
- private ELResolver makeResolver()
+ ELResolver makeResolver()
{
CompositeELResolver chain = new CompositeELResolver();
@@ -231,7 +230,7 @@
private static Method getPrintMethod()
{
- Class myClass;
+ Class<?> myClass;
try
{
myClass = JuelScriptEngine.class;
@@ -255,7 +254,7 @@
private static Method getImportMethod()
{
- Class myClass;
+ Class<?> myClass;
try
{
myClass = JuelScriptEngine.class;
@@ -277,11 +276,11 @@
public static void importFunctions(ScriptContext ctx, String namespace, Object obj)
{
- Class clazz = null;
+ Class<?> clazz = null;
- if (obj instanceof Class)
+ if (obj instanceof Class<?>)
{
- clazz = (Class)obj;
+ clazz = (Class<?>)obj;
} else {
if (obj instanceof String)
{
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/script/ScriptContextEngineView.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/script/ScriptContextEngineView.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/script/ScriptContextEngineView.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -84,7 +84,7 @@
*/
public boolean containsValue( Object value )
{
- Set values = totalValueSet();
+ Set<Object> values = totalValueSet();
return values.contains( value );
}
@@ -208,7 +208,7 @@
*
* @return a set view of the keys contained in this map.
*/
- public Set keySet()
+ public Set<String> keySet()
{
return totalKeySet();
}
@@ -220,7 +220,7 @@
*
* @return a collection view of the values contained in this map.
*/
- public Collection values()
+ public Collection<Object> values()
{
return totalValueSet();
}
@@ -245,18 +245,18 @@
throw new Error("unimplemented");
}
- private Set totalKeySet()
+ private Set<String> totalKeySet()
{
- Set keys = new HashSet();
+ Set<String> keys = new HashSet<String>();
List<Integer> scopes = context.getScopes();
for ( int i : scopes ) {
keys.addAll( context.getBindings( i ).keySet() );
}
return Collections.unmodifiableSet(keys);
}
- private Set totalValueSet()
+ private Set<Object> totalValueSet()
{
- Set values = new HashSet();
+ Set<Object> values = new HashSet<Object>();
List<Integer> scopes = context.getScopes();
for ( int i : scopes ) {
values.addAll( context.getBindings( i ).values() );
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/script/XPathScriptEngine.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/script/XPathScriptEngine.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/script/XPathScriptEngine.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -151,7 +151,7 @@
// Internals only below this point
// find a variable of given qname in given context
- private static Object findVariable(QName qname, ScriptContext ctx) {
+ static Object findVariable(QName qname, ScriptContext ctx) {
String name;
int scope;
@@ -178,23 +178,6 @@
return null;
}
- private static void collectNamespaces(Map<String, String> map, Bindings scope) {
- for (String key : scope.keySet()) {
- if (key.startsWith(XMLNS_COLON)) {
- Object uri = scope.get(key);
- // collect all variables starting with "xmlns:" and
- // collect the prefix to URI mappings.
- String prefix = key.substring(XMLNS_COLON.length());
- if (uri instanceof String) {
- String tmp = (String) uri;
- if (tmp.length() != 0) {
- map.put(prefix, tmp);
- }
- }
- }
- }
- }
-
private static NamespaceContext makeNamespaceContext(ScriptContext ctx) {
// namespace prefix-to-URI mappings
final Map<String, String> namespaces = new HashMap<String, String>();
@@ -246,11 +229,11 @@
return null;
}
- public Iterator getPrefixes(String namespaceURI) {
+ public Iterator<String> getPrefixes(String namespaceURI) {
if (namespaceURI == null) {
throw new IllegalArgumentException();
}
- List list = new ArrayList();
+ List<String> list = new ArrayList<String>();
for (String prefix : namespaces.keySet()) {
String uri = namespaces.get(prefix);
if (namespaceURI.equals(uri)) {
@@ -262,12 +245,12 @@
};
}
- private static XPathFunction makeXPathFunction(final Constructor ctr, int arity) {
+ private static XPathFunction makeXPathFunction(final Constructor<?> ctr, int arity) {
if (ctr.getParameterTypes().length != arity) {
return null;
}
return new XPathFunction() {
-
+ @SuppressWarnings("unchecked")
public Object evaluate(List args) {
try {
return ctr.newInstance(args.toArray());
@@ -284,7 +267,7 @@
if (Modifier.isStatic(modifiers) && numArgs == arity) {
// static method. expose "as is".
return new XPathFunction() {
-
+ @SuppressWarnings("unchecked")
public Object evaluate(List args) {
try {
return method.invoke(null, args.toArray());
@@ -296,9 +279,9 @@
} else if ((numArgs + 1) == arity) {
// instance method. treat the first arg as 'this'
return new XPathFunction() {
-
+ @SuppressWarnings("unchecked")
public Object evaluate(List args) {
- List tmp = args.subList(1, args.size());
+ List<?> tmp = args.subList(1, args.size());
try {
return method.invoke(args.get(0), tmp.toArray());
} catch (Exception exp) {
@@ -313,7 +296,7 @@
private static XPathFunction makeXPathFunction(final String funcName, final Invocable invocable) {
return new XPathFunction() {
-
+ @SuppressWarnings("unchecked")
public Object evaluate(List args) {
try {
return invocable.invokeFunction(funcName, args.toArray());
@@ -325,7 +308,7 @@
}
// make a XPathFunction from given object
- private static XPathFunction makeXPathFunction(QName qname, Object obj, int arity) {
+ static XPathFunction makeXPathFunction(QName qname, Object obj, int arity) {
if (obj == null) {
return null;
} else if (obj instanceof XPathFunction) {
@@ -334,9 +317,9 @@
} else if (obj instanceof Method) {
// a Method object. wrap as XPathFunction
return makeXPathFunction((Method) obj, arity);
- } else if (obj instanceof Constructor) {
+ } else if (obj instanceof Constructor<?>) {
// a Constructor object. wrap as XPathFunction
- return makeXPathFunction((Constructor) obj, arity);
+ return makeXPathFunction((Constructor<?>) obj, arity);
} else if (obj instanceof Invocable) {
// wrap a script function as XPathFunction. Using this,
// scripts from other languages (for eg. JavaScript) can use
@@ -404,7 +387,7 @@
}
return null;
}
- private Object evalXPath(XPathExpression expr, final ScriptContext ctx) throws ScriptException {
+ Object evalXPath(XPathExpression expr, final ScriptContext ctx) throws ScriptException {
try {
Object resultType = getVariable(ctx, XPATH_RESULT_TYPE);
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/session/DbSession.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/session/DbSession.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/session/DbSession.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -94,13 +94,13 @@
// job methods //////////////////////////////////////////////////////////////
/** the first job to finish among eligible and non-locked jobs or null if none */
- public JobImpl<?> findFirstAcquirableJob();
+ public JobImpl findFirstAcquirableJob();
/** the list of jobs of the process instance that mustn't be concurrent */
- public List<JobImpl<?>> findExclusiveJobs(Execution processInstance);
+ public List<JobImpl> findExclusiveJobs(Execution processInstance);
/** the first job to finish among non-owned jobs or null if none */
- public JobImpl<?> findFirstDueJob();
+ public JobImpl findFirstDueJob();
/** returns a list of start process timers for the given process definition */
public List<StartProcessTimer> findStartProcessTimers(String processDefinitionId);
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/svc/AsyncCommandMessage.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/svc/AsyncCommandMessage.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/svc/AsyncCommandMessage.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -24,21 +24,19 @@
import org.jbpm.api.Execution;
import org.jbpm.api.cmd.Command;
import org.jbpm.api.cmd.Environment;
-import org.jbpm.api.job.Job;
import org.jbpm.pvm.internal.cmd.CommandService;
import org.jbpm.pvm.internal.env.EnvironmentImpl;
import org.jbpm.pvm.internal.job.MessageImpl;
-
/**
* @author Tom Baeyens
*/
-public class AsyncCommandMessage extends MessageImpl<Object> {
+public class AsyncCommandMessage extends MessageImpl {
private static final long serialVersionUID = 1L;
- Command<?> command;
- String userId;
+ private Command<?> command;
+ private String userId;
public AsyncCommandMessage(Command<?> command) {
this.command = command;
@@ -49,22 +47,23 @@
this.userId = userId;
}
- public Object execute(Environment environmentInterface) throws Exception {
- EnvironmentImpl environment = (EnvironmentImpl) environmentInterface;
+ protected void executeVoid(Environment environment) throws Exception {
execution.setState(Execution.STATE_ACTIVE_ROOT);
- if (userId!=null) {
- environment.setAuthenticatedUserId(userId);
- }
- try {
- CommandService commandService = environment.get(CommandService.class);
+ CommandService commandService = environment.get(CommandService.class);
+ if (userId == null) {
commandService.execute(command);
- } finally {
- if (userId!=null) {
- environment.setAuthenticatedUserId(null);
+ }
+ else {
+ EnvironmentImpl environmentImpl = (EnvironmentImpl) environment;
+ environmentImpl.setAuthenticatedUserId(userId);
+ try {
+ commandService.execute(command);
}
+ finally {
+ environmentImpl.setAuthenticatedUserId(null);
+ }
}
- return null;
}
public String toString() {
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/svc/SerializeInterceptor.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/svc/SerializeInterceptor.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/svc/SerializeInterceptor.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -23,6 +23,7 @@
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
+import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
@@ -30,32 +31,38 @@
import org.jbpm.api.cmd.Command;
import org.jbpm.internal.log.Log;
-
/**
* @author Tom Baeyens
*/
public class SerializeInterceptor extends Interceptor {
-
+
private static final Log log = Log.getLog(SerializeInterceptor.class.getName());
+ @SuppressWarnings("unchecked")
public <T> T execute(Command<T> command) {
- log.info("serializing command "+command);
+ log.info("serializing command " + command);
Command<T> serializedCommand = (Command<T>) serialize(command);
T returnValue = next.execute(serializedCommand);
- T serializedReturnValue = (T) serialize(returnValue);
- return serializedReturnValue;
+ return (T) serialize(returnValue);
}
- public Object serialize(Object o) {
+ private static Object serialize(Object o) {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(o);
+ oos.close();
+
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
return ois.readObject();
- } catch (Exception e) {
+ }
+ catch (IOException e) {
throw new JbpmException("serialization exception", e);
}
+ catch (ClassNotFoundException e) {
+ // should not happen, class is already loaded
+ throw new AssertionError(e);
+ }
}
}
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/task/SwimlaneDefinitionImpl.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/task/SwimlaneDefinitionImpl.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/task/SwimlaneDefinitionImpl.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -21,12 +21,10 @@
*/
package org.jbpm.pvm.internal.task;
-import java.io.Serializable;
-
/**
* is a process role (aka participatingUser).
*/
-public class SwimlaneDefinitionImpl extends AssignableDefinitionImpl implements Serializable {
+public class SwimlaneDefinitionImpl extends AssignableDefinitionImpl {
private static final long serialVersionUID = 1L;
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/task/TaskDefinitionImpl.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/task/TaskDefinitionImpl.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/task/TaskDefinitionImpl.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -21,7 +21,6 @@
*/
package org.jbpm.pvm.internal.task;
-import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
@@ -30,7 +29,7 @@
/**
* defines a task and how the actor(s) must be calculated at runtime.
*/
-public class TaskDefinitionImpl extends AssignableDefinitionImpl implements Serializable {
+public class TaskDefinitionImpl extends AssignableDefinitionImpl {
private static final long serialVersionUID = 1L;
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/tx/SpringCommandCallback.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/tx/SpringCommandCallback.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/tx/SpringCommandCallback.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -34,9 +34,9 @@
public class SpringCommandCallback implements TransactionCallback {
CommandService next;
- Command<Object> command;
+ Command<?> command;
- public SpringCommandCallback(CommandService next, Command command) {
+ public SpringCommandCallback(CommandService next, Command<?> command) {
this.next = next;
this.command = command;
}
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/tx/SpringTransaction.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/tx/SpringTransaction.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/tx/SpringTransaction.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -27,11 +27,10 @@
import org.springframework.transaction.support.TransactionSynchronizationManager;
-
/**
* @author Tom Baeyens
*/
-public class SpringTransaction extends AbstractTransaction implements Transaction, Serializable {
+public class SpringTransaction extends AbstractTransaction implements Serializable {
private static final long serialVersionUID = 1L;
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/tx/SpringTransactionFactory.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/tx/SpringTransactionFactory.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/tx/SpringTransactionFactory.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -24,8 +24,6 @@
import org.hibernate.transaction.JDBCTransaction;
import org.hibernate.transaction.TransactionFactory;
-import org.springframework.transaction.support.TransactionSynchronizationManager;
-
/**
* Spring-aware implementation of the Hibernate TransactionFactory interface, aware of
* Spring-synchronized transactions (in particular Spring-managed JTA transactions)
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/tx/StandardTransaction.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/tx/StandardTransaction.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/tx/StandardTransaction.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -35,7 +35,7 @@
* non thread safe (which is ok).
* @author Tom Baeyens
*/
-public class StandardTransaction extends AbstractTransaction implements Transaction, Serializable {
+public class StandardTransaction extends AbstractTransaction implements Serializable {
private static final long serialVersionUID = 1L;
private static Log log = Log.getLog(StandardTransaction.class.getName());
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/tx/StandardTransactionInterceptor.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/tx/StandardTransactionInterceptor.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/tx/StandardTransactionInterceptor.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -23,11 +23,9 @@
import org.jbpm.api.JbpmException;
import org.jbpm.api.cmd.Command;
-import org.jbpm.internal.log.Log;
import org.jbpm.pvm.internal.env.EnvironmentImpl;
import org.jbpm.pvm.internal.svc.Interceptor;
-
/** calls setRollbackOnly on the transaction in the environment
* in case an exception occurs during execution of the command.
*
@@ -35,8 +33,6 @@
*/
public class StandardTransactionInterceptor extends Interceptor {
- private static final Log log = Log.getLog(StandardTransactionInterceptor.class.getName());
-
public <T> T execute(Command<T> command) {
EnvironmentImpl environment = EnvironmentImpl.getCurrent();
if (environment==null) {
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/type/converter/SerializableToBytesConverter.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/type/converter/SerializableToBytesConverter.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/type/converter/SerializableToBytesConverter.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -30,7 +30,6 @@
import org.jbpm.api.JbpmException;
import org.jbpm.pvm.internal.env.EnvironmentImpl;
-import org.jbpm.pvm.internal.model.ExecutionImpl;
import org.jbpm.pvm.internal.model.ScopeInstanceImpl;
import org.jbpm.pvm.internal.repository.DeploymentObjectInputStream;
import org.jbpm.pvm.internal.tx.DeserializedObject;
Added: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/util/CollectionUtil.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/util/CollectionUtil.java (rev 0)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/util/CollectionUtil.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -0,0 +1,115 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jbpm.pvm.internal.util;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author Alejandro Guizar
+ */
+public class CollectionUtil {
+
+ /** Indicates whether collection elements should be actually checked. */
+ private static final boolean DEBUG = false;
+
+ private CollectionUtil() {
+ // hide default constructor to prevent instantiation
+ }
+
+ /**
+ * Ensures that all elements of the given collection can be cast to a desired type.
+ *
+ * @param collection the collection to check
+ * @param type the desired type
+ * @return a collection of the desired type
+ * @throws ClassCastException if an element cannot be cast to the desired type
+ */
+ @SuppressWarnings("unchecked")
+ public static <E> Collection<E> checkCollection(Collection<?> collection, Class<E> type) {
+ if (DEBUG) {
+ Collection<E> copy = new ArrayList<E>(collection.size());
+ for (Object element : collection) {
+ copy.add(type.cast(element));
+ }
+ return copy;
+ }
+ return (Collection<E>) collection;
+ }
+
+ /**
+ * Ensures that all elements of the given list can be cast to a desired type.
+ *
+ * @param list the list to check
+ * @param type the desired type
+ * @return a list of the desired type
+ * @throws ClassCastException if an element cannot be cast to the desired type
+ */
+ @SuppressWarnings("unchecked")
+ public static <E> List<E> checkList(List<?> list, Class<E> type) {
+ if (DEBUG) {
+ List<E> copy = new ArrayList<E>(list.size());
+ for (Object element : list) {
+ copy.add(type.cast(element));
+ }
+ return copy;
+ }
+ return (List<E>) list;
+ }
+
+ /**
+ * Ensures that all elements of the given set can be cast to a desired type.
+ *
+ * @param list the set to check
+ * @param type the desired type
+ * @return a set of the desired type
+ * @throws ClassCastException if an element cannot be cast to the desired type
+ */
+ @SuppressWarnings("unchecked")
+ public static <E> Set<E> checkSet(Set<?> set, Class<E> type) {
+ if (DEBUG) {
+ Set<E> copy = new HashSet<E>();
+ for (Object element : set) {
+ copy.add(type.cast(element));
+ }
+ return copy;
+ }
+ return (Set<E>) set;
+ }
+
+ @SuppressWarnings("unchecked")
+ public static <K, V> Map<K, V> checkMap(Map<?, ?> map, Class<K> keyType, Class<V> valueType) {
+ if (DEBUG) {
+ Map<K, V> copy = new HashMap<K, V>();
+ for (Map.Entry<?, ?> entry : map.entrySet()) {
+ copy.put(keyType.cast(entry.getKey()), valueType.cast(entry.getValue()));
+ }
+ return copy;
+ }
+ return (Map<K, V>) map;
+ }
+}
Property changes on: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/util/CollectionUtil.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ native
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/util/EqualsUtil.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/util/EqualsUtil.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/util/EqualsUtil.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -21,39 +21,55 @@
*/
package org.jbpm.pvm.internal.util;
-public abstract class EqualsUtil {
+public class EqualsUtil {
+ private EqualsUtil() {
+ // hide default constructor to prevent instantiation
+ }
+
+ /**
+ * hack to support comparing hibernate proxies against the real objects. since it falls back
+ * to ==, clients do not need to override {@link Object#hashCode()}.
+ *
+ * @deprecated hack does not work
+ * @see <a href="https://jira.jboss.org/jira/browse/JBPM-2489">JBPM-2489</a>
+ */
+ @Deprecated
public static boolean equals(Object thisObject, Object otherObject) {
- if ( (thisObject==null) || (otherObject==null) ) return false;
-
+ if ((thisObject == null) || (otherObject == null))
+ return false;
+
if (isProxy(otherObject)) {
return otherObject.equals(thisObject);
- } else {
- return otherObject==thisObject;
}
+ else {
+ return otherObject == thisObject;
+ }
}
- static boolean isInitialized = false;
- static boolean isHibernateInClasspth = true;
- static Class<?> hibernateProxyClass = null;
-
- static boolean isProxy(Object otherObject) {
+ private static boolean isInitialized;
+ private static boolean isHibernateInClasspath = true;
+ private static Class<?> hibernateProxyClass;
+
+ private static boolean isProxy(Object otherObject) {
boolean isProxy = false;
- if (!isInitialized) initializeHibernateProxyClass();
+ if (!isInitialized)
+ initializeHibernateProxyClass();
- if (isHibernateInClasspth) {
+ if (isHibernateInClasspath) {
return hibernateProxyClass.isAssignableFrom(otherObject.getClass());
}
return isProxy;
}
- static synchronized void initializeHibernateProxyClass() {
+ private static synchronized void initializeHibernateProxyClass() {
try {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
hibernateProxyClass = classLoader.loadClass("org.hibernate.proxy.HibernateProxy");
- } catch (ClassNotFoundException e) {
- isHibernateInClasspth = false;
}
+ catch (ClassNotFoundException e) {
+ isHibernateInClasspath = false;
+ }
isInitialized = true;
}
}
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/util/StringUtil.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/util/StringUtil.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/util/StringUtil.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -31,14 +31,18 @@
/**
* @author Tom Baeyens
*/
-public abstract class StringUtil {
+public class StringUtil {
+ private StringUtil() {
+ // hide default constructor to prevent instantiation
+ }
+
public static List<String> tokenize(String text, String delimiter) {
if (delimiter==null) {
throw new JbpmException("delimiter is null");
}
if (text==null) {
- return Collections.EMPTY_LIST;
+ return Collections.emptyList();
}
List<String> pieces = new ArrayList<String>();
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/wire/WireContext.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/wire/WireContext.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/wire/WireContext.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -640,9 +640,7 @@
if (descriptors!=null) {
Descriptor descriptor = descriptors.get(objectName);
if (descriptor!=null) {
- if (wireEvent==null) {
- wireEvent = new WireObjectEventInfo(eventName, objectName, object);
- }
+ wireEvent = new WireObjectEventInfo(eventName, objectName, object);
descriptor.fire(eventName, wireEvent);
}
}
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/wire/binding/ListBinding.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/wire/binding/ListBinding.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/wire/binding/ListBinding.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -23,11 +23,10 @@
import java.util.List;
-import org.jbpm.pvm.internal.jobexecutor.JobExecutor;
import org.jbpm.pvm.internal.wire.descriptor.CollectionDescriptor;
import org.jbpm.pvm.internal.wire.descriptor.ListDescriptor;
-/** parses a descriptor for creating a {@link JobExecutor}.
+/** parses a descriptor for creating a {@link List}.
*
* See schema docs for more details.
*
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/wire/descriptor/HibernateSessionFactoryDescriptor.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/wire/descriptor/HibernateSessionFactoryDescriptor.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/wire/descriptor/HibernateSessionFactoryDescriptor.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -21,6 +21,9 @@
*/
package org.jbpm.pvm.internal.wire.descriptor;
+import org.hibernate.SessionFactory;
+import org.hibernate.cfg.Configuration;
+
import org.jbpm.internal.log.Log;
import org.jbpm.pvm.internal.util.Listener;
import org.jbpm.pvm.internal.wire.Descriptor;
@@ -28,18 +31,13 @@
import org.jbpm.pvm.internal.wire.WireDefinition;
import org.jbpm.pvm.internal.wire.WireException;
-import org.hibernate.SessionFactory;
-import org.hibernate.cfg.Configuration;
-
-import java.net.URL;
-
/**
* @author Tom Baeyens
*/
public class HibernateSessionFactoryDescriptor extends AbstractDescriptor {
private static final long serialVersionUID = 1L;
- private static final Log log = Log.getLog(HibernateSessionFactoryDescriptor.class.getName());
+ static final Log log = Log.getLog(HibernateSessionFactoryDescriptor.class.getName());
String configurationName;
Descriptor configurationDescriptor;
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/wire/descriptor/ShortDescriptor.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/wire/descriptor/ShortDescriptor.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/wire/descriptor/ShortDescriptor.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -32,7 +32,7 @@
*
* @see Descriptor
*/
-public class ShortDescriptor extends AbstractDescriptor implements Descriptor {
+public class ShortDescriptor extends AbstractDescriptor {
private static final long serialVersionUID = 1L;
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/wire/descriptor/StringDescriptor.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/wire/descriptor/StringDescriptor.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/wire/descriptor/StringDescriptor.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -12,7 +12,7 @@
*
* @see Descriptor
*/
-public class StringDescriptor extends AbstractDescriptor implements Descriptor {
+public class StringDescriptor extends AbstractDescriptor {
private static final long serialVersionUID = 1L;
Modified: jbpm4/trunk/modules/pvm/src/main/resources/jbpm.execution.hbm.xml
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/resources/jbpm.execution.hbm.xml 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/resources/jbpm.execution.hbm.xml 2010-06-24 06:06:27 UTC (rev 6435)
@@ -207,7 +207,7 @@
<discriminator column="CLASS_" />
<version name="dbversion" column="DBVERSION_" />
- <property name="duedate" column="DUEDATE_" type="timestamp" index="IDX_JOBDUEDATE" />
+ <property name="dueDate" column="DUEDATE_" type="timestamp" index="IDX_JOBDUEDATE" />
<property name="state" column="STATE_" />
<property name="isExclusive" column="ISEXCLUSIVE_" />
<property name="lockOwner" column="LOCKOWNER_" />
@@ -260,7 +260,7 @@
<![CDATA[
select t
from org.jbpm.pvm.internal.job.TimerImpl as t
- order by duedate asc
+ order by dueDate asc
]]>
</query>
@@ -276,7 +276,7 @@
select job
from org.jbpm.pvm.internal.job.JobImpl as job
where job.retries = 0
- order by duedate asc
+ order by dueDate asc
]]>
</query>
@@ -285,19 +285,11 @@
<![CDATA[
select job
from org.jbpm.pvm.internal.job.JobImpl as job
- where ( ( (job.lockExpirationTime is null)
- or (job.lockExpirationTime <= :now)
- )
- and
- ( (job.duedate is null)
- or (job.duedate <= :now)
- )
- and
- ( job.retries > 0 )
- and
- ( job.state != 'suspended' )
- )
- order by job.duedate asc
+ where (job.lockExpirationTime is null or job.lockExpirationTime <= :now)
+ and (job.dueDate is null or job.dueDate <= :now)
+ and job.retries > 0
+ and job.state != 'suspended'
+ order by job.dueDate asc
]]>
</query>
@@ -310,10 +302,8 @@
and job.isExclusive = true
and job.retries > 0
and job.state != 'suspended'
- and ( (job.duedate is null)
- or (job.duedate <= :now)
- )
- order by job.duedate asc
+ and (job.dueDate is null or job.dueDate <= :now)
+ order by job.dueDate asc
]]>
</query>
@@ -324,7 +314,7 @@
where job.lockOwner is null
and job.retries > 0
and job.state != 'suspended'
- order by job.duedate asc
+ order by job.dueDate asc
]]>
</query>
@@ -356,4 +346,12 @@
]]>
</query>
+ <query name="findProcessInstanceIds">
+ <![CDATA[
+ select processInstance.id
+ from org.jbpm.pvm.internal.model.ExecutionImpl as processInstance
+ where processInstance.processDefinitionId = :processDefinitionId
+ and processInstance.parent is null
+ ]]>
+ </query>
</hibernate-mapping>
\ No newline at end of file
Modified: jbpm4/trunk/modules/pvm/src/main/resources/jbpm.identity.hbm.xml
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/resources/jbpm.identity.hbm.xml 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/pvm/src/main/resources/jbpm.identity.hbm.xml 2010-06-24 06:06:27 UTC (rev 6435)
@@ -56,5 +56,25 @@
foreign-key="FK_GROUP_PARENT"
index="IDX_GROUP_PARENT"/>
</class>
-
+
+ <query name="findGroupsByUser">
+ <![CDATA[
+ select distinct g
+ from org.jbpm.pvm.internal.identity.impl.MembershipImpl m
+ join m.user u
+ join m.group g
+ where u.id = :userId
+ ]]>
+ </query>
+
+ <query name="findGroupsByUserAndGroupType">
+ <![CDATA[
+ select distinct g
+ from org.jbpm.pvm.internal.identity.impl.MembershipImpl m
+ join m.user u
+ join m.group g
+ where u.id = :userId
+ and g.type = :groupType
+ ]]>
+ </query>
</hibernate-mapping>
\ No newline at end of file
Modified: jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/bpmn/test/intermediatecatch/IntermediateCatchTimerEventTest.java
===================================================================
--- jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/bpmn/test/intermediatecatch/IntermediateCatchTimerEventTest.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/bpmn/test/intermediatecatch/IntermediateCatchTimerEventTest.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -160,7 +160,7 @@
Job timerJob = managementService.createJobQuery().processInstanceId(pi.getId()).uniqueResult();
long expectedTimerDueDate = processStartTime + (5 * 60 * 60 * 1000); // expected = 5 hours in ms
- assertEquals(expectedTimerDueDate, timerJob.getDuedate().getTime());
+ assertEquals(expectedTimerDueDate, timerJob.getDueDate().getTime());
managementService.executeJob(timerJob.getId());
assertProcessInstanceEnded(pi);
@@ -174,7 +174,7 @@
Job timerJob = managementService.createJobQuery().processInstanceId(pi.getId()).uniqueResult();
Date expectedDueDate = DateUtils.getDateAtMidnight(10, Calendar.OCTOBER, 2099);
- assertEquals(expectedDueDate.getTime(), timerJob.getDuedate().getTime());
+ assertEquals(expectedDueDate.getTime(), timerJob.getDueDate().getTime());
managementService.executeJob(timerJob.getId());
assertProcessInstanceEnded(pi);
@@ -188,7 +188,7 @@
CollectionAssertions.assertContainsSameElements(pi.findActiveActivityNames(), "intermediateTimer");
Job timerJob = managementService.createJobQuery().processInstanceId(pi.getId()).uniqueResult();
- assertEquals(DateUtils.getDate(20, Calendar.JANUARY, 2010, 0, 2, 0).getTime(), timerJob.getDuedate().getTime());
+ assertEquals(DateUtils.getDate(20, Calendar.JANUARY, 2010, 0, 2, 0).getTime(), timerJob.getDueDate().getTime());
managementService.executeJob(timerJob.getId());
assertProcessInstanceEnded(pi);
@@ -202,13 +202,10 @@
CollectionAssertions.assertContainsSameElements(pi.findActiveActivityNames(), "intermediateTimer");
Job timerJob = managementService.createJobQuery().processInstanceId(pi.getId()).uniqueResult();
- assertEquals(DateUtils.getDate(22, Calendar.JANUARY, 2010, 23, 0, 0).getTime(), timerJob.getDuedate().getTime());
+ assertEquals(DateUtils.getDate(22, Calendar.JANUARY, 2010, 23, 0, 0).getTime(), timerJob.getDueDate().getTime());
managementService.executeJob(timerJob.getId());
assertProcessInstanceEnded(pi);
}
-
-
-
}
Modified: jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/bpmn/test/startevent/TimerStartEventTest.java
===================================================================
--- jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/bpmn/test/startevent/TimerStartEventTest.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/bpmn/test/startevent/TimerStartEventTest.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -164,7 +164,7 @@
// After deployment, there should be one job in the database that starts a new process instance
Job startProcessTimer = managementService.createJobQuery().uniqueResult();
assertNotNull(startProcessTimer);
- assertEquals(DateUtils.getDateAtMidnight(10, Calendar.OCTOBER, 2099).getTime(), startProcessTimer.getDuedate().getTime());
+ assertEquals(DateUtils.getDateAtMidnight(10, Calendar.OCTOBER, 2099).getTime(), startProcessTimer.getDueDate().getTime());
ProcessInstanceQuery procInstQuery = executionService.createProcessInstanceQuery()
.processDefinitionId(findProcessDefinitionId("timerStartFixedDueDate"));
@@ -186,7 +186,7 @@
// After deployment, there should be one job in the database that starts a new process instance
Job startProcessTimer = managementService.createJobQuery().uniqueResult();
assertNotNull(startProcessTimer);
- assertEquals(DateUtils.getDate(10, Calendar.OCTOBER, 2099, 10, 0, 0).getTime(), startProcessTimer.getDuedate().getTime());
+ assertEquals(DateUtils.getDate(10, Calendar.OCTOBER, 2099, 10, 0, 0).getTime(), startProcessTimer.getDueDate().getTime());
// Triggering the job should start a new process instance of the deployed process definition
ProcessInstanceQuery procInstQuery = executionService.createProcessInstanceQuery()
@@ -200,7 +200,7 @@
// Since a timeCycle was used, the job should have been recreated with a new duedate
startProcessTimer = managementService.createJobQuery().uniqueResult();
- assertEquals(DateUtils.getDate(10, Calendar.OCTOBER, 2099, 20, 0, 0).getTime(), startProcessTimer.getDuedate().getTime());
+ assertEquals(DateUtils.getDate(10, Calendar.OCTOBER, 2099, 20, 0, 0).getTime(), startProcessTimer.getDueDate().getTime());
// So we need to manually delete it
@@ -214,7 +214,7 @@
// After deployment, there should be one job in the database that starts a new process instance
Job startProcessTimer = managementService.createJobQuery().uniqueResult();
assertNotNull(startProcessTimer);
- assertEquals(DateUtils.getDate(10, Calendar.OCTOBER, 2099, 22, 0, 0).getTime(), startProcessTimer.getDuedate().getTime());
+ assertEquals(DateUtils.getDate(10, Calendar.OCTOBER, 2099, 22, 0, 0).getTime(), startProcessTimer.getDueDate().getTime());
// Triggering the job should start a new process instance of the deployed process definition
ProcessInstanceQuery procInstQuery = executionService.createProcessInstanceQuery()
@@ -228,7 +228,7 @@
// Since a timeCycle was used, the job should have been recreated with a new duedate
startProcessTimer = managementService.createJobQuery().uniqueResult();
- assertEquals(DateUtils.getDate(11, Calendar.OCTOBER, 2099, 22, 0, 0).getTime(), startProcessTimer.getDuedate().getTime());
+ assertEquals(DateUtils.getDate(11, Calendar.OCTOBER, 2099, 22, 0, 0).getTime(), startProcessTimer.getDueDate().getTime());
// So we need to manually delete it
managementService.deleteJob(Long.valueOf(startProcessTimer.getId()));
Modified: jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/identity/IdentityTest.java
===================================================================
--- jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/identity/IdentityTest.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/identity/IdentityTest.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -21,6 +21,7 @@
*/
package org.jbpm.test.identity;
+import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -63,17 +64,12 @@
identityService.createMembership("jeffyu", redhatGroupId);
List<Group> groups = identityService.findGroupsByUser("jeffyu");
- assertTrue(groups.size() > 0);
-
Set<String> groupNames = new HashSet<String>();
for (Group group : groups) {
groupNames.add(group.getName());
}
- Set<String> expectedGroupNames = new HashSet<String>();
- expectedGroupNames.add("redhat");
-
- assertEquals(expectedGroupNames, groupNames);
+ assertEquals(Collections.singleton("redhat"), groupNames);
identityService.deleteUser("jeffyu");
identityService.deleteGroup(redhatGroupId);
@@ -86,17 +82,12 @@
identityService.createMembership("johndoe", redhatGroupId, "developer");
List<Group> groups = identityService.findGroupsByUserAndGroupType("johndoe", "unit");
- assertTrue(groups.size() > 0);
-
Set<String> groupNames = new HashSet<String>();
for (Group group : groups) {
groupNames.add(group.getName());
}
- Set<String> expectedGroupNames = new HashSet<String>();
- expectedGroupNames.add("redhat");
-
- assertEquals(expectedGroupNames, groupNames);
+ assertEquals(Collections.singleton("redhat"), groupNames);
identityService.deleteUser("johndoe");
identityService.deleteGroup(redhatGroupId);
Modified: jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/task/AssignmentHandlerTest.java
===================================================================
--- jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/task/AssignmentHandlerTest.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/task/AssignmentHandlerTest.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -3,11 +3,13 @@
import java.util.List;
import org.jbpm.api.ProcessInstance;
+import org.jbpm.api.TaskService;
import org.jbpm.api.model.OpenExecution;
import org.jbpm.api.task.Assignable;
import org.jbpm.api.task.AssignmentHandler;
import org.jbpm.api.task.Participation;
import org.jbpm.api.task.Task;
+import org.jbpm.pvm.internal.env.EnvironmentImpl;
import org.jbpm.test.JbpmTestCase;
public class AssignmentHandlerTest extends JbpmTestCase {
@@ -99,7 +101,8 @@
public void assign(Assignable assignable, OpenExecution execution) throws Exception {
// retrieve the participations
Task task = (Task) assignable;
- List<Participation> participations = taskService.getTaskParticipations(task.getId());
+ List<Participation> participations = EnvironmentImpl.getFromCurrent(TaskService.class)
+ .getTaskParticipations(task.getId());
// If the participations list is not empty, assign task to default user
if (!participations.isEmpty()) {
Modified: jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/task/TaskCommentsTest.java
===================================================================
--- jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/task/TaskCommentsTest.java 2010-06-24 03:39:54 UTC (rev 6434)
+++ jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/task/TaskCommentsTest.java 2010-06-24 06:06:27 UTC (rev 6435)
@@ -50,7 +50,7 @@
taskService.addTaskComment(taskId, "i'll clean up the mess");
- List<HistoryComment> taskComments = taskService.getTaskComments(taskId);
+ List<? extends HistoryComment> taskComments = taskService.getTaskComments(taskId);
assertEquals("what a party yesterday", taskComments.get(0).getMessage());
assertEquals("i'll clean up the mess", taskComments.get(1).getMessage());
15 years, 10 months
JBoss JBPM SVN: r6434 - jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/script.
by do-not-reply@jboss.org
Author: rebody
Date: 2010-06-23 23:39:54 -0400 (Wed, 23 Jun 2010)
New Revision: 6434
Modified:
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/script/EnvironmentBindings.java
Log:
JBPM-2897 remove unsupportedOpertionException from EnvironmentBindings
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/script/EnvironmentBindings.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/script/EnvironmentBindings.java 2010-06-23 11:35:02 UTC (rev 6433)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/script/EnvironmentBindings.java 2010-06-24 03:39:54 UTC (rev 6434)
@@ -22,6 +22,7 @@
package org.jbpm.pvm.internal.script;
import java.util.Collection;
+import java.util.Collections;
import java.util.Map;
import java.util.Set;
@@ -32,9 +33,10 @@
/**
* @author Tom Baeyens
+ * @author Huisheng Xu
*/
public class EnvironmentBindings implements Bindings {
-
+
protected EnvironmentImpl environment;
public EnvironmentBindings(String[] readContextNames, String writeContextName) {
@@ -54,38 +56,38 @@
}
public void putAll(Map< ? extends String, ? extends Object> toMerge) {
- throw new UnsupportedOperationException();
+ //
}
public Object remove(Object key) {
- throw new UnsupportedOperationException();
+ return null;
}
public void clear() {
- throw new UnsupportedOperationException();
+ //
}
public boolean containsValue(Object value) {
- throw new UnsupportedOperationException();
+ return false;
}
public Set<java.util.Map.Entry<String, Object>> entrySet() {
- throw new UnsupportedOperationException();
+ return Collections.EMPTY_SET;
}
public boolean isEmpty() {
- throw new UnsupportedOperationException();
+ return true;
}
public Set<String> keySet() {
- throw new UnsupportedOperationException();
+ return Collections.EMPTY_SET;
}
public int size() {
- throw new UnsupportedOperationException();
+ return 0;
}
public Collection<Object> values() {
- throw new UnsupportedOperationException();
+ return Collections.EMPTY_SET;
}
}
15 years, 10 months
JBoss JBPM SVN: r6433 - projects/exception_framework/trunk.
by do-not-reply@jboss.org
Author: eschabell
Date: 2010-06-23 07:35:02 -0400 (Wed, 23 Jun 2010)
New Revision: 6433
Modified:
projects/exception_framework/trunk/pom.xml
Log:
Added plugin version to stop it from trying to use default build with version 1.3.
Modified: projects/exception_framework/trunk/pom.xml
===================================================================
--- projects/exception_framework/trunk/pom.xml 2010-06-23 03:06:09 UTC (rev 6432)
+++ projects/exception_framework/trunk/pom.xml 2010-06-23 11:35:02 UTC (rev 6433)
@@ -7,10 +7,17 @@
<description>A generic jBPM exception framework.</description>
<build>
<plugins>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>1.5</source>
+ <target>1.5</target>
+ </configuration>
+ </plugin>
<plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>build-helper-maven-plugin</artifactId>
- <version>1.5</version>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <version>1.5</version>
<executions>
<execution>
<id>add-resource</id>
@@ -91,4 +98,4 @@
<scope>provided</scope>
</dependency>
</dependencies>
-</project>
\ No newline at end of file
+</project>
15 years, 10 months
JBoss JBPM SVN: r6432 - in jbpm4/trunk/modules: pvm/src/main/java/org/jbpm/pvm/internal/jobexecutor and 1 other directory.
by do-not-reply@jboss.org
Author: alex.guizar(a)jboss.com
Date: 2010-06-22 23:06:09 -0400 (Tue, 22 Jun 2010)
New Revision: 6432
Modified:
jbpm4/trunk/modules/distro/src/main/files/install/build.xml
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/jobexecutor/JobExecutor.java
Log:
JBPM-2893: simplify os conditions in install script
pass join flag to job dispatcher thread
Modified: jbpm4/trunk/modules/distro/src/main/files/install/build.xml
===================================================================
--- jbpm4/trunk/modules/distro/src/main/files/install/build.xml 2010-06-22 23:17:42 UTC (rev 6431)
+++ jbpm4/trunk/modules/distro/src/main/files/install/build.xml 2010-06-23 03:06:09 UTC (rev 6432)
@@ -68,20 +68,13 @@
<property name="signavio.tmp.dir" value="${jbpm.home}/install/generated/signavio-war" />
<property name="signavio.repo.dir.name" value="signavio-repository" />
- <!-- GENERAL CONDITIONS -->
+ <!-- CONTAINER CONDITIONS -->
<condition property="is.jboss.distro.available">
<available file="${jboss.distro.path}" />
</condition>
<condition property="is.tomcat.distro.available">
<available file="${tomcat.distro.path}" />
</condition>
- <condition property="is.linux.unix.or.mac">
- <or>
- <os family="unix" />
- <os family="mac" />
- <os name="sunos" />
- </or>
- </condition>
<condition property="is.hsqldb">
<equals arg1="${database}" arg2="hsqldb" />
</condition>
@@ -90,64 +83,42 @@
<condition property="is.windows">
<os family="windows" />
</condition>
- <condition property="is.not.windows">
- <not>
- <isset property="is.windows" />
- </not>
+ <condition property="is.unix">
+ <os family="unix" />
</condition>
- <condition property="is.mac">
- <os family="mac" />
- </condition>
-
+ <!-- JBOSS CONDITIONS -->
<condition property="is.jboss.500">
<equals arg1="${jboss.version}" arg2="5.0.0.GA" />
</condition>
-
<condition property="is.jboss.510">
<equals arg1="${jboss.version}" arg2="5.1.0.GA" />
</condition>
- <!-- ECLIPSE RELATED CONDITIONS -->
+ <!-- ECLIPSE CONDITIONS -->
<condition property="eclipse.filename" value="eclipse-jee-galileo-win32.zip">
- <contains string="${os.name}" casesensitive="false" substring="win" />
+ <os family="windows" />
</condition>
<condition property="eclipse.tarfilename" value="eclipse-jee-galileo-macosx-cocoa.tar">
- <contains string="${os.name}" casesensitive="false" substring="mac" />
+ <os name="Mac OS X" />
</condition>
<condition property="eclipse.filename" value="${eclipse.tarfilename}.gz">
- <contains string="${os.name}" casesensitive="false" substring="mac" />
+ <os name="Mac OS X" />
</condition>
<condition property="eclipse.tarfilename" value="eclipse-jee-galileo-linux-gtk.tar">
- <and>
- <contains string="${os.name}" casesensitive="false" substring="linux" />
- <not>
- <contains string="${os.arch}" casesensitive="false" substring="64" />
- </not>
- </and>
+ <os name="Linux" arch="i386" />
</condition>
<condition property="eclipse.filename" value="${eclipse.tarfilename}.gz">
- <and>
- <contains string="${os.name}" casesensitive="false" substring="linux" />
- <not>
- <contains string="${os.arch}" casesensitive="false" substring="64" />
- </not>
- </and>
+ <os name="Linux" arch="i386" />
</condition>
<condition property="eclipse.tarfilename" value="eclipse-jee-galileo-linux-gtk-x86_64.tar">
- <and>
- <contains string="${os.name}" casesensitive="false" substring="linux" />
- <contains string="${os.arch}" casesensitive="false" substring="64" />
- </and>
+ <os name="Linux" arch="x86_64" />
</condition>
<condition property="eclipse.filename" value="${eclipse.tarfilename}.gz">
- <and>
- <contains string="${os.name}" casesensitive="false" substring="linux" />
- <contains string="${os.arch}" casesensitive="false" substring="64" />
- </and>
+ <os name="Linux" arch="x86_64" />
</condition>
<property name="eclipse.distro.url"
- value="http://mirror.cc.vt.edu/pub/eclipse/technology/epp/downloads/release/gali..." />
+ value="http://www.eclipse.org/downloads/download.php?file=/technology/epp/downlo..." />
<property name="eclipse.distro.dir" value="downloads" />
<property name="eclipse.parent.dir" value="${jbpm.home}" />
<property name="eclipse.distro.path" value="${eclipse.distro.dir}/${eclipse.filename}" />
@@ -492,10 +463,10 @@
depends="get.tomcat"
description="Downloads tomcat to ${tomcat.distro.dir} if its not available and then unzips tomcat">
<unzip src="${tomcat.distro.path}" dest="${tomcat.parent.dir}" />
- <antcall target="install.tomcat.linuxandmac" />
+ <antcall target="install.tomcat.unix" />
</target>
- <target name="install.tomcat.linuxandmac" if="is.linux.unix.or.mac">
+ <target name="install.tomcat.unix" if="is.unix">
<chmod perm="a+x">
<fileset dir="${tomcat.home}/bin">
<include name="*.sh" />
@@ -801,8 +772,8 @@
<target name="install.eclipse"
depends="get.eclipse"
description="unzips eclipse, downloads eclipse if it is not available in ${eclipse.distro.dir}">
+ <antcall target="internal.install.eclipse.unix" />
<antcall target="internal.install.eclipse.windows" />
- <antcall target="internal.install.eclipse.non.windows" />
</target>
<!-- ### GET ECLIPSE ##################################################### -->
@@ -952,7 +923,7 @@
overwrite="true" />
</target>
- <target name="internal.install.eclipse.non.windows" if="is.not.windows">
+ <target name="internal.install.eclipse.unix" if="is.unix">
<gunzip src="${eclipse.distro.dir}/${eclipse.filename}" dest="${eclipse.distro.dir}" />
<untar src="${eclipse.distro.dir}/${eclipse.tarfilename}"
dest="${jbpm.home}"
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/jobexecutor/JobExecutor.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/jobexecutor/JobExecutor.java 2010-06-22 23:17:42 UTC (rev 6431)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/jobexecutor/JobExecutor.java 2010-06-23 03:06:09 UTC (rev 6432)
@@ -129,7 +129,7 @@
log.debug("stopping job executor");
if (isActive) {
isActive = false;
- dispatcherThread.deactivate(true);
+ dispatcherThread.deactivate(join);
threadPool.shutdown();
if (join) {
try {
15 years, 10 months
JBoss JBPM SVN: r6431 - in jbpm4/trunk: modules/pvm and 2 other directories.
by do-not-reply@jboss.org
Author: alex.guizar(a)jboss.com
Date: 2010-06-22 19:17:42 -0400 (Tue, 22 Jun 2010)
New Revision: 6431
Modified:
jbpm4/trunk/modules/pvm/pom.xml
jbpm4/trunk/modules/test-cfg/
jbpm4/trunk/modules/test-cfg/.classpath
jbpm4/trunk/modules/test-cfg/.project
jbpm4/trunk/modules/test-cfg/pom.xml
jbpm4/trunk/pom.xml
jbpm4/trunk/qa/hudson-jbpm4-base.sh
jbpm4/trunk/qa/hudson-jbpm4-cfg.sh
Log:
JBPM-2893: fix test-cfg module, broken after the dependency scope review
Modified: jbpm4/trunk/modules/pvm/pom.xml
===================================================================
--- jbpm4/trunk/modules/pvm/pom.xml 2010-06-22 22:03:45 UTC (rev 6430)
+++ jbpm4/trunk/modules/pvm/pom.xml 2010-06-22 23:17:42 UTC (rev 6431)
@@ -47,6 +47,11 @@
<scope>provided</scope>
</dependency>
<dependency>
+ <groupId>asm</groupId>
+ <artifactId>asm</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
<groupId>org.beanshell</groupId>
<artifactId>bsh</artifactId>
<scope>provided</scope>
@@ -159,12 +164,6 @@
<artifactId>spring</artifactId>
<scope>provided</scope>
</dependency>
- <dependency>
- <groupId>asm</groupId>
- <artifactId>asm</artifactId>
- <version>1.5.3</version>
- <scope>test</scope>
- </dependency>
</dependencies>
<!-- Plugins -->
Property changes on: jbpm4/trunk/modules/test-cfg
___________________________________________________________________
Name: svn:ignore
- target
+ target
.settings
Modified: jbpm4/trunk/modules/test-cfg/.classpath
===================================================================
--- jbpm4/trunk/modules/test-cfg/.classpath 2010-06-22 22:03:45 UTC (rev 6430)
+++ jbpm4/trunk/modules/test-cfg/.classpath 2010-06-22 23:17:42 UTC (rev 6431)
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
- <classpathentry kind="src" output="target/test-classes" path="src/test/java"/>
- <classpathentry kind="src" output="target/test-classes" path="src/test/resources"/>
+ <classpathentry kind="src" output="target/test-classes" path="src/test/java"/>
+ <classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
<classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER"/>
<classpathentry kind="output" path="target/classes"/>
Modified: jbpm4/trunk/modules/test-cfg/.project
===================================================================
--- jbpm4/trunk/modules/test-cfg/.project 2010-06-22 22:03:45 UTC (rev 6430)
+++ jbpm4/trunk/modules/test-cfg/.project 2010-06-22 23:17:42 UTC (rev 6431)
@@ -1,18 +1,23 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
- <name>jbpm-test-cfg</name>
- <comment></comment>
- <projects>
- </projects>
- <buildSpec>
- <buildCommand>
- <name>org.eclipse.jdt.core.javabuilder</name>
- <arguments>
- </arguments>
- </buildCommand>
- </buildSpec>
- <natures>
- <nature>org.eclipse.jdt.core.javanature</nature>
- <nature>org.maven.ide.eclipse.maven2Nature</nature>
- </natures>
-</projectDescription>
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>jbpm-test-cfg</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.maven.ide.eclipse.maven2Builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.maven.ide.eclipse.maven2Nature</nature>
+ </natures>
+</projectDescription>
Modified: jbpm4/trunk/modules/test-cfg/pom.xml
===================================================================
--- jbpm4/trunk/modules/test-cfg/pom.xml 2010-06-22 22:03:45 UTC (rev 6430)
+++ jbpm4/trunk/modules/test-cfg/pom.xml 2010-06-22 23:17:42 UTC (rev 6431)
@@ -1,17 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- ====================================================================== -->
+<!-- jBPM: Workflow in Java -->
<!-- -->
-<!-- JBoss, the OpenSource J2EE webOS -->
-<!-- -->
<!-- Distributable under LGPL license. -->
<!-- See terms of license at http://www.gnu.org. -->
-<!-- -->
<!-- ====================================================================== -->
-<!-- $Id: pom.xml 5246 2009-07-06 11:07:48Z tom.baeyens(a)jboss.com $ -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+<!-- $Id$ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
<modelVersion>4.0.0</modelVersion>
<name>jBPM 4 - Test Cfg</name>
<groupId>org.jbpm.jbpm4</groupId>
@@ -28,7 +28,6 @@
<!-- Dependencies -->
<dependencies>
-
<dependency>
<groupId>org.jbpm.jbpm4</groupId>
<artifactId>jbpm-api</artifactId>
@@ -48,21 +47,37 @@
<artifactId>jbpm-bpmn</artifactId>
<scope>runtime</scope>
</dependency>
+
<dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring</artifactId>
+ <groupId>asm</groupId>
+ <artifactId>asm</artifactId>
<scope>test</scope>
</dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-mock</artifactId>
- <scope>test</scope>
- </dependency>
<dependency>
+ <groupId>org.hibernate</groupId>
+ <artifactId>hibernate-entitymanager</artifactId>
+ <version>3.4.0.GA</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
<groupId>jboss</groupId>
<artifactId>jboss-j2ee</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>javax.mail</groupId>
+ <artifactId>mail</artifactId>
+ <scope>runtime</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-mock</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
-
</project>
Property changes on: jbpm4/trunk/modules/test-cfg/pom.xml
___________________________________________________________________
Name: svn:keywords
+ Id
Modified: jbpm4/trunk/pom.xml
===================================================================
--- jbpm4/trunk/pom.xml 2010-06-22 22:03:45 UTC (rev 6430)
+++ jbpm4/trunk/pom.xml 2010-06-22 23:17:42 UTC (rev 6431)
@@ -45,6 +45,7 @@
<properties>
<activation.version>1.1.1</activation.version>
<apache.ant.version>1.7.0</apache.ant.version>
+ <asm.version>1.5.3</asm.version>
<aspectjrt.version>1.5.3</aspectjrt.version>
<beanshell.version>2.0b5</beanshell.version>
<cactus.version>1.8.1</cactus.version>
@@ -212,6 +213,11 @@
<version>${apache.ant.version}</version>
</dependency>
<dependency>
+ <groupId>asm</groupId>
+ <artifactId>asm</artifactId>
+ <version>${asm.version}</version>
+ </dependency>
+ <dependency>
<groupId>aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${aspectjrt.version}</version>
Modified: jbpm4/trunk/qa/hudson-jbpm4-base.sh
===================================================================
--- jbpm4/trunk/qa/hudson-jbpm4-base.sh 2010-06-22 22:03:45 UTC (rev 6430)
+++ jbpm4/trunk/qa/hudson-jbpm4-base.sh 2010-06-22 23:17:42 UTC (rev 6431)
@@ -2,4 +2,4 @@
#
# runs the smoke test suite
-mvn -U clean install
+mvn -U -Dmaven.test.failure.ignore=true clean install
Modified: jbpm4/trunk/qa/hudson-jbpm4-cfg.sh
===================================================================
--- jbpm4/trunk/qa/hudson-jbpm4-cfg.sh 2010-06-22 22:03:45 UTC (rev 6430)
+++ jbpm4/trunk/qa/hudson-jbpm4-cfg.sh 2010-06-22 23:17:42 UTC (rev 6431)
@@ -2,7 +2,6 @@
#
# runs the configuration test suite
-mvn clean install
+mvn -DskipTests clean install
cd modules/test-cfg
-mvn clean test
-cd ../..
+mvn -Dmaven.test.failure.ignore=true clean test
15 years, 10 months
JBoss JBPM SVN: r6430 - jbpm3/branches/jbpm-3.2-soa/modules/userguide/src/main/docbook/en-US.
by do-not-reply@jboss.org
Author: dlesage
Date: 2010-06-22 18:03:45 -0400 (Tue, 22 Jun 2010)
New Revision: 6430
Modified:
jbpm3/branches/jbpm-3.2-soa/modules/userguide/src/main/docbook/en-US/async.xml
jbpm3/branches/jbpm-3.2-soa/modules/userguide/src/main/docbook/en-US/calendar.xml
jbpm3/branches/jbpm-3.2-soa/modules/userguide/src/main/docbook/en-US/configuration.xml
jbpm3/branches/jbpm-3.2-soa/modules/userguide/src/main/docbook/en-US/context.xml
jbpm3/branches/jbpm-3.2-soa/modules/userguide/src/main/docbook/en-US/enterprise.xml
jbpm3/branches/jbpm-3.2-soa/modules/userguide/src/main/docbook/en-US/introduction.xml
jbpm3/branches/jbpm-3.2-soa/modules/userguide/src/main/docbook/en-US/logging.xml
jbpm3/branches/jbpm-3.2-soa/modules/userguide/src/main/docbook/en-US/mail.xml
jbpm3/branches/jbpm-3.2-soa/modules/userguide/src/main/docbook/en-US/modelling.xml
jbpm3/branches/jbpm-3.2-soa/modules/userguide/src/main/docbook/en-US/persistence.xml
jbpm3/branches/jbpm-3.2-soa/modules/userguide/src/main/docbook/en-US/scheduler.xml
jbpm3/branches/jbpm-3.2-soa/modules/userguide/src/main/docbook/en-US/tutorial.xml
Log:
Grammar fixes - phase 1
Modified: jbpm3/branches/jbpm-3.2-soa/modules/userguide/src/main/docbook/en-US/async.xml
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/userguide/src/main/docbook/en-US/async.xml 2010-06-22 17:57:45 UTC (rev 6429)
+++ jbpm3/branches/jbpm-3.2-soa/modules/userguide/src/main/docbook/en-US/async.xml 2010-06-22 22:03:45 UTC (rev 6430)
@@ -3,80 +3,106 @@
<!ENTITY % BOOK_ENTITIES SYSTEM "jBPM_jPDL_User_Guide.ent">
%BOOK_ENTITIES;
]>
+
<chapter id="asynchronouscontinuations">
- <title>Asynchronous continuations</title>
+ <title>
+ Asynchronous Continuations
+ </title>
<section id="theconcept">
- <title>The concept</title>
+ <title>The Concept</title>
- <para>jBPM is based on Graph Oriented Programming (GOP). Basically, GOP specifies a
- simple state machine that can handle concurrent paths of execution. But in the execution
- algorithm specified in GOP, all state transitions are done in a single operation in the
- thread of the client. By default, this
- performing state transitions in the thread of the client is a good approach cause it fits
- naturally with server side transactions. The process execution moves from one wait state
- to another wait state in one transaction.
+ <para>
+ jBPM is based on <firstterm>Graph-Oriented Programming</firstterm>
+ (GOP). Basically, GOP specifies a simple-state machine that can
+ handle concurrent paths of execution but, in the specified execution
+ algorithm, all state transitions are undertaken in a single thread
+ client operation. By default, it is a good approach to perform state
+ transitions in the thread of the client because it fits naturally
+ with server-side transactions. The process execution moves from one
+ "wait" state to another in the space of one transaction.
</para>
- <para>In some situations, a developer might want to fine-tune the transaction
- demarcation in the process definition. In jPDL, it is possible to specify that the process
- execution should continue asynchronously with the attribute <literal>async="true"</literal>.
- <literal>async="true"</literal> can be specified on all node types and all action types.
+ <para>
+ In some situations, a developer might want to fine-tune the
+ transaction demarcation in the process definition. In jPDL, it is
+ possible to specify that the process execution should continue
+ asynchronously with the attribute <code>async="true"</code>.
+ <code>async="true"</code> is supported only when it is triggered in
+ an event but can be specified on all node types and all action
+ types.
</para>
- </section>
- <section id="anexample">
- <title>An example</title>
+</section>
+ <section id="asynchronousexample">
+ <title>An Example</title>
- <para>Normally, a node is always executed after a token has entered the node. So the node is
- executed in the thread of the client. We'll explore asynchronous continuations by looking
- two examples. The first example is a part of a process with 3 nodes. Node 'a' is a wait
- state, node 'b' is an automated step and node 'c' is again a wait state. This process does
- not contain any asynchronous behaviour and it is represented in the picture below.
+ <para>
+ Normally, a node is always executed after a token has entered
+ it. Hence, the node is executed in the client's thread. One
+ will explore asynchronous continuations by looking at two
+ examples. The first example is part of a process with three
+ nodes. Node 'a' is a wait state, node 'b' is an automated step
+ and node 'c' is, again, a wait state. This process does not
+ contain any asynchronous behavior and it is represented in the
+ diagram below.
</para>
- <para>The first frame, shows the starting situation. The token points to node 'a', meaning
- that the path of execution is waiting for an external trigger. That trigger must be given
- by sending a signal to the token. When the signal arrives, the token will be passed from
- node 'a' over the transition to node 'b'. After the token arrived in node 'b', node 'b'
- is executed. Recall that node 'b' is an automated step that does not behave as a wait
- state (e.g. sending an email). So the second frame is a snapshot taken when node 'b' is
- being executed. Since node 'b' is an automated step in the process, the execute of node
- 'b' will include the propagation of the token over the transition to node 'c'. Node 'c'
- is a wait state so the third frame shows the final situation after the signal method
- returns.
+ <para>
+ The first frame shows the starting situation. The token points
+ to node 'a', meaning that the path of execution is waiting for
+ an external trigger. That trigger must be given by sending a
+ signal to the token. When the signal arrives, the token will be
+ passed from node 'a' over the transition to node 'b'. After the
+ token arrived in node 'b', node 'b' is executed. Recall that
+ node 'b' is an automated step that does not behave as a wait
+ state (e.g. sending an email). So the second frame is a snapshot
+ taken when node 'b' is being executed. Since node 'b' is an
+ automated step in the process, the execute of node 'b' will
+ include the propagation of the token over the transition to node
+ 'c'. Node 'c' is a wait state so the third frame shows the final
+ situation after the signal method returns.
</para>
<figure id="async1.image">
- <title>Example 1: Process without asynchronous continuation</title>
- <mediaobject><imageobject><imagedata align="center" fileref="images/async1.gif"/></imageobject></mediaobject>
+ <title>Example One: Process without Asynchronous Continuation</title>
+ <mediaobject><imageobject><imagedata fileref="images/async1.png"/></imageobject></mediaobject>
</figure>
- <para>While persistence is not mandatory in jBPM, the most common scenario is that a signal
- is called within a transaction. Let's have a look at the updates of that transaction.
- First of all, the token is updated to point to node 'c'. These updates are generated by
- hibernate as a result of the <literal>GraphSession.saveProcessInstance</literal> on a
- JDBC connection. Second, in case the automated action would access and update some
- transactional resources, those transactional updates should be combined or part of
- the same transaction.
+ <para>
+ Whilst "persistence" is not mandatory in jBPM, most commonly a
+ signal will be called within a transaction. Look at the updates of
+ that transaction. Initially, the token is updated to point to node
+ 'c'. These updates are generated by
+ <application>Hibernate</application> as a result of the
+ <classname>GraphSession.saveProcessInstance</classname> on a JDBC
+ connection. Secondly, in case the automated action accesses and
+ updates some transactional resources, such updates should be
+ combined or made part of the same transaction.
</para>
- <para>Now, we are going to look at the second example, the second example is a variant of
- the first example and introduces an asynchronous continuation in node 'b'. Nodes 'a' and
- 'c' behave the same as in the first example, namely they behave as wait states. In jPDL,
- a node is marked as asynchronous by setting the attribute <literal>async="true"</literal>.
+ <para>
+ The second example is a variant of the first and introduces an
+ asynchronous continuation in node 'b'. Nodes 'a' and 'c' behave the
+ same as in the first example, namely they behave as wait states. In
+ jPDL a node is marked as asynchronous by setting the attribute
+ <code>async="true"</code>.
</para>
- <para>The result of adding <literal>async="true"</literal> to node 'b' is that the process
- execution will be split up into 2 parts. The first part will execute the process up to
- the point where node 'b' is to be executed. The second part will execute node 'b' and
- that execution will stop in wait state 'c'.
+ <para>
+ The result of adding <code>async="true"</code> to node 'b' is that
+ the process execution will be split into two parts. The first of these
+ will execute the process up to the point at which node 'b' is to be
+ executed. The second part will execute node 'b.' That execution
+ will stop in wait state 'c'.
</para>
- <para>The transaction will hence be split up into 2 separate transactions. One transaction
- for each part. While it requires an external trigger (the invocation of the
- <literal>Token.signal</literal> method) to leave node 'a' in the first transaction, jBPM
- will automatically trigger and perform the second transaction.
+ <para>
+ The transaction will hence be split into two separate transactions,
+ one for each part. While it requires an external trigger (the
+ invocation of the <literal>Token.signal</literal> method) to leave
+ node 'a' in the first transaction, jBPM will automatically trigger
+ and perform the second transaction.
</para>
<figure id="asynchronous.continuations.image">
@@ -84,83 +110,105 @@
<mediaobject><imageobject><imagedata align="center" fileref="images/asynchronous.continuations.gif"/></imageobject></mediaobject>
</figure>
- <para>For actions, the principle is similar. Actions that are marked with the
- attribute <literal>async="true"</literal> are executed outside of the thread that
+ <para>
+ For actions, the principle is similar. Actions that are marked with the
+ attribute <code>async="true"</code> are executed outside of the thread that
executes the process. If persistence is configured (it is by default), the actions
will be executed in a separate transaction.
</para>
<para>In jBPM, asynchronous continuations are realized by using an asynchronous messaging
system. When the process execution arrives at a point that should be executed
- asynchronously, jBPM will suspend the execution, produces a job message and send it
+ asynchronously, jBPM will suspend the execution, produces a command message and send it
to the command executor. The command executor is a separate component that, upon receipt
of a message, will resume the execution of the process where it got suspended.
</para>
- <para>jBPM can be configured to use a JMS provider or its built-in asynchronous messaging
- system. The built-in messaging system is quite limited in functionality, but allows
- this feature to be supported on environments where JMS is unavailable.
+ <para>
+ jBPM can be configured to use a JMS provider or its built-in
+ asynchronous messaging system. The built-in messaging system is
+ quite limited in functionality, but allows this feature to be
+ supported on environments where JMS is unavailable.
</para>
</section>
<section id="thejobexecutor">
- <title>The job executor</title>
+ <title>The Job Executor</title>
- <para>The job executor is the component that resumes process executions asynchronously.
- It waits for job messages to arrive over an asynchronous messaging system and executes
- them. The two job messages used for asynchronous continuations are
- <literal>ExecuteNodeJob</literal> and <literal>ExecuteActionJob</literal>.
+ <para>
+ The <firstterm>job executor</firstterm> is the component that
+ resumes process executions asynchronously. It waits for job messages
+ to arrive over an asynchronous messaging system and executes them.
+ The two job messages used for asynchronous continuations are
+ <classname>ExecuteNodeJob</classname> and
+ <classname>ExecuteActionJob</classname>.
</para>
- <para>These job messages are produced by the process execution. During process execution,
- for each node or action that has to be executed asynchronously, a <literal>Job</literal>
- object will be dispatched to the <literal>MessageService</literal>. The message service
- is associated with the <literal>JbpmContext</literal> and it just collects all the
- messages that have to be sent.
+ <para>
+ These job messages are produced by the process execution. During process execution,
+ for each node or action that has to be executed asynchronously, a <classname>Job</classname>
+ (Plain Old Java Object) will be dispatched to the <classname>MessageService</classname>. The message service
+ is associated with the <classname>JbpmContext</classname> and it just collects all the
+ messages that have to be sent.
</para>
<para>The messages will be sent as part of <literal>JbpmContext.close()</literal>.
- That method cascades the <literal>close()</literal> invocation
- to all of the associated services. The actual services can be configured in
- <literal>jbpm.cfg.xml</literal>. One of the services, <literal>DbMessageService</literal>, is
- configured by default and will notify the job executor that new job messages are available.
+ That method cascades the <code>close()</code> invocation
+ to all of the associated services. The actual services can be configured in
+ <literal>jbpm.cfg.xml</literal>. One of the services, <literal>DbMessageService</literal>, is
+ configured by default and will notify the job executor that new job messages are available.
</para>
- <para>The graph execution mechanism uses the interfaces
- <literal>MessageServiceFactory</literal> and <literal>MessageService</literal> to
- send messages. This is to make the asynchronous messaging service
- configurable (also in <literal>jbpm.cfg.xml</literal>). In Java EE environments, the
- <literal>DbMessageService</literal> can be replaced with the <literal>JmsMessageService</literal>
- to leverage the application server's capabilities.
+ <para>
+ The graph execution mechanism uses the interfaces
+ <classname>MessageServiceFactory</classname> and <classname>MessageService</classname> to
+ send messages. This is to make the asynchronous messaging service
+ configurable (also in <filename>jbpm.cfg.xml</filename>). In Java EE environments, the
+ <classname>DbMessageService</classname> can be replaced with the <classname>JmsMessageService</classname>
+ to leverage the application server's capabilities.
</para>
- <para>Here's how the job executor works in a nutshell:
+ <para>
+ The following is a brief summary of the way in which the job
+ executor works.
</para>
- <para>Jobs are records in the database. Jobs are objects and can be executed, too. Both timers
- and async messages are jobs. For async messages, the dueDate is simply set to the current time when they
- are inserted. The job executor must execute the jobs. This is done in 2 phases: 1) a job
- executor thread must acquire a job and 2) the thread that acquired the job must execute it.
+ <para>
+ "Jobs" are records in the database. Furthermore, they are objects
+ and can be executed. Both timers and asynchronous messages are jobs.
+ For asynchronous messages, the <property>dueDate</property> is
+ simply set to the current time when they are inserted. The job
+ executor must execute the jobs. This is done in two phases.
+ <itemizedlist>
+ <listitem>
+ <para>A job executor thread must acquire a job</para>
+ </listitem>
+ <listitem>
+ <para>The thread that acquired the job must execute it</para>
+ </listitem>
+ </itemizedlist>
</para>
<para>Acquiring a job and executing the job are done in 2 separate transactions. A thread
acquires a job by putting its name into the owner field of the job. Each thread has a unique
- name based on ip-address and sequence number. Hibernate's optimistic locking is enabled on
+ name based on IP address and sequence number. Hibernate's optimistic locking is enabled on
<literal>Job</literal>-objects. So if 2 threads try to acquire a job concurrently, one of
- them will get a <literal>StaleStateException</literal> and rollback. Only the first one will succeed. The
+ them will get a StaleObjectException and rollback. Only the first one will succeed. The
thread that succeeds in acquiring a job is now responsible for executing it in a separate
transaction.
</para>
<para>A thread could die between acquisition and execution of a job. To clean-up after
those situations, there is one lock-monitor thread per job executor that checks the lock times.
- Jobs that are locked for more then 30 mins (by default) will be unlocked so that they can be
- executed by another job.
+ The lock monitor thread will unlock any jobs that have been locked for more than 30 minutes,
+ so that they can be executed by another job executor thread.
</para>
- <para>The required isolation level should be set to REPEATABLE_READ for hibernate's optimistic
- locking to work correctly. That isolation level will guarantee that
+ <para>
+ The isolation level must be set to <literal>REPEATABLE_READ</literal> for Hibernate's
+ optimistic locking to work correctly. <literal>REPEATABLE_READ</literal> guarantees that
+ this query will only update one row in exactly one of the competing transactions.
</para>
<programlisting>update JBPM_JOB job
@@ -169,50 +217,62 @@
where
job.version = 1</programlisting>
- <para>will only result in 1 row updated in exactly 1 of the competing transactions.
+
+ <para>
+ Non-Repeatable Reads can lead to the following anomaly.
+ A transaction re-reads data it has previously read and finds that
+ data has been modified by another transaction, one that has been
+ committed since the transaction's previous read.
</para>
-
- <para>Non-Repeatable Reads means that the following anomaly can happen: A transaction re-reads
- data it has previously read and finds that data has been modified by another transaction, one
- that has been committed since the transaction's previous read.
+
+ <para>
+ Non-Repeatable reads are a problem for optimistic locking and therefore, isolation level
+ <literal>READ_COMMITTED</literal> is not enough because it allows for Non-Repeatable reads to occur.
+ So <literal>REPEATABLE_READ</literal> is required if you configure more than one job executor thread.
</para>
-
- <para>Non-Repeatable reads are a problem for optimistic locking and therefore isolation level
- READ_COMMITTED is not enough cause it allows for Non-Repeatable reads to occur. So
- REPEATABLE_READ is required if you configure more than one job executor thread.
- </para>
</section>
<section id="jbpmsbuiltinasynchronousmessaging">
<title>jBPM's built-in asynchronous messaging</title>
- <para>When using jBPM's built-in asynchronous messaging, job messages will be sent by persisting
- them to the database. This message persisting is done in the same transaction/JDBC
- connection as the jBPM process updates.
+ <para>
+ When using jBPM's built-in asynchronous messaging, job messages will be sent by persisting
+ them to the database. This message persisting can be done in the same transaction or JDBC
+ connection as the jBPM process updates.
</para>
<para>The job messages will be stored in the <literal>JBPM_JOB</literal> table.
</para>
- <para>The job executor (<literal>org.jbpm.job.executor.JobExecutor</literal>)
- will read the messages from the database table and execute them. So the typical
- transaction of the job executor looks like this: 1) read next job message
- 2) execute job 3) delete job message.
+ <para>
+ The POJO command executor (<literal>org.jbpm.msg.command.CommandExecutor</literal>)
+ will read the messages from the database table and execute them. The typical
+ transaction of the POJO command executor looks like this:
+ <orderedlist>
+ <listitem><para>Read next command message</para></listitem>
+ <listitem><para>Execute command message</para></listitem>
+ <listitem><para>Delete command message</para></listitem>
+ </orderedlist>
</para>
- <para>If execution of a job fails, the transaction will be rolled back.
- After that, a new transaction will be started that adds the exception stack trace to the
- job message in the database. The job executor filters out all messages that contain
+ <para>If execution of a command message fails, the transaction will be rolled back.
+ After that, a new transaction will be started that adds the error message to the
+ message in the database. The command executor filters out all messages that contain
an exception.
</para>
<figure id="job.executor.image">
<title>Job executor transactions</title>
<mediaobject><imageobject><imagedata align="center" fileref="images/pojo.command.executor.gif"/></imageobject></mediaobject>
</figure>
- <para>If for some reason or another, the transaction that adds the exception to the
- job message would fail, it is rolled back as well. In that case, the
- message remains in the database without an exception so it will be retried later.
+ <para>
+ If the transaction that adds the exception to the command message fails, it
+ is rolled back. The message will remain in the queue without an
+ exception and will be retried later.
</para>
- <para>Limitation: beware that jBPM's built-in asynchronous messaging system does
- not support multinode locking. So you cannot just deploy the job
- executor multiple times and have them configured to use the same database.
- </para>
+
+ <important>
+ <para>jBPM's built-in asynchronous messaging system does not support multi-node
+ locking. You cannot deploy the POJO command executor multiple times and have
+ them configured to use the same database.
+ </para>
+ </important>
+
</section>
</chapter>
Modified: jbpm3/branches/jbpm-3.2-soa/modules/userguide/src/main/docbook/en-US/calendar.xml
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/userguide/src/main/docbook/en-US/calendar.xml 2010-06-22 17:57:45 UTC (rev 6429)
+++ jbpm3/branches/jbpm-3.2-soa/modules/userguide/src/main/docbook/en-US/calendar.xml 2010-06-22 22:03:45 UTC (rev 6430)
@@ -3,70 +3,102 @@
<!ENTITY % BOOK_ENTITIES SYSTEM "jBPM_jPDL_User_Guide.ent">
%BOOK_ENTITIES;
]>
+
<chapter id="businesscalendar">
- <title>Business calendar</title>
+ <title>
+ Business Calendar
+ </title>
- <para>This chapter describes the business calendar of jBPM. The business
- calendar knows about business hours and is used in calculation of due dates
- for tasks and timers.</para>
+ <para>
+ Read this chapter to learn about the Business Process Manager's
+ calendar functionality, which is used to calculate due dates for
+ tasks and timers.
+ </para>
- <para>The business calendar is able to calculate a due date by adding a
- duration to or subtracting it from a base date. If the base date is ommited,
- the 'current' date is used.</para>
+ <para>
+ It does so by adding or subtracting a duration with a base date. (If
+ the base date is omitted, the current date is used by default.)
+ </para>
- <section id="duedate">
- <title>Duedate</title>
+ <section id="duedate">
+ <title>
+ Due Date
+ </title>
- <para>As mentioned the due date is composed of a duration and a base date.
- If this base date is ommitted, the duration is relative to the date (and
- time) at the moment of calculating the duedate. The format is:</para>
+ <para>
+ The due date is comprised of a duration and a base date. The
+ formula used is: <code>duedate ::= [<basedate> +/-]
+ <duration></code>
+ </para>
- <para><literal>duedate ::= [<basedate> +/-]
- <duration></literal></para>
+ <section id="duration">
+ <title>
+ Duration
+ </title>
- <section id="duration">
- <title>Duration</title>
+ <para>
+ A duration is specified in either absolute or business
+ hours by use of this formula: <code>duration ::=
+ <quantity> [business] <unit></code>
+ </para>
- <para>A duration is specified in absolute or in business hours. Let's
- look at the syntax:</para>
+ <para>
+ In the calculation above, <code><quantity></code> must
+ be a piece of text that is parsable with
+ <command>Double.parseDouble(quantity)</command>.
+ <code><unit></code> will be one of: second, seconds,
+ minute, minutes, hour, hours, day, days, week, weeks, month,
+ months, year or years. Adding the optional
+ <code>business</code> flag will mean that only business
+ hours will be taken into account for this duration. (Without
+ it, the duration will be interpreted as an absolute time
+ period.)
+ </para>
+ </section>
- <para><literal>duration ::= <quantity> [business]
- <unit></literal></para>
+ <section id="baseDate">
+ <title>
+ Base Date
+ </title>
+
+ <para>
+ The base date is calculated in this way: <code>basedate ::=
+ <EL></code>.
+ </para>
- <para>Where <literal><quantity></literal> is a piece of text that
- is parsable with Double.parseDouble(quantity).
- <literal><unit></literal> is one of {second, seconds, minute,
- minutes, hour, hours, day, days, week, weeks, month, months, year,
- years}. And adding the optional indication <literal>business</literal>
- means that only business hours should be taken into account for this
- duration. Without the indication <literal>business</literal>, the
- duration will be interpreted as an absolute time period.</para>
- </section>
+ <para>
+ In the formula above, <code><EL></code> can be any
+ Java Expression Language expression that resolves to a <systemitem>Java
+ Date</systemitem> or <systemitem>Calendar</systemitem> object.
+ </para>
+
+ <warning>
+ <para>
+ Do not reference variables of any other object
+ types, as this will result in a
+ <exceptionname>JbpmException</exceptionname> error.
+ </para>
+ </warning>
- <section id="baseDate">
- <title>Base date</title>
+ <para>
+ The base date is supported in a number of places, these
+ being a plain timer's <property>duedate</property>
+ attributes, on a task reminder and the timer within a task.
+ However, it is not supported on the
+ <property>repeat</property> attributes of these elements.
+ </para>
+
+ </section>
- <para>A duration is specified in absolute or in business hours. Let's
- look at the syntax:</para>
+ <section id="duedateExamples">
+ <title>
+ Due Date Examples
+ </title>
+
+ <para>
+ The following uses are all valid:
+ </para>
- <para><literal>basedate ::= <EL></literal></para>
-
- <para>Where <literal><EL></literal> is any JAVA Expression
- Language expression that resolves to a JAVA Date or Calendar object.
- Referencing variable of other object types, even a String in a date
- format like '2036-02-12', will throw a JbpmException</para>
-
- <para>NOTE: This basedate is supported on the duedate attributes of a
- plain timer, on the reminder of a task and the timer within a task. It
- is <emphasis role="bold">not</emphasis> supported on the repeat
- attributes of these elements.</para>
- </section>
-
- <section id="duedateExamples">
- <title>Examples</title>
-
- <para>The following examples of the usage are all possible</para>
-
<programlisting><timer name="daysBeforeHoliday" duedate="5 business days">...</timer>
<timer name="pensionDate" duedate="#{dateOfBirth} + 65 years" >...</timer>
@@ -81,17 +113,21 @@
</section>
<section id="calendarconfiguration">
- <title>Calendar configuration</title>
+ <title>
+ Calendar Configuration
+ </title>
- <para>The file
- <literal>org/jbpm/calendar/jbpm.business.calendar.properties</literal>
- specifies what business hours are. The configuration file can be
- customized and a modified copy can be placed in the root of the
- classpath.</para>
+ <para>
+ Define the business hours in the
+ <filename>org/jbpm/calendar/jbpm.business.calendar.properties</filename>
+ file. (To customize this configuration file, place a modified
+ copy in the root of the classpath.)
+ </para>
- <para>This is the example business hour specification that is shipped by
- default in <literal>jbpm.business.calendar.properties</literal>:</para>
-
+ <para>
+ This is the default business hour specification found in
+ <filename>jbpm.business.calendar.properties</filename>:
+ </para>
<programlisting>hour.format=HH:mm
#weekday ::= [<daypart> [& <daypart>]*]
#daypart ::= <start-hour>-<to-hour>
@@ -126,5 +162,6 @@
business.week.expressed.in.hours= 40
business.month.expressed.in.business.days= 21
business.year.expressed.in.business.days= 220</programlisting>
+
</section>
</chapter>
\ No newline at end of file
Modified: jbpm3/branches/jbpm-3.2-soa/modules/userguide/src/main/docbook/en-US/configuration.xml
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/userguide/src/main/docbook/en-US/configuration.xml 2010-06-22 17:57:45 UTC (rev 6429)
+++ jbpm3/branches/jbpm-3.2-soa/modules/userguide/src/main/docbook/en-US/configuration.xml 2010-06-22 22:03:45 UTC (rev 6430)
@@ -3,32 +3,56 @@
<!ENTITY % BOOK_ENTITIES SYSTEM "jBPM_jPDL_User_Guide.ent">
%BOOK_ENTITIES;
]>
+
<chapter id="configuration">
- <title>Configuration</title>
+ <title>
+ Configuration
+ </title>
- <para>The simplest way to configure jBPM is by putting the <literal>jbpm.cfg.xml</literal>
- configuration file in the root of the classpath. If that file is not found as a
- resource, the default minimal configuration will be used that is included in the
- jbpm library (<literal>org/jbpm/default.jbpm.cfg.xml</literal>). If a jbpm configuration
- file is provided, the values configured will be used as defaults. So you only
- need to specify the parts that are different from the default configuration file.
+ <para>
+ Read this chapter and studied the examples to learn how to configure the
+ jBPM.
</para>
- <para>The jBPM configuration is represented by the java class <literal>org.jbpm.JbpmConfiguration</literal>.
- Most easy way to get a hold of the JbpmConfiguration is to make use of the singleton
- instance method <literal>JbpmConfiguration.getInstance()</literal>.
+ <para>
+ The simplest way to configure the Business Process Manager is by
+ putting the <filename>jbpm.cfg.xml</filename> configuration file into
+ the root of the classpath. If the file is not available for use as a
+ resource, the default minimal configuration will be used instead. This
+ minimal configuration is included in the jBPM library
+ (<filename>org/jbpm/default.jbpm.cfg.xml</filename>.) If a jBPM
+ configuration file is provided, the values it contains will be used as
+ the defaults. Hence, one only needs to specify the values that are to
+ be different from those in the default configuration file.
</para>
+
+ <para>
+ The jBPM configuration is represented by a Java class called
+ <classname>org.jbpm.JbpmConfiguration</classname>. Obtain it by
+ making use of the <systemitem>singleton</systemitem> instance method
+ (<methodname>JbpmConfiguration.getInstance()</methodname>.)
+ </para>
- <para>If you want to load a configuration from another source, you can use the
- <literal>JbpmConfiguration.parseXxxx</literal> methods.
+<note>
+ <para>
+ Use the <methodname>JbpmConfiguration.parseXxxx</methodname> methods
+ to load a configuration from another source.
</para>
+</note>
<programlisting>static JbpmConfinguration jbpmConfiguration = JbpmConfinguration.parseResource("my.jbpm.cfg.xml");</programlisting>
- <para>The JbpmConfiguration is threadsafe and hence can be kept in a static member. All threads can use
- the JbpmConfiguration as a factory for JbpmContext objects. A JbpmContext typically represents one
- transaction. The JbpmContext makes services available inside of a context block.
- A context block looks like this:
+ <para>
+ The <classname>JbpmConfiguration</classname> is "thread safe" and,
+ hence, can be kept in a <firstterm>static member</firstterm>.
+ </para>
+
+ <para>
+ Every thread can use a <classname>JbpmConfiguration</classname> as a
+ <firstterm>factory</firstterm> for <classname>JbpmContext</classname>
+ objects. A <classname>JbpmContext</classname> will usually represent
+ one transaction. They make services available inside
+ <firstterm>context blocks</firstterm> which looks like this:
</para>
<programlisting>JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
@@ -40,15 +64,21 @@
jbpmContext.close();
}</programlisting>
- <para>The <literal>JbpmContext</literal> makes a set of services and the configuration available
- to jBPM. These services are configured in the <literal>jbpm.cfg.xml</literal> configuration file and
- make it possible for
- jBPM to run in any Java environment and use whatever services are available in that environment.
- </para>
+ <para>
+ The <classname>JbpmContext</classname> makes both a set of services
+ and the configuration settings available to the Business Process
+ Manager. The services are configured by the values in the
+ <filename>jbpm.cfg.xml</filename> file. They make it possible for the
+ jBPM to run in any Java environment, using whatever services are
+ available within said environment.
+ </para>
- <para>Here's the default configuration for the JbpmContext:
- </para>
+ <para>
+ Here are the default configuration settings for the
+ <classname>JbpmContext</classname>:
+ </para>
+
<programlisting><![CDATA[<jbpm-configuration>
<jbpm-context>
@@ -113,36 +143,53 @@
</jbpm-configuration>]]></programlisting>
- <para>In this configuration file you can see 3 parts:
+ <para>
+ The above file contains three parts:
</para>
- <itemizedlist>
- <listitem><para>The first part configures the jbpm context with a set of service
- implementations. The possible configuration options are covered in the chapters
- that cover the specific service implementations.
- </para></listitem>
- <listitem><para>The second part are all mappings of references to configuration
- resources. These resource references can be updated if you want to customize
- one of these configuration files. Typically, you make a copy the default configuration
- which is in the <literal>jbpm-3.x.jar</literal> and put it somewhere on the classpath.
- Then you update the reference in this file and jbpm will use your customized version
- of that configuration file.
- </para></listitem>
- <listitem><para>The third part are some miscellaneous configurations used in jbpm.
- These configuration options are described in the chapters that cover the
- specific topic.
- </para></listitem>
- </itemizedlist>
+ <orderedlist>
+ <listitem>
+ <para>
+ a set of <firstterm>service implementations</firstterm> which
+ configure the <classname>JbpmContext</classname>. (The possible
+ configuration options are detailed in the chapters that cover
+ specific service implementations.)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ all of the mappings linking references to configuration
+ resources. If one wishes to customize one of the configuration
+ files, update these mappings. To do so, always back up the
+ default configuration file (<filename>jbpm-3.x.jar</filename>)
+ to another location on the classpath first. Then, update the
+ reference in this file, pointing it to the customized version
+ that the jBPM is to use.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ miscellaneous configurations for use by the
+ jBPM. (These are described in the chapters that
+ cover the specific topics in question.)
+ </para>
+ </listitem>
+ </orderedlist>
- <para>The default configured set of services is targeted at a simple webapp environment
- and minimal dependencies. The persistence service will obtain a jdbc connection and all
- the other services will use the same connection to perform their services. So all of your
- workflow operations are centralized into 1 transaction on a JDBC connection without the
- need for a transaction manager.
+ <para>
+ The default configuration has been optimized for a simple web
+ application environment which has minimal dependencies. The
+ persistence service obtains a JDBC connection which is used by all
+ of the other services. Hence, all of the workflow operations are
+ centralized as they are placed in a single transaction on a JDBC
+ connection (without the need for a transaction manager.)
</para>
- <para><literal>JbpmContext</literal> contains convenience methods for most of the common
- process operations:
+
+ <para>
+ <classname>JbpmContext</classname> contains <firstterm>convenience
+ methods</firstterm> for most of the common process operations. They
+ are demonstrated in this code sample:
</para>
<programlisting> public void deployProcessDefinition(ProcessDefinition processDefinition) {...}
@@ -161,31 +208,70 @@
public void save(TaskInstance taskInstance) {...}
public void setRollbackOnly() {...}</programlisting>
- <para>Note that the <literal>XxxForUpdate</literal> methods will register the loaded
- object for auto-save so that you don't have to call one of the save methods
- explicitly.
+ <note>
+ <para>
+ There is no need to call any of the save methods explicitly
+ because the <methodname>XxxForUpdate</methodname> methods are
+ designed to register the loaded object for "auto-save."
</para>
+</note>
- <para>It's possible to specify multiple <literal>jbpm-context</literal>s, but then you have
- to make sure that each <literal>jbpm-context</literal> is given a unique <literal>name</literal>
- attribute. Named contexts can be retrieved with <literal>JbpmConfiguration.createContext(String name);</literal>
+ <para>
+ It is possible to specify multiple
+ <classname>jbpm-context</classname>s. To do so, make sure that each
+ of them is given a unique <property>name</property> attribute.
+ (Retrieve named contexts by using
+ <methodname>JbpmConfiguration.createContext(String
+ name);</methodname>.)
</para>
- <para>A <literal>service</literal> element specifies the name of a service and the service factory
- for that service. The service will only be created in case it's asked for with
- <literal>JbpmContext.getServices().getService(String name)</literal>.
+ <para>
+ A <property>service</property> element specifies its own name and
+ associated <firstterm>service factory</firstterm>. The service
+ will only be created when requested to do so by
+ <methodname>JbpmContext.getServices().getService(String
+ name)</methodname>.
</para>
-
- <para>The factories
- can also be specified as an element instead of an attribute. That might be necessary to
- inject some configuration information in the factory objects. The component responsible
- for parsing the XML, creating and wiring the objects is called the object factory.
+
+<note>
+ <para>
+ One can also specfy the <systemitem>factories</systemitem> as
+ <firstterm>elements</firstterm> instead of attributes. This is
+ necessary when injecting some configuration information into factory
+ objects.
+ </para>
+</note>
+
+ <para>
+ Note that the component responsible for creating and wiring the
+ objects and parsing the XML is called the <classname>object
+ factory</classname>.
</para>
<section id="customizingfactories">
- <title>Customizing factories</title>
- <para>A common mistake when customizing factories is to mix the short and the long notation.
- Examples of the short notation can be seen in the default configuration file and above: E.g.
+ <title>
+ Customizing Factories
+ </title>
+
+ <warning>
+ <para>
+ A mistake commonly made by people when they are trying to
+ customize factories is to mix long and short notation together.
+ (Examples of the short notation can be seen in the default
+ configuration file.)
+ </para>
+ </warning>
+
+ <para>
+ <application>Hibernate</application> logs
+ <exceptionname>StateObjectStateException</exceptionname> exceptions
+ and generates a <systemitem>stack trace</systemitem>. In order to
+ remove the latter, set
+ <classname>org.hibernate.event.def.AbstractFlushingEventListener</classname>
+ to <code>FATAL</code>. (Alternatively, if using
+ <systemitem>log4j</systemitem>, set the following line in the
+ configuration: for that:
+ <code>log4j.logger.org.hibernate.event.def.AbstractFlushingEventListener=FATAL</code>
</para>
<programlisting> ...
<service name='persistence' factory='org.jbpm.persistence.db.DbPersistenceServiceFactory' /></programlisting>
@@ -204,120 +290,209 @@
</section>
<section id="configurationproperties">
- <title>Configuration properties</title>
+ <title>
+ Configuration Properties
+ </title>
- <para><emphasis role="bold">jbpm.byte.block.size</emphasis>:
- File attachments and binary variables are stored in the database. Not as blobs, but as a list of fixed sized binary objects.
- This is done to improve portability amongst different databases and improve overall embeddability of jBPM. This parameter
- controls the size of the fixed length chunks.
- </para>
- <para><emphasis role="bold">jbpm.task.instance.factory</emphasis>:
- To customize the way that task instances are created, specify a fully qualified class name in this property. This might be
- necessary when you want to customize the TaskInstance bean and add new properties to it. See also <xref linkend="customizingtaskinstances" />
- The specified class should implement org.jbpm.taskmgmt.TaskInstanceFactory.
- </para>
- <para><emphasis role="bold">jbpm.variable.resolver</emphasis>:
- To customize the way that jBPM will look for the first term in JSF-like expressions.
- </para>
+ <variablelist>
+
+ <varlistentry>
+ <term><property>jbpm.byte.block.size</property></term>
+ <listitem>
+ <para>
+ File attachments and binary variables are stored in the
+ database in the form of a list of fixed-sized, binary
+ objects. (The aim of this is to improve portability
+ amongst different databases. It also allows one to embed
+ the jBPM more easily.) This parameter controls the size of
+ those fixed-length chunks.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><property>jbpm.task.instance.factory</property></term>
+ <listitem>
+ <para>
+ To customize the way in which task instances are
+ created, specify a fully-qualified classname against
+ this property. (This is often necessary when one intends
+ to customize, and add new properties to, the
+ <classname>TaskInstance</classname> bean.) Ensure that
+ the specified classname implements the
+ <interfacename>org.jbpm.taskmgmt.TaskInstanceFactory</interfacename>
+ interface. (Refer to <xref
+ linkend="customizingtaskinstances" /> for more
+ information.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><property>jbpm.variable.resolver</property></term>
+ <listitem>
+ <para>
+ Use this to customize the way in which jBPM looks for
+ the first term in "JSF"-like expressions.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
</section>
<section id="configurationfiles">
- <title>Other configuration files</title>
+ <title>Other Configuration Files</title>
- <para>Here's a short description of all the configuration files that are customizable in jBPM.
+ <para>
+ There are a number of configuration files in the jBPM
+ which can be customized:
</para>
- <section id="hibernatecfgxmlfile">
- <title>Hibernate cfg xml file</title>
- <para>This file contains hibernate configurations and references to the
- hibernate mapping resource files.</para>
- <para>Location: <literal>hibernate.cfg.xml</literal> unless specified
- otherwise in the jbpm.hibernate.cfg.xml property in the jbpm.properties file.
- In the jbpm project the default hibernate cfg xml file is located in
- directory <literal>src/config.files/hibernate.cfg.xml</literal></para>
- </section>
+ <variablelist>
- <section id="hibernatequeriesconfigurationfile">
- <title>Hibernate queries configuration file</title>
- <para>This file contains hibernate queries that are used in the jBPM
- sessions <literal>org.jbpm.db.*Session</literal>.
- </para>
- <para>Location: <literal>org/jbpm/db/hibernate.queries.hbm.xml</literal>
- </para>
- </section>
+ <varlistentry>
+ <term><filename>hibernate.cfg.xml</filename></term>
+ <listitem>
+ <para>
+ This contains references to, and configuration details
+ for, the <application>Hibernate</application> mapping
+ resource files.
+ </para>
+ <para>
+ To specify a different file, configure the
+ <property>jbpm.hibernate.cfg.xml</property> property in
+ <filename>jbpm.properties</filename>. (The
+ default <application>Hibernate</application>
+ configuration file is located in the
+ <filename>src/config.files/hibernate.cfg.xml</filename>
+ sub-directory.)
+ </para>
+ </listitem>
+ </varlistentry>
- <section id="nodetypesconfigurationfile">
- <title>Node types configuration file</title>
- <para>This file contains the mapping of XML node elements to
- Node implementation classes.
- </para>
- <para>Location: <literal>org/jbpm/graph/node/node.types.xml</literal></para>
- </section>
+ <varlistentry>
+ <term><filename>org/jbpm/db/hibernate.queries.hbm.xml</filename></term>
+ <listitem>
+ <para>
+ This file contains those <application>Hibernate</application>
+ queries to be used in the jBPM sessions
+ (<classname>org.jbpm.db.*Session</classname>.)
+ </para>
+ </listitem>
+ </varlistentry>
- <section id="actiontypesconfigurationfile">
- <title>Action types configuration file</title>
- <para>This file contains the mapping of XML action elements to
- Action implementation classes.
- </para>
- <para>Location: <literal>org/jbpm/graph/action/action.types.xml</literal></para>
- </section>
+ <varlistentry>
+ <term><filename>org/jbpm/graph/node/node.types.xml</filename></term>
+ <listitem>
+ <para>
+ This file is used to map XML node elements to
+ <classname>Node</classname> implementation classes.
+ </para>
+ </listitem>
+ </varlistentry>
- <section id="businesscalendarconfigurationfile">
- <title>Business calendar configuration file</title>
- <para>Contains the definition of business hours and free time.</para>
- <para>Location: <literal>org/jbpm/calendar/jbpm.business.calendar.properties</literal></para>
- </section>
+ <varlistentry>
+ <term><filename>org/jbpm/graph/action/action.types.xml</filename></term>
+ <listitem>
+ <para>
+ This file is used to map XML action elements to
+ <classname>Action</classname> implementation classes.
+ </para>
+ </listitem>
+ </varlistentry>
- <section id="variablemappingconfigurationfile">
- <title>Variable mapping configuration file</title>
- <para>Specifies how the values of the process variables (java objects) are
- converted to variable instances for storage in the jbpm database.</para>
- <para>Location: <literal>org/jbpm/context/exe/jbpm.varmapping.xml</literal></para>
- </section>
+ <varlistentry>
+ <term><filename>org/jbpm/calendar/jbpm.business.calendar.properties</filename></term>
+ <listitem>
+ <para>
+ This contains the definitions of "business hours" and
+ "free time."
+ </para>
+ </listitem>
+ </varlistentry>
- <section id="converterconfigurationfile">
- <title>Converter configuration file</title>
- <para>Specifies the id-to-classname mappings. The id's are stored in the database.
- The org.jbpm.db.hibernate.ConverterEnumType is used to map the ids to the singleton
- objects.</para>
- <para>Location: <literal>org/jbpm/db/hibernate/jbpm.converter.properties</literal></para>
- </section>
+ <varlistentry>
+ <term><filename>org/jbpm/context/exe/jbpm.varmapping.xml</filename></term>
+ <listitem>
+ <para>
+ This specifies the way in which the process variables values
+ (Java objects) are converted to variable instances for
+ storage in the jBPM database.
+ </para>
+ </listitem>
+ </varlistentry>
- <section id="defaultmodulesconfigurationfile">
- <title>Default modules configuration file</title>
- <para>specifies which modules are added to a new ProcessDefinition by default.</para>
- <para>Location: <literal>org/jbpm/graph/def/jbpm.default.modules.properties</literal></para>
- </section>
-
- <section id="parsersconfigurationfile">
- <title>Process archive parsers configuration file</title>
- <para>specifies the phases of process archive parsing</para>
- <para>Location: <literal>org/jbpm/jpdl/par/jbpm.parsers.xml</literal></para>
- </section>
+ <varlistentry>
+ <term><filename>org/jbpm/db/hibernate/jbpm.converter.properties</filename></term>
+ <listitem>
+ <para>
+ This specifies the <code>id-to-classname</code> mappings. The
+ <property>id</property>s are stored in the database. The
+ <classname>org.jbpm.db.hibernate.ConverterEnumType</classname> class
+ is used to map the identifiers to the
+ <systemitem>singleton</systemitem> objects.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><filename>org/jbpm/graph/def/jbpm.default.modules.properties</filename></term>
+ <listitem>
+ <para>
+ This specifies which modules are to be added to a new
+ <classname>ProcessDefinition</classname> by default.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><filename>org/jbpm/jpdl/par/jbpm.parsers.xml</filename></term>
+ <listitem>
+ <para>
+ This specifies the phases of <firstterm>process archive
+ parsing</firstterm>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
</section>
<section id="loggingofoptimisticconcurrencyexceptions">
- <title>Logging of optimistic concurrency exceptions</title>
- <para>When running in a cluster, jBPM synchronizes on the database. By default with optimistic
- locking. This means that each operation is performed in a transaction. And if at the end a
- collision is detected, then the transaction is rolled back and has to be handled. E.g. by a
- retry. So optimistic locking exceptions are usually part of the normal operation. Therefor,
- by default, the <literal>org.hibernate.StateObjectStateException</literal>s the that hibernate
- throws in that case are not logged with error and a stack trace, but instead a simple info
- message 'optimistic locking failed' is displayed.
+ <title>
+ Logging Optimistic Concurrency Exceptions
+ </title>
+
+ <para>
+ When it is run in a cluster configuration, the jBPM synchronizes with
+ the database by using <firstterm>optimistic locking</firstterm>.
+ This means that each operation is performed in a transaction and
+ if, at the end, a collision is detected, then the transaction in
+ question is rolled back and has to be handled with a retry. This
+ can cause
+ <exceptionname>org.hibernate.StateObjectStateException</exceptionname>
+ exceptions. If and when this happens,
+ <application>Hibernate</application> will log the exceptions
+ with a simple message, <screen>optimistic locking
+ failed</screen>.
</para>
- <para>Hibernate itself will log the StateObjectStateException including a stack trace. If you
- want to get rid of these stack traces, put the level of
- <literal>org.hibernate.event.def.AbstractFlushingEventListener</literal> to FATAL. If you use
- log4j following line of configuration can be used for that:
- <programlisting>log4j.logger.org.hibernate.event.def.AbstractFlushingEventListener=FATAL</programlisting>
+ <para>
+ <application>Hibernate</application> can also log the
+ <exceptionname>StateObjectStateException</exceptionname> with a
+ stack trace. To remove these stack traces, set the
+ <classname>org.hibernate.event.def.AbstractFlushingEventListener</classname>
+ class to <code>FATAL</code>. Do so in
+ <application>log4j</application> by using the following
+ configuration:
</para>
- <para>If you want to enable logging of the jBPM stack traces, add the following line to your
- jbpm.cfg.xml:
- <programlisting><boolean name="jbpm.hide.stale.object.exceptions" value="false" /></programlisting>.
- </para>
+
+ <programlisting><boolean name="jbpm.hide.stale.object.exceptions" value="false" /></programlisting>
+
</section>
<section id="configuringjobexecutor">
@@ -383,14 +558,20 @@
</section>
<section id="objectfactory">
- <title>Object factory</title>
- <para>The object factory can create objects according to a beans-like xml configuration file.
- The configuration file specifies how objects should be created, configured and wired together
- to form a complete object graph. The object factory can inject the configurations and other
- beans into a bean.
+ <title>Object Factory</title>
+ <para>
+ The <firstterm>Object Factory</firstterm> can build objects to
+ the specification contained in a "beans-like" XML configuration
+ file. This file dictates how objects are to be
+ created, configured and wired together to form a complete object
+ graph. Also use the Object Factory to inject configurations and
+ other beans into a single bean.
</para>
- <para>In its simplest form, the object factory is able to create basic types and java beans
- from such a configuration:
+
+ <para>
+ In its most elementary form, the Object Factory is able to create both
+ basic <firstterm>types</firstterm> and Java beans from such a
+ configuration, as shown in the following examples:
</para>
<programlisting><beans>
<bean name="task" class="org.jbpm.taskmgmt.exe.TaskInstance"/>
@@ -416,7 +597,9 @@
assertNull(of.getNewObject("dusttodust"));</programlisting>
- <para>Also you can configure lists:</para>
+ <para>
+ This code shows how to configure lists:
+ </para>
<programlisting><beans>
<list name="numbers">
@@ -426,7 +609,9 @@
</list>
</beans></programlisting>
- <para>and maps</para>
+ <para>
+ This code demonstrates how to configure maps:
+ </para>
<programlisting><beans>
<map name="numbers">
@@ -436,8 +621,11 @@
</map>
</beans></programlisting>
- <para>Beans can be configured with direct field injection and via property setters.</para>
-
+ <para>
+ Use <firstterm>direct field injection</firstterm> and property
+ <systemitem>setter</systemitem> methods to configure beans:
+ </para>
+
<programlisting><beans>
<bean name="task" class="org.jbpm.taskmgmt.exe.TaskInstance" >
<field name="name"><string>do dishes</string></field>
@@ -445,8 +633,10 @@
</bean>
</beans></programlisting>
- <para>Beans can be referenced. The referenced object doesn't have to be a bean,
- it can be a string, integer or any other object.
+ <para>
+ Beans can be <firstterm>referenced</firstterm>. The referenced
+ object doesn't have to be a bean; it can be a string, an integer or
+ any other kind. Here is some code that demonstrates this capability:
</para>
<programlisting><beans>
@@ -454,7 +644,9 @@
<ref name="b" bean="a" />
</beans></programlisting>
- <para>Beans can be constructed with any constructor</para>
+ <para>
+ Beans can be built with any constructor, as this code shows:
+ </para>
<programlisting><beans>
<bean name="task" class="org.jbpm.taskmgmt.exe.TaskInstance" >
@@ -469,7 +661,10 @@
</bean>
</beans></programlisting>
- <para>... or with a factory method on a bean ...</para>
+ <para>
+ Beans can be constructed using a <methodname>factory</methodname>
+ method:
+ </para>
<programlisting><beans>
<bean name="taskFactory"
@@ -488,7 +683,10 @@
</bean>
</beans></programlisting>
- <para>... or with a static factory method on a class ...</para>
+ <para>
+ Beans can be constructed using a <methodname>static
+ factory</methodname> method on a class:
+ </para>
<programlisting><beans>
<bean name="task" class="org.jbpm.taskmgmt.exe.TaskInstance" >
@@ -503,20 +701,45 @@
</bean>
</beans></programlisting>
- <para>Each named object can be marked as singleton with the attribute <literal>singleton="true"</literal>.
- That means that a given object factory will always return the same object for each request. Note that
- singletons are not shared between different object factories.
+ <para>
+ Use the attribute <code>singleton="true"</code> to mark each named
+ object as a <systemitem>singleton</systemitem>. Doing so will ensure that a
+ given <classname>object factory</classname> always returns the
+ same object for each request.
+ </para>
+
+ <note>
+ <para>
+ <systemitem>Singletons</systemitem> cannot be shared between
+ different object factories.
</para>
+</note>
- <para>The singleton feature causes the differentiation between the methods <literal>getObject</literal>
- and <literal>getNewObject</literal>. Typical users of the object factory will use the
- <literal>getNewObject</literal>. This means that first the object factory's object cache is cleared
- before the new object graph is constructed. During construction of the object graph, the non-singleton
- objects are stored in the object factory's object cache to allow for shared references to one object.
- The singleton object cache is different from the plain object cache. The singleton cache is never
- cleared, while the plain object cache is cleared at the start of every <literal>getNewObject</literal>
- method.
+ <para>
+ The <systemitem>singleton</systemitem> feature causes
+ differentiation between the methods named
+ <methodname>getObject</methodname> and
+ <methodname>getNewObject</methodname>. Normally, one should use
+ <methodname>getNewObject</methodname> as this clears the
+ <classname>object factory</classname>'s <firstterm>object
+ cache</firstterm> before the new object graph is constructed.
+ </para>
+
+ <para>
+ During construction of the object graph, the
+ <firstterm>non-singleton objects</firstterm> are stored in the
+ <classname>object factory</classname>'s cache. This allows
+ references to one object to be shared. Bear in mind that the
+ <systemitem>singleton object cache</systemitem> is different from
+ the <systemitem>plain object cache</systemitem>. The
+ <systemitem>singleton</systemitem> cache is never cleared, whilst
+ the plain one is cleared every time a
+ <methodname>getNewObject</methodname> method is started.
</para>
+ <para>
+ Having studied this chapter, one now has a thorough knowledge
+ of the many ways in which the jBPM can be configured.
+ </para>
</section>
</chapter>
Modified: jbpm3/branches/jbpm-3.2-soa/modules/userguide/src/main/docbook/en-US/context.xml
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/userguide/src/main/docbook/en-US/context.xml 2010-06-22 17:57:45 UTC (rev 6429)
+++ jbpm3/branches/jbpm-3.2-soa/modules/userguide/src/main/docbook/en-US/context.xml 2010-06-22 22:03:45 UTC (rev 6430)
@@ -3,163 +3,233 @@
<!ENTITY % BOOK_ENTITIES SYSTEM "jBPM_jPDL_User_Guide.ent">
%BOOK_ENTITIES;
]>
+
<chapter id="context">
- <title>Context</title>
+ <title>
+ The Context
+ </title>
- <para>Context is about process variables. Process variables are
- key-value pairs that maintain information related to the process instance.
- Since the context must be storable in a database, some minor limitations
- apply.</para>
+ <para>
+ Read this chapter to learn about <firstterm>process
+ variables</firstterm>. Process variables are key-value pairs that
+ maintain process instance-related information.
+ </para>
+ <note>
+ <para>
+ Since one must be able to store the <firstterm>context</firstterm>
+ in a database, some minor limitations apply.
+ </para>
+ </note>
+
<section id="accessingvariables">
- <title>Accessing variables</title>
+ <title>
+ Accessing Process Variables
+ </title>
- <para>org.jbpm.context.exe.ContextInstance serves as the central
- interface to work with process variables. You can obtain the
- ContextInstance from a ProcessInstance like this : </para>
+ <para>
+ <interfacename>org.jbpm.context.exe.ContextInstance</interfacename>
+ serves as the central interface for process variables. Obtain the
+ <interfacename>ContextInstance</interfacename> from a process
+ instance in this manner:
+ </para>
<programlisting>ProcessInstance processInstance = ...;
ContextInstance contextInstance = (ContextInstance) processInstance.getInstance(ContextInstance.class);</programlisting>
- <para>The most basic operations are</para>
+ <para>
+ These are the basic operations:
+ </para>
<programlisting>void ContextInstance.setVariable(String variableName, Object value);
void ContextInstance.setVariable(String variableName, Object value, Token token);
Object ContextInstance.getVariable(String variableName);
Object ContextInstance.getVariable(String variableName, Token token);</programlisting>
- <para>The variable names are java.lang.String. By default, jBPM supports the following
- value types:
+ <para>
+ The variable name is <classname>java.lang.String</classname>. By
+ default, the Business Process Manager supports the following
+ value types. (It also supports any other class that can be persisted
+ with <application>Hibernate</application>.)
</para>
+ <simplelist columns="2" type="horiz">
+ <member><classname>java.lang.String</classname></member>
+ <member><classname>java.lang.Boolean</classname></member>
+ <member><classname>java.lang.Character</classname></member>
+ <member><classname>java.lang.Float</classname></member>
+ <member><classname>java.lang.Double</classname></member>
+ <member><classname>java.lang.Long</classname></member>
+ <member><classname>java.lang.Byte</classname></member>
+ <member><classname>java.lang.Integer</classname></member>
+ <member><classname>java.util.Date</classname></member>
+ <member><classname>byte[]</classname></member>
+ <member><classname>java.io.Serializable</classname></member>
+ </simplelist>
+
+<note>
<para>
- <itemizedlist>
- <listitem><para><literal>java.lang.String</literal></para></listitem>
- <listitem><para><literal>java.lang.Boolean</literal></para></listitem>
- <listitem><para><literal>java.lang.Character</literal></para></listitem>
- <listitem><para><literal>java.lang.Float</literal></para></listitem>
- <listitem><para><literal>java.lang.Double</literal></para></listitem>
- <listitem><para><literal>java.lang.Long</literal></para></listitem>
- <listitem><para><literal>java.lang.Byte</literal></para></listitem>
- <listitem><para><literal>java.lang.Short</literal></para></listitem>
- <listitem><para><literal>java.lang.Integer</literal></para></listitem>
- <listitem><para><literal>java.util.Date</literal></para></listitem>
- <listitem><para><literal>byte[]</literal></para></listitem>
- <listitem><para><literal>java.io.Serializable</literal></para></listitem>
- <listitem><para><literal>classes that are persistable with hibernate</literal></para></listitem>
- </itemizedlist>
+ <firstterm>Untyped null values</firstterm> can also be stored
+ persistently.
</para>
-
- <para>Also an untyped null value can be stored persistently.
- </para>
-
- <para>All other types can be stored in the process variables without any problem. But
- it will cause an exception when you try to save the process instance.
- </para>
+</note>
<para>To configure jBPM for storing hibernate persistent objects in the variables,
see Storing hibernate persistent objects.
</para>
</section>
- <section id="variablelifetime">
- <title>Variable lifetime</title>
+<section id="variablelifetime">
+ <title>
+ Variable Life Time
+ </title>
- <para>Variables do not have to be declared in the process archive. At runtime, you
- can just put any java object in the variables. If that variable was not present, it will
- be created. Just the same as with a plain <literal>java.util.Map</literal>.</para>
-
- <para>Variables can be deleted with</para>
+ <para>
+ Variables do not have to be declared in the process archive. At
+ run-time, simply put any Java object in the variables. If a
+ variable did not exist, it will be created, in the same way as a
+ plain <classname>java.util.Map</classname>. Note that
+ variables can also be deleted.
+ </para>
<programlisting>ContextInstance.deleteVariable(String variableName);
ContextInstance.deleteVariable(String variableName, Token token);</programlisting>
- <para>Automatic changing of types is now supported. This means that it is allowed to
- overwrite a variable with a value of a different type. Of course, you should try to
- limit the number of type changes since this creates a more db communication then a
- plain update of a column.
+ <para>
+ Types can change automatically. This means that a type is allowed to
+ overwrite a variable with a value of a different type. It is
+ important to always try to limit the number of type changes since
+ this generates more comunications with the database than a plain
+ column update.
</para>
</section>
<section id="variablepersistence">
- <title>Variable persistence</title>
- <para>The variables are a part of the process instance. Saving the process instance
- in the database, brings the database in sync with the process instance. The variables
- are created, updated and deleted from the database as a result of saving (=updating)
- the process instance in the database. For more information, see
- <xref linkend="persistence" />.
+ <title>
+ Variable Persistence
+ </title>
+
+ <para>
+ The variables are part of the process instance. Saving the process
+ instance in the database will synchronise the database with the
+ process instance. (The variables are created, updated and deleted by
+ doing this.) For more information, see <xref linkend="persistence"
+ />.
</para>
</section>
<section id="variablescopes">
- <title>Variables scopes</title>
- <para>Each path of execution (read: token) has its own set of process variables.
- Requesting a variable is always done on a token. Process instances have a tree
- of tokens (see graph oriented programming ).
- When requesting a variable without specifying a token, the default token is the
- root token.
+ <title>
+ Variable Scopes
+ </title>
+
+ <para>
+ Each path of execution (also known as a
+ <firstterm>token</firstterm>) has its own set of process variables.
+ Variables are always requested on a path of execution. Process
+ instances have a tree of these paths. If a variable is requested but
+ no path is specified, the <systemitem>root token</systemitem> will
+ be used by default.
</para>
- <para>The variable lookup is done recursively over the parents of the given
- token. The behaviour is similar to the scoping of variables in programming
- languages.
+ <para>
+ The variable look-up occurs recursively. It runs
+ over the parents of the given path of execution. (This is
+ similar to the way in which variables are scoped in programming
+ languages.)
</para>
- <para>When a non-existing variable is set on a token, the variable is created
- on the root-token. This means that each variable has by default process
- scope. To make a variable token-local, you have to create it explicitely
- with:</para>
+ <para>
+ When a non-existent variable is set on a path of execution, the
+ variable is created on the <systemitem>root token</systemitem>.
+ (Hence, each variable has, by default, a process scope.) To make
+ a variable token "local", create it explicitly, as per this
+ example:
+ </para>
<programlisting>ContextInstance.createVariable(String name, Object value, Token token);</programlisting>
<section id="variableoverloading">
- <title>Variables overloading</title>
- <para>Variable overloading means that each path of execution can have its
- own copy of a variable with the same name. They are treated as independant
- and hence can be of different types. Variable overloading can be
- interesting if you launch multiple concurrent paths of execution over
- the same transition. Then the only thing that distinguishes those paths
- of executions are their respective set of variables.</para>
+ <title>
+ Variable Overloading
+ </title>
+
+ <para>
+ <firstterm>Variable overloading</firstterm> means that each path
+ of execution can have its own copy of a variable with the same
+ name. These copies are all treated independently of each other
+ and can be of different types. Variable overloading can be
+ interesting if one is launching multiple concurrent paths of
+ execution over the same transition. This is because the only
+ thing that will distinguish these paths will be their respective
+ set of variables.
+ </para>
</section>
<section id="variableoverriding">
- <title>Variables overriding</title>
- <para>Variable overriding means that variables of nested paths of execution
- override variables in more global paths of execution. Generally, nested paths
- of execution relate to concurrency : the paths of execution between a fork and
- a join are children (nested) of the path of execution that arrived in the
- fork. For example, if you have a variable 'contact' in the process instance
- scope, you can override this variable in the nested paths of execution 'shipping'
- and 'billing'.</para>
+ <title>
+ Variable Over-Riding
+ </title>
+
+ <para>
+ <firstterm>Variable over-riding</firstterm> simply means that
+ variables in <firstterm>nested paths of execution</firstterm>
+ over-ride variables in more global paths of execution.
+ Generally, "nested paths of execution" relates to concurrency:
+ the paths of execution between a fork and a join are children
+ (nested) of the path of execution that arrived in the fork. For
+ example, ione can over-ride a variable named
+ <literal>contact</literal> in the process instance scope with
+ this variable in the nested paths of execution
+ <literal>shipping</literal> and <literal>billing</literal>.
+ </para>
</section>
<section id="taskinstancevariablescope">
- <title>Task instance variable scope</title>
- <para>For more info on task instance variables, see the section on Task Instance Variables.
+ <title>
+ Task Instance Variable Scope
+ </title>
+
+ <para>
+ To learn about task instance variables, read <xref
+ linkend="taskinstancevariables" />.
</para>
</section>
</section>
<section id="transientvariables">
- <title>Transient variables</title>
+ <title>
+ Transient Variables
+ </title>
- <para>When a process instance is persisted in the database, normal variables
- are also persisted as part of the process instance. In some situations
- you might want to use a variable in a delegation class, but you don't want
- to store it in the database. An example could be a database connection that
- you want to pass from outside of jBPM to a delegation class. This can be
- done with transient variables.
+ <para>
+ When a process instance is persisted in the database, so too are
+ normal variables. However, at times one might want to use a
+ variable in a delegation class without storing it in the database.
+ This can be achieved with <firstterm>transient variables</firstterm>.
</para>
- <para>The lifetime of transient variables is the same as the ProcessInstance
- java object.</para>
-
- <para>Because of their nature, transient variables are not related to a token.
- So there is only one map of transient variables for a process instance object.</para>
-
- <para>The transient variables are accessable with their own set of methods
- in the context instance, and don't need to be declared in the
- processdefinition.xml</para>
+ <note>
+ <para>
+ The lifespan of a transient variable is the same as that of a
+ <systemitem>ProcessInstance</systemitem> Java object.
+ </para>
+</note>
+
+<note>
+ <para>
+ Because of their nature, transient variables are not related to
+ paths of execution. Therefore, a process instance object will have
+ only one map of them.
+ </para>
+</note>
+
+
+ <para>
+ The transient variables are accessible through their own set of methods
+ in the context instance. They do not need to be declared in the
+ <filename>processdefinition.xml</filename> file.
+ </para>
<programlisting>Object ContextInstance.getTransientVariable(String name);
void ContextInstance.setTransientVariable(String name, Object value);</programlisting>
@@ -268,6 +338,12 @@
<para>that means that the Long objects that are put in the variables are just stored
in a variable instance of type LongInstance without being converted.</para>
- </section>
+
+ <para>
+ This chapter has covered process variables in great detail. The
+ reader should now be confident that he or she understands this topic.
+ </para>
+
+ </section>
</chapter>
Modified: jbpm3/branches/jbpm-3.2-soa/modules/userguide/src/main/docbook/en-US/enterprise.xml
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/userguide/src/main/docbook/en-US/enterprise.xml 2010-06-22 17:57:45 UTC (rev 6429)
+++ jbpm3/branches/jbpm-3.2-soa/modules/userguide/src/main/docbook/en-US/enterprise.xml 2010-06-22 22:03:45 UTC (rev 6430)
@@ -5,27 +5,36 @@
]>
<chapter id="enterprise">
- <title>Java EE Application Server Facilities</title>
+ <title>
+ Java EE Application Server Facilities
+ </title>
- <para>The present chapter describes the facilities offered by jBPM to leverage the Java EE
- infrastructure.
+ <para>
+ Read this chapter to learn about the facilities offered by the jBPM
+ to that can be used to leverage the Java EE infrastructure.
</para>
<section id="enterprisebeans">
- <title>Enterprise Beans</title>
+ <title>
+ Enterprise Beans
+ </title>
- <para><literal>CommandServiceBean</literal> is a stateless session bean that executes
- jBPM commands by calling it's execute method within a separate jBPM context. The environment
- entries and resources available for customization are summarized in the table below.
+ <para>
+ The <systemitem>CommandServiceBean</systemitem> is a
+ <firstterm>stateless session bean</firstterm> that runs Business
+ Process Manager commands by calling its
+ <methodname>execute</methodname> method within a separate jBPM
+ context. The available environment entries and customizable
+ resources are summarized in the following table:
</para>
<table>
- <title>Command service bean environment</title>
+ <title>Command Service Bean Environment</title>
<tgroup cols="3" align="left" colsep="1" rowsep="1">
- <colspec colwidth="1*"/>
- <colspec colwidth="1*"/>
- <colspec colwidth="3*"/>
+ <colspec colwidth="4*"/>
+ <colspec colwidth="2*"/>
+ <colspec colwidth="5*"/>
<thead>
<row>
<entry>Name</entry>
@@ -35,94 +44,114 @@
</thead>
<tbody>
<row>
- <entry><literal>JbpmCfgResource</literal></entry>
+ <entry><systemitem>JbpmCfgResource</systemitem></entry>
<entry>Environment Entry</entry>
- <entry>The classpath resource from which to read the jBPM configuration.
- Optional, defaults to <literal>jbpm.cfg.xml</literal>.
+ <entry>This the classpath resource from which the jBPM configuration is read.
+ Optional, defaults to <filename>jbpm.cfg.xml</filename>.
</entry>
</row>
<row>
- <entry><literal>ejb/TimerEntityBean</literal></entry>
+ <entry><systemitem>ejb/TimerEntityBean</systemitem></entry>
<entry>EJB Reference</entry>
- <entry>Link to the local entity bean that implements the scheduler service.
+ <entry>This is a link to the local entity bean that implements the scheduler service.
Required for processes that contain timers.
</entry>
</row>
<row>
- <entry><literal>jdbc/JbpmDataSource</literal></entry>
+ <entry><systemitem>jdbc/JbpmDataSource</systemitem></entry>
<entry>Resource Manager Reference</entry>
- <entry>Logical name of the data source that provides JDBC connections to the
- jBPM persistence service. Must match the <literal>hibernate.connection.datasource
- </literal> property in the Hibernate configuration file.
+ <entry>This is the logical name of the data source that provides JDBC connections to the
+ jBPM persistence service. Must match the <property>hibernate.connection.datasource
+ </property> property in the Hibernate configuration file.
</entry>
</row>
<row>
- <entry><literal>jms/JbpmConnectionFactory</literal></entry>
+ <entry><systemitem>jms/JbpmConnectionFactory</systemitem></entry>
<entry>Resource Manager Reference</entry>
- <entry>Logical name of the factory that provides JMS connections to the jBPM
+ <entry>This is the logical name of the factory that provides JMS connections to the jBPM
message service. Required for processes that contain asynchronous continuations.
</entry>
</row>
<row>
- <entry><literal>jms/JobQueue</literal></entry>
+ <entry><systemitem>jms/JobQueue</systemitem></entry>
<entry>Message Destination Reference</entry>
- <entry>The jBPM message service sends job messages to the queue referenced here.
+ <entry>The jBPM message service sends job messages to this queue.
To ensure this is the same queue from which the job listener bean receives
- messages, the <literal>message-destination-link</literal> points to a common
- logical destination, <literal>JobQueue</literal>.
+ messages, the <systemitem>message-destination-link</systemitem> points to a common
+ logical destination, <systemitem>JobQueue</systemitem>.
</entry>
</row>
<row>
- <entry><literal>jms/CommandQueue</literal></entry>
+ <entry><systemitem>jms/CommandQueue</systemitem></entry>
<entry>Message Destination Reference</entry>
- <entry>The command listener bean receives messages from the queue referenced here.
+ <entry>The command listener bean receives messages from this queue.
To ensure this is the same queue to which command messages can be sent,
- the <literal>message-destination-link element</literal> points to a common
- logical destination, <literal>CommandQueue</literal>.
+ the <systemitem>message-destination-link element</systemitem> points to a common
+ logical destination, <systemitem>CommandQueue</systemitem>.
</entry>
</row>
</tbody>
</tgroup>
</table>
- <para><literal>CommandListenerBean</literal> is a message-driven bean that listens
- on the <literal>CommandQueue</literal> for command messages. This bean delegates
- command execution to the <literal>CommandServiceBean</literal>.
+ <para>
+ The <systemitem>CommandListenerBean</systemitem> is a message-driven
+ bean that listens to the <systemitem>CommandQueue</systemitem> for
+ command messages. It delegates command execution to the
+ <systemitem>CommandServiceBean</systemitem>.
</para>
- <para>The body of the message must be a Java object that implements the <literal>
- org.jbpm.Command</literal> interface. The message properties, if any, are ignored.
- If the message does not match the expected format, it is forwarded to the <literal>
- DeadLetterQueue</literal>. No further processing is done on the message.
- If the destination reference is absent, the message is rejected.
+ <para>
+ The body of the message must be a Java object that can implement the
+ <interfacename> org.jbpm.Command</interfacename> interface. (The
+ message properties, if any, are ignored.) If the message is not of
+ the expected format, it is forwarded to the <methodname>
+ DeadLetterQueue</methodname> and will not be processed any further.
+ The message will also be rejected if the destination reference is
+ absent.
</para>
- <para>In case the received message specifies a <code>replyTo</code> destination,
- the result of the command execution is wrapped into an object message and sent
- there. The command connection factory environment reference indicates the resource
- manager that supplies JMS connections.
+ <para>
+ If a received message specifies a <code>replyTo</code>
+ destination, the command execution result will be wrapped in an
+ <systemitem>object message</systemitem> and sent there.
</para>
+
+ <para>
+ The <systemitem>command connection factory environment
+ reference</systemitem> points to the resource manager being used
+ to supply Java Message Service connections.
+ </para>
- <para>Conversely, <literal>JobListenerBean</literal> is a message-driven bean that
- listens on the <literal>JbpmJobQueue</literal> for job messages to support asynchronous
- continuations.
+ <para>
+ Conversely, <systemitem>JobListenerBean</systemitem> is a
+ message-driven bean that listens to the
+ <systemitem>JbpmJobQueue</systemitem> for job messages, in order to
+ support <firstterm>asynchronous continuations</firstterm>.
</para>
- <para>The message must have a property called <literal>jobId</literal> of type
- <literal>long</literal> which references a pending <literal>Job</literal> in the
- database. The message body, if any, is ignored.
+<note>
+ <para>
+ Be aware that the message must have a property called
+ <property>jobId</property> of type <code>long</code>. This
+ property must contain references to a pending
+ <property>Job</property> in the database. The message body, if
+ it exists, is ignored.
</para>
+</note>
- <para>This bean extends the <literal>CommandListenerBean</literal> and inherits its
- environment entries and resource references available for customization.
+ <para>
+ This bean extends the <classname>CommandListenerBean</classname>. It
+ inherits the latter's environmental entries and those resource
+ references that can be customized.
</para>
<table>
<title>Command/Job listener bean environment</title>
<tgroup cols="3" align="left" colsep="1" rowsep="1">
- <colspec colwidth="1*"/>
- <colspec colwidth="1*"/>
- <colspec colwidth="3*"/>
+ <colspec colwidth="9*"/>
+ <colspec colwidth="4*"/>
+ <colspec colwidth="9*"/>
<thead>
<row>
<entry>Name</entry>
@@ -132,25 +161,25 @@
</thead>
<tbody>
<row>
- <entry><code>ejb/LocalCommandServiceBean</code></entry>
+ <entry><classname>ejb/LocalCommandServiceBean</classname></entry>
<entry>EJB Reference</entry>
- <entry>Link to the local session bean that executes commands on a separate
+ <entry>This is a link to the local session bean that executes commands on a separate
jBPM context.
</entry>
</row>
<row>
- <entry><code>jms/JbpmConnectionFactory</code></entry>
+ <entry><classname>jms/JbpmConnectionFactory</classname></entry>
<entry>Resource Manager Reference</entry>
- <entry>Logical name of the factory that provides JMS connections for producing
+ <entry>This is the logical name of the factory that provides Java Message Service connections for producing
result messages. Required for command messages that indicate a reply
destination.
</entry>
</row>
<row>
- <entry><code>jms/DeadLetterQueue</code></entry>
+ <entry><classname>jms/DeadLetterQueue</classname></entry>
<entry>Message Destination Reference</entry>
<entry>Messages which do not contain a command are sent to the queue referenced
- here. Optional; if absent, such messages are rejected, which may cause the
+ here. It is optional. If it is absent, such messages are rejected, which may cause the
container to redeliver.
</entry>
</row>
@@ -158,34 +187,59 @@
</tgroup>
</table>
- <para>The <literal>TimerEntityBean</literal> interacts with the EJB timer service to
- schedule jBPM timers. Upon expiration, execution of the timer is actually delegated to
- the command service bean.</para>
+ <para>
+ The <systemitem>TimerEntityBean</systemitem> is used by the
+ <firstterm>Enterprise Java Bean timer service</firstterm> for
+ scheduling. When the bean expires, timer execution is delegated to
+ the <systemitem>command service</systemitem> bean.
+ </para>
- <para>The timer entity bean requires access to the jBPM data source for reading timer
- data. The EJB deployment descriptor does not provide a way to define how an entity bean
- maps to a database. This is left off to the container provider. In JBoss AS, the
- <literal>jbosscmp-jdbc.xml</literal> descriptor defines the data source JNDI name and
- the relational mapping data (table and column names, among others). Note that the
- JBoss CMP descriptor uses a global JNDI name (<literal>java:JbpmDS</literal>),
- as opposed to a resource manager reference (<literal>java:comp/env/jdbc/JbpmDataSource</literal>).
+ <para>
+ The <systemitem>TimerEntityBean</systemitem> requires access to the
+ Business Process Manager's data source. The Enterprise Java Bean
+ deployment descriptor does not define how an entity bean is to map
+ to a database. (This is left to the container provider.) In the
+ <application>JBoss Application Server</application>, the
+ <property>jbosscmp-jdbc.xml</property> descriptor defines the data
+ source's JNDI name and relational mapping data (such as the table
+ and column names.)
+ </para>
+
+ <note>
+ <para>
+ The JBoss CMP (<firstterm>container-managed
+ persistence</firstterm>) descriptor uses a global
+ JNDI name (<systemitem>java:JbpmDS</systemitem>), as opposed to a
+ resource manager reference
+ (<systemitem>java:comp/env/jdbc/JbpmDataSource</systemitem>).
</para>
+</note>
- <para>Earlier versions of jBPM used a stateless session bean called <literal>TimerServiceBean
- </literal> to interact with the EJB timer service. The session approach had to be abandoned
- because there is an unavoidable bottleneck at the cancelation methods. Because session beans
- have no identity, the timer service is forced to iterate through <emphasis>all</emphasis>
- the timers for finding the ones it has to cancel. The bean is still around for backwards
- compatibility. It works under the same environment as the <literal>TimerEntityBean</literal>,
- so migration is easy.
+<note>
+ <para>
+ Earlier versions of the Business Process Manager used a stateless
+ session bean called <systemitem>TimerServiceBean </systemitem> to
+ interact with the Enterprise Java Bean timer service. The session
+ approach had to be abandoned because it caused an unavoidable
+ bottleneck for the <methodname>cancellation</methodname> methods.
+ Because session beans have no identity, the timer service was forced
+ to iterate through <emphasis>all</emphasis> the timers to find the
+ ones it had to cancel.
+ </para>
+
+ <para>
+ The bean is still available for backwards
+ compatibility purposes. It works in the same environment as the
+ <systemitem>TimerEntityBean</systemitem>, so migration is easy.
</para>
+</note>
<table border="1">
- <title>Timer entity/service bean environment</title>
+ <title>Timer Entity/Service Bean Environment</title>
<tgroup cols="3" align="left" colsep="1" rowsep="1">
- <colspec colwidth="1*"/>
- <colspec colwidth="1*"/>
- <colspec colwidth="3*"/>
+ <colspec colwidth="9*"/>
+ <colspec colwidth="4*"/>
+ <colspec colwidth="10*"/>
<thead>
<row>
<entry>Name</entry>
@@ -197,7 +251,8 @@
<row>
<entry><code>ejb/LocalCommandServiceBean</code></entry>
<entry>EJB Reference</entry>
- <entry>Link to the local session bean that executes timers on a separate jBPM context.
+ <entry>This is a link to the local session bean that executes
+ timers on a separate jBPM context.
</entry>
</row>
</tbody>
@@ -573,6 +628,14 @@
</jboss-web>]]></programlisting>
+<para>
+ Having studied this chapter, you should now have a thorough
+ understanding of the facilities offered by the jBPM that can be used to
+ leverage the Java EE infrastructure and should be comfortable with
+ testing some of these in your corporate environment.
+</para>
+
+
</section>
</chapter>
Modified: jbpm3/branches/jbpm-3.2-soa/modules/userguide/src/main/docbook/en-US/introduction.xml
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/userguide/src/main/docbook/en-US/introduction.xml 2010-06-22 17:57:45 UTC (rev 6429)
+++ jbpm3/branches/jbpm-3.2-soa/modules/userguide/src/main/docbook/en-US/introduction.xml 2010-06-22 22:03:45 UTC (rev 6430)
@@ -4,27 +4,64 @@
%BOOK_ENTITIES;
]>
<chapter id="introduction">
- <title>Introduction</title>
+ <title>
+ Introduction
+ </title>
- <para>JBoss jBPM is a flexible, extensible framework for process languages. jPDL is
- one process language that is build on top of that common framework. It is an intuitive
- process language to express business processes graphically in terms
- of tasks, wait states for asynchronous communication, timers, automated actions,...
- To bind these operations together, jPDL has the most powerful and extensible
- control flow mechanism.</para>
+ <para>
+ This <emphasis>Guide</emphasis> has been written for
+ developers and administrators. Read on in order to learn how
+ to use jBPM and JPDL in your corporate setting. Note that
+ this book not only teaches how to use the software but
+ explains, in significant detail, how it works.
+ </para>
- <para>jPDL has minimal dependencies and can be used as easy as using a java library.
- But it can also be used in environments where extreme throughput is crucial by
- deploying it on a J2EE clustered application server. </para>
+ <para>
+ The JBoss <firstterm>Business Process Manager</firstterm> (jBPM) is
+ a flexible and extensible scaffolding for process languages. The
+ <firstterm>jBPM Process Definition Language</firstterm> (JPDL) is
+ one of the <firstterm>process languages</firstterm> that is built on
+ top of this framework. It is an intuitive language, designed to
+ enable the user to express business processes graphically. It does
+ so by representing <firstterm>tasks</firstterm>, <firstterm>wait
+ states</firstterm> (for asynchronous communication),
+ <firstterm>timers</firstterm> and automated
+ <firstterm>actions</firstterm>. To bind these operations together,
+ the language has a powerful and extensible <firstterm>control flow
+ mechanism</firstterm>.
+ </para>
- <para>jPDL can be configured with any database and it can be deployed on any
- application server.</para>
+ <para>
+ The JPDL has few dependencies, making it is as easy to install as a
+ Java library. To do so, deploy it on a <firstterm>J2EE clustered
+ application server</firstterm>. One will find it particularly useful
+ in environments in which extreme throughput is a crucial requirement.
+ </para>
+
+<note>
+ <para>
+ The JPDL can be configured for use with any database. It can also be
+ deployed on any application server.
+ </para>
+ </note>
<section>
- <title>Overview</title>
- <para>The core workflow and BPM functionality is packaged as a simple java library.
- This library includes a service to manage and execute processes in the jPDL
- database.</para>
+ <title>
+ Overview
+ </title>
+
+ <para>
+ Read this section to gain an overview of the way in which the jBPM
+ works.
+ </para>
+
+ <para>
+ The core workflow and business process management functionality
+ is packaged in the form of a simple Java library. This library
+ includes a service that manages and executes jPDL database
+ processes.
+ </para>
+
<figure id="overview.image">
<title>Overview of the jPDL components</title>
<mediaobject><imageobject><imagedata align="center" fileref="images/overview.gif"/></imageobject></mediaobject>
@@ -32,164 +69,211 @@
</section>
<section>
- <title>The jPDL suite</title>
- <para>The suite is a download that contains all the jBPM components bundled in one easy
- download. The download includes:
- </para>
+ <title>
+ The jPDL Suite
+ </title>
+
+ <para>
+ This suite contains all of the jBPM components
+ and the following sub-directories:
+ </para>
+
+ <itemizedlist>
+ <listitem><para>config </para></listitem>
+ <listitem><para>database </para></listitem>
+ <listitem><para>deploy </para></listitem>
+ <listitem><para>designer </para></listitem>
+ <listitem><para>examples </para></listitem>
+ <listitem><para>lib </para></listitem>
+ <listitem><para>src </para></listitem>
+ </itemizedlist>
- <variablelist>
- <varlistentry>
- <term><filename>config</filename></term>
- <listitem><para>configuration files for a standard java environment</para></listitem>
- </varlistentry>
- <varlistentry>
- <term><filename>db</filename></term>
- <listitem><para>SQL scripts for DB creation and compatibility information</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term><filename>designer</filename></term>
- <listitem><para>the eclipse plugin to author jPDL processes and installation
- scripts (this is not part of the plain jpdl download) See also
- <xref linkend="jpdlgraphicalprocessdesigner"/>.</para></listitem>
- </varlistentry>
+
+ <para>
+ The <application>JBoss Application Server</application> consists
+ of the following components:
+ </para>
- <varlistentry>
- <term><filename>doc</filename></term>
- <listitem><para>userguide and javadocs</para></listitem>
- </varlistentry>
+ <variablelist>
+ <varlistentry>
+ <term>The jBPM Web Console</term>
+ <listitem>
+ <para>
+ This is packaged
+ as a web archive. Both <firstterm>process participants</firstterm>
+ and jBPM administrators can use this console.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>The Job Executor</term>
+ <listitem>
+ <para>
+ This is part of the <application>Console Web
+ Application</application>. It is launched by a
+ <firstterm>servlet</firstterm>, then spawns a
+ <firstterm>thread pool</firstterm>, whose job it is to
+ monitor and executes timers and asynchronous messages.
+ </para>
+ </listitem>
+ </varlistentry>
- <varlistentry>
- <term><filename>examples</filename></term>
- <listitem><para>These are examples.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term><filename>lib</filename></term>
- <listitem><para>libraries on which jbpm depends. For more information on
- this see <xref linkend="thirdpartylibraries" /></para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term><filename>server</filename></term>
- <listitem><para>a preconfigured jboss that contains jbpm inside the console
- web application (this is not part of the plain jpdl
- download)</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term><filename>src</filename></term>
- <listitem><para>the jbpm and identity component java sources</para></listitem>
- </varlistentry>
- </variablelist>
+ <varlistentry>
+ <term>The jBPM Tables</term>
+ <listitem>
+ <para>
+ These are contained in the default
+ <application>Hypersonic</application> database. (It
+ already contains a process.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>An Example Process</term>
+ <listitem>
+ <para>
+ One example process is already deployed to the jBPM
+ database.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Identity Component</term>
+ <listitem>
+ <para>
+ The identity component libraries are part of the
+ <application>Console Web Application</application>. It
+ owns those tables found in the database which have the
+ <code>JBPM_ID_</code> prefix.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
-
-
-
-
- <para>The preconfigured JBoss application server has the following components installed :
- </para>
-
- <variablelist>
- <varlistentry><term>The web console</term>
-
- <listitem><para>packaged as a web archive. That console can be
- used by process participants as well as jBPM administrators.</para></listitem>
- </varlistentry>
-
-
- <varlistentry><term>job executor</term>
-
- <listitem><para>enacts timers and asynchronous messages. There is
- a servlet context listener in the console web app that launches the job executor, which
- spawns a thread pool for monitoring and executing timers and asynchronous messages.</para></listitem>
- </varlistentry>
-
-
- <varlistentry><term>jBPM database</term>
-
- <listitem><para>an in-process hypersonic database that
- contains the jBPM tables.</para></listitem>
- </varlistentry>
-
-
- <varlistentry><term>example process</term>
-
- <listitem><para>is already deployed into the jBPM database.</para></listitem>
- </varlistentry>
-
-
- <varlistentry><term>Identity component</term>
-
- <listitem><para>libraries are part of
- the console web application. The tables of the identity component are available in the database (those are the tables
- that start with JBPM_ID_)</para></listitem>
- </varlistentry>
- </variablelist>
-
</section>
<section id="jpdlgraphicalprocessdesigner">
- <title>The jPDL graphical process designer</title>
- <para>jPDL also includes a graphical designer tool. The designer is a
- graphical tool for authoring business processes. It's an eclipse plugin.</para>
- <para>The most important feature of the graphical designer tool is that it
- includes support for both the business analyst as well as the
- technical developer. This enables a smooth transition from business process
- modelling to the practical implementation.</para>
- <para>The plugin is available as a local update site (plain zip file) for
- installation via the standard eclipse software updates mechanism. The
- jPDL graphical process designer plugin is also included in
- <ulink url="http://www.jboss.org/tools/">JBossTools</ulink>,
- <ulink url="http://www.redhat.com/developer_studio/">JBoss Developer Studio</ulink> and
- the SOA Platform.
+ <title>
+ The jPDL Graphical Process Designer
+ </title>
+
+ <para>
+ The jPDL also includes the <application>Graphical Process Designer
+ Tool</application>. Use it to design business processes. (It is an
+ <application>Eclipse</application> plug-in and is included with the
+ <application>JBoss Developer Studio</application> product.)
</para>
+
+ <para>
+ It facilitates a smooth transition from business process
+ modeling to practical implementation, making it of use to both the
+ business analyst and the technical developer.
+ </para>
</section>
<section>
- <title>The jBPM console web application</title>
- <para>The jBPM console web application serves two purposes. First, it serves as a central
- user interface for interacting with runtime tasks generated by the process
- executions. Secondly, it is an administration and monitoring console that allows to
- inspect and manipulate runtime instances. The third functionality is Business Activity
- Monitoring. These are statistics about process executions. This is useful information
- for managers to find bottlenecks or other kinds of optimisations.</para>
+ <title>
+ The jBPM Console Web Application
+ </title>
+
+ <para>
+ The <application>Console Web Application</application> serves
+ three purposes. Firstly, it functions as a central user interface,
+ allowing one to interact with those run-time tasks that have been
+ generated by the process executions. Secondly, it is an
+ administrative and monitoring console that allows one to inspect and
+ manipulate run-time instances. The third role of this software is
+ that of business activity monitor. In this role, it presents
+ statistics about the execution of processes. This information is of
+ use to managers seeking to optimize performance as it allows them to
+ find and eliminate bottlenecks.
+ </para>
+
</section>
<section>
- <title>The jBPM core library</title>
- <para>The JBoss jBPM core component is the plain java (J2SE) library for managing
- process definitions and the runtime environment for execution of process instances.
+ <title>
+ The jBPM Core Library
+ </title>
+
+ <para>
+ The Business Process Manager has two core components. These are the
+ "plain Java" (J2SE) library, which manages process definitions, and
+ the run-time environment, which executes process instances.
</para>
- <para>JBoss jBPM is a java library. As a consequence, it can be used in any java
- environment like e.g. a webapplication, a swing application, an EJB, a webservice,...
- The jBPM library can also be packaged and exposed as a stateless session EJB. This
- allows clustered deployment and scalability for extreme high throughput. The stateless
- session EJB will be written against the J2EE 1.4 specifications so that it is
- deployable on any application server.
+
+ <para>
+ The jBPM, itself, is a Java library. Consequently, it can be used in
+ any Java environment, be it a web or
+ <application>Swing</application> application, an
+ <systemitem>Enterprise Java Bean</systemitem> or a web service.
+ </para>
+
+ <para>
+ One can also package and expose the jBPM library as a
+ <firstterm>stateless session</firstterm> <systemitem>Enterprise Java
+ Bean</systemitem>. Do this if there is a need to create a clustered
+ deployment or provide scalability for extremely high throughput. (The
+ stateless session <systemitem>Enterprise Java Bean</systemitem>
+ adheres to the <literal>J2EE 1.3</literal> specifications, mearning
+ that it can be deployed on any application server.)
</para>
- <para>Depending on the functionalities that you use, the library <literal>lib/jbpm-jpdl.jar</literal>
- has some dependencies on other third party libraries such as e.g. hibernate, dom4j
- and others. We have done great efforts to require only those dependent libraries that
- you actually use. The dependencies are further documented in <xref linkend="deployment" /></para>
- <para>For its persistence, jBPM uses hibernate internally. Apart from traditional
- O/R mapping, hibernate also resolves the SQL dialect differences between the different
- databases, making jBPM portable across all current databases.</para>
- <para>The JBoss jBPM API can be accessed from any custom java software in your
- project, like e.g. your web application, your EJB's, your web service components,
- your message driven beans or any other java component.</para>
+
+
+ <para>
+ Be aware that some parts of the <filename>jbpm-jpdl.jar</filename>
+ file are dependent upon third-party libraries such as
+ <application>Hibernate</application> and
+ <application>Dom4J</application>.
+ </para>
+
+ <para>
+ <application>Hibernate</application> provides the jBPM with
+ <firstterm>persistence</firstterm> functionality. Also, apart from
+ providing traditional <firstterm>O/R mapping</firstterm>,
+ <application>Hibernate</application> resolves the differences between
+ the Structured Query Language dialects used by competing databases.
+ This ability makes the jBPM highly portable.
+ </para>
+
+ <para>
+ The Business Process Manager's application programming interface can
+ be accessed from any custom Java code in your project, whether it be
+ a web application, an Enterprise Java Bean, a web service component
+ or a message-driven bean.
+ </para>
+
</section>
<section>
- <title>The JBoss jBPM identity component</title>
- <para>JBoss jBPM can integrate with any company directory that contains users and other
- organisational information. But for projects where no organisational information component
- is readily available, JBoss jBPM includes this component. The model used in the identity
- component is richer then the traditional servlet-, ejb- and portlet models.</para>
- <para>For more information, see <xref linkend="theidentitycomponent" /></para>
+ <title>
+ The Identity Component
+ </title>
+
+ <para>
+ The jBPM can integrate with any company directory that contains user
+ (and other organizational) data. (For those projects for which no
+ organizational information component is available, use the
+ <firstterm>Identity Component</firstterm>. This component has a
+ "richer" model than those used by traditional servlets, Enterprise
+ Java Beans and portlets.)
+ </para>
+
+ <note>
+ <para>
+ Read <xref linkend="theidentitycomponent" /> to learn more about
+ this topic.
+ </para>
+ </note>
+
+
+
</section>
<section>
@@ -204,6 +288,12 @@
servlet context listener in the web app deployment descriptor to start/stop the job
executor during creation/destruction of the servlet context, or start up a separate JVM
and start the job executor in there programatically.</para>
- </section>
+
+
+ <para>
+ Having read this chapter, you have gained a broad overview of the
+ jBPM and its constituent components.
+ </para>
+ </section>
</chapter>
Modified: jbpm3/branches/jbpm-3.2-soa/modules/userguide/src/main/docbook/en-US/logging.xml
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/userguide/src/main/docbook/en-US/logging.xml 2010-06-22 17:57:45 UTC (rev 6429)
+++ jbpm3/branches/jbpm-3.2-soa/modules/userguide/src/main/docbook/en-US/logging.xml 2010-06-22 22:03:45 UTC (rev 6430)
@@ -4,63 +4,104 @@
%BOOK_ENTITIES;
]>
<chapter id="logging">
- <title>Logging</title>
+ <title>
+ Logging
+ </title>
- <para>The purpose of logging is to keep track of the history of a
- process execution. As the runtime data of a process execution changes,
- all the delta's are stored in the logs.</para>
+ <para>
+ Read this chapter to learn about the logging functionality present in the
+ Business Process Manager and the various ways in which it can be
+ utilized.
+ </para>
+
+ <para>
+ The purpose of logging is to record the history of a process
+ execution. As the run-time data of each process execution alters, the
+ changes are stored in the logs.
+ </para>
- <para>Process logging, which is covered in this chapter, is not to be confused
- with software logging. Software logging traces the execution of a software
- program (usually for debugging purposes). Process logging traces the execution
- of process instances.</para>
+ <note>
+ <para>
+ <firstterm>Process logging</firstterm>, which is covered in this
+ chapter, is not to be confused with <firstterm>software
+ logging</firstterm>. Software logging traces the execution of a
+ software program (usually for the purpose of debugging it.) Process
+ logging, by contast, traces the execution of process instances.
+ </para>
+ </note>
- <para>There are various use cases for process logging information. Most obvious is
- the consulting of the process history by participants of a process execution.
+ <para>
+ There are many ways in which process logging information can be
+ useful. Most obvious of these is the consulting of the process
+ history by process execution participants.
</para>
- <para>Another use case is
- Business Activity Monitoring (BAM). BAM will query or analyse the logs of process
- executions to find usefull statistical information about the business process. E.g.
- how much time is spend on average in each step of the process ? Where are the
- bottlenecks in the process ? ... This information is key to implement real business
- process management in an organisation. Real business process management is about how
- an organisation manages their processes, how these are supported by information technology
- *and* how these two improve the other in an iterative process.
+ <para>
+ Another use case is that of <firstterm>Business Activity
+ Monitoring</firstterm> (BAM). This can be used to query or analyze
+ the logs of process executions to find useful statistical
+ information about the business process. This information is key to
+ implementing "real" business process management in an organization.
+ (Real business process management is about how an organization
+ manages its processes, how these processes are supported by
+ information technology and how these two can be usede improve each
+ other in an iterative process.)
</para>
- <para>Next use case is the undo functionality. Process logs can be used to implement
- the undo. Since the logs contain the delta's of the runtime information, the logs can be
- played in reverse order to bring the process back into a previous state.
+ <para>
+ Process logs can also be used to implement "undos." Since the logs
+ contain a record of all run-time information changes, they can be
+ "played" in reverse order to bring a process back into a previous
+ state.
</para>
<section id="creationoflogs">
- <title>Creation of logs</title>
- <para>Logs are produced by jBPM modules while they are running process executions.
- But also users can insert process logs. A log entry is a java object that inherits from
- <literal>org.jbpm.logging.log.ProcessLog</literal>. Process log entries are added to
- the <literal>LoggingInstance</literal>. The <literal>LoggingInstance</literal> is an
- optional extension of the <literal>ProcessInstance</literal>.
+ <title>
+ Log Creation
+ </title>
+
+ <para>
+ Business Process Manager modules produce logs when they run process
+ executions. But also users can insert process logs. (A log entry is
+ a Java object that inherits from
+ <classname>org.jbpm.logging.log.ProcessLog</classname>.) Process log
+ entries are added to the <systemitem>LoggingInstance</systemitem>,
+ which is an optional extension of the
+ <systemitem>ProcessInstance</systemitem>.
</para>
- <para>Various kinds of logs are generated by jBPM : graph execution logs, context logs
- and task management logs. For more information about the specific data contained in
- those logs, we refer to the javadocs. A good starting point is the class
- <literal>org.jbpm.logging.log.ProcessLog</literal> since from that class you can navigate
- down the inheritance tree.</para>
+ <para>
+ The Business Process Manager generates many different kinds of log,
+ these being graph execution logs, context logs and task management
+ logs. A good starting point is
+ <classname>org.jbpm.logging.log.ProcessLog</classname> since one can
+ use that to navigate down the <systemitem>inheritance
+ tree</systemitem>.
+ </para>
- <para>The <literal>LoggingInstance</literal> will collect all the log entries. When
- the <literal>ProcessInstance</literal> is saved, all the logs in the <literal>LoggingInstance</literal>
- will be flushed to the database. The <literal>logs</literal>-field of a <literal>ProcessInstance</literal>
- is not mapped with hibernate to avoid that logs are retrieved from the database in each transactions.
- Each <literal>ProcessLog</literal> is made in the context
- of a path of execution (<literal>Token</literal>) and hence, the <literal>ProcessLog</literal>
- refers to that token. The <literal>Token</literal> also serves as an index-sequence generator
- for the index of the <literal>ProcessLog</literal> in the <literal>Token</literal>. This will
- be important for log retrieval. That way, logs that are produced in subsequent transactions
- will have sequential sequence numbers. (wow, that a lot of seq's in there :-s ).</para>
- <para>The API method for adding process logs is the following.
+ <para>
+ The <systemitem>LoggingInstance</systemitem> collects all log
+ entries. When the <systemitem>ProcessInstance</systemitem> is saved,
+ they are flushed from here to the database. (The
+ <systemitem>ProcessInstance</systemitem>'s <property>logs</property>
+ field is not mapped to <application>Hibernate</application>. This is so as to
+ avoid those logs that are retrieved from the database in each
+ transaction.)
+ </para>
+
+ <para>
+ Each <systemitem>ProcessInstance</systemitem> is made in the
+ context of a path of execution and hence, the
+ <systemitem>ProcessLog</systemitem> refers to that token, which
+ also serves as an <firstterm>index sequence
+ generator</firstterm> it. (This is important for log retrieval
+ as it means that logs produced in subsequent transactions shall
+ have sequential sequence numbers.
+ </para>
+
+ <para>
+ Use this API method to add process logs:
</para>
<programlisting>public class LoggingInstance extends ModuleInstance {
@@ -69,17 +110,22 @@
...
}</programlisting>
- <para>The UML diagram for logging information looks like this:</para>
+ <para>
+ This is the UML diagram for information logging:
+ </para>
<figure id="logging.model.image">
<title>The jBPM logging information class diagram</title>
<mediaobject><imageobject><imagedata align="center" fileref="images/logging.model.gif"/></imageobject></mediaobject>
</figure>
- <para>A <literal>CompositeLog</literal>
- is a special kind of log entry. It serves as a parent log for a number of child logs,
- thereby creating the means for a hierarchical structure in the logs.
- The API for inserting a log is the following.</para>
+ <para>
+ A <firstterm>CompositeLog</firstterm> is a special case. It
+ serves as the parent log for a number of children, thereby
+ creating the means for a hierarchical structure to be applied.
+ The following application programming interface is used to
+ insert a log:
+ </para>
<programlisting>public class LoggingInstance extends ModuleInstance {
...
@@ -88,10 +134,11 @@
...
}</programlisting>
- <para>The <literal>CompositeLog</literal>s should always be called in a
- <literal>try-finally</literal>-block to make sure that the hierarchical
- structure of logs is consistent. For example:</para>
-
+ <para>
+ The <systemitem>CompositeLog</systemitem>s should always be called
+ in a <methodname>try-finally-block</methodname> to make sure that the
+ hierarchical structure is consistent. For example:
+ </para>
<programlisting>startCompositeLog(new MyCompositeLog());
try {
...
@@ -102,29 +149,45 @@
</section>
<section id="logconfigurations">
- <title>Log configurations</title>
- <para>For deployments where logs are not important, it suffices to remove the logging line in the
- jbpm-context section of the jbpm.cfg.xml configuration file:
+ <title>
+ Log Configurations
+ </title>
+
+ <para>
+ If logs are not important for a particular deployment, simply remove
+ the logging line from the <property>jbpm-context</property> section
+ of the <filename>jbpm.cfg.xml</filename> configuration file:
</para>
<programlisting><service name='logging' factory='org.jbpm.logging.db.DbLoggingServiceFactory' /></programlisting>
- <para>In case you want to filter the logs, you need to write a custom implementation of the
- LoggingService that is a subclass of DbLoggingService. Also you need to create a custom
- logging ServiceFactory and specify that one in the factory attribute.
+
+ <para>
+ In order to filter the logs, write a custom implementation of the
+ <classname>LoggingService</classname> (this is a subclass of
+ <classname>DbLoggingService</classname>.) Having done so, create a
+ custom <systemitem>ServiceFactory</systemitem> for logging and
+ specify it in the <systemitem>factory</systemitem> attribute.
</para>
</section>
<section id="logretrieval">
- <title>Log retrieval</title>
- <para>As said before, logs cannot be retrieved from the database by navigating
- the LoggingInstance to its logs. Instead, logs of a process instance should always
- be queried from the database. The <literal>LoggingSession</literal> has 2 methods
- that serve this purpose.
+ <title>
+ Log Retrieval
+ </title>
+
+ <para>
+ Process instance logs must always be retrieved via database queries.
+ There are two methods to achieve this through
+ <systemitem>LoggingSession</systemitem>.
</para>
- <para>The first method retrieves all the logs for a process instance. These logs
- will be grouped by token in a Map. The map will associate a List of ProcessLogs
- with every Token in the process instance. The list will contain the ProcessLogs
- in the same ordered as they were created.</para>
+ <para>
+ The first method retrieves all logs for a process instance. These
+ logs will be grouped by token in a map. This map will associate a
+ list of <systemitem>ProcessLogs</systemitem> with every token in the
+ process instance. The list will contain the
+ <systemitem>ProcessLogs</systemitem> in the same order as that in
+ which they were created.
+ </para>
<programlisting>public class LoggingSession {
...
@@ -132,8 +195,11 @@
...
}</programlisting>
- <para>The second method retrieves the logs for a specific Token. The returned list
- will contain the ProcessLogs in the same ordered as they were created.</para>
+ <para>
+ The second method retrieves the logs for a specific token. The list will contain the
+ <systemitem>ProcessLogs</systemitem> in the same order as that in
+ which they were created.
+ </para>
<programlisting>public class LoggingSession {
public List findLogsByToken(long tokenId) {...}
@@ -155,9 +221,13 @@
analysis. Data warehousing even might be done on a modified database schema which is
optimized for its purpose.</para>
- <para>In this section, we only want to propose the technique of warehousing in
- the context of jBPM. The purposes are too diverse, preventing a generic solution
- to be included in jBPM that could cover all those requirements.</para>
+ <para>
+ Having perused this chapter, the reader will now know how logging
+ works in jBPM and has some idea of the various uses to which it can
+ be put.
+ </para>
+
</section>
+
</chapter>
Modified: jbpm3/branches/jbpm-3.2-soa/modules/userguide/src/main/docbook/en-US/mail.xml
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/userguide/src/main/docbook/en-US/mail.xml 2010-06-22 17:57:45 UTC (rev 6429)
+++ jbpm3/branches/jbpm-3.2-soa/modules/userguide/src/main/docbook/en-US/mail.xml 2010-06-22 22:03:45 UTC (rev 6430)
@@ -4,25 +4,44 @@
%BOOK_ENTITIES;
]>
<chapter id="mail">
- <title>Email support</title>
+ <title>
+ E. Mail Support
+ </title>
- <para>This chapter describes the out-of-the-box email support in jBPM jPDL.
+ <para>
+ This chapter describes the "out-of-the-box" e. mail support
+ available in Business Process Manager JPDL. Read this information to
+ learn how to configure different aspects of the mail functionality.
</para>
<section id="mailinjpdl">
- <title>Mail in jPDL</title>
+ <title>
+ Mail in JPDL
+ </title>
- <para>There are four ways of specifying when emails should be sent from a process.
+ <para>
+ There are four ways in which one can specify the point in time at
+ which e. mails are to be sent from a process. Each shall be examined
+ in turn.
</para>
+
<section id="mailaction">
- <title>Mail action</title>
- <para>A mail action can be used when the sending of this email should <emphasis role="bold">not</emphasis>
- be shown as a node in the process graph.
+ <title>
+ Mail Action
+ </title>
+
+ <para>
+ Use a <firstterm>mail action</firstterm> if there is a reason not
+ to show the e. mail as a node in the process graph.
</para>
- <para>Anywhere you are allowed to specify actions in the process, you can specify a mail action
- like this:
+
+<note>
+ <para>
+ A mail action can be added to the process anywhere that a normal
+ action can be added.
</para>
+</note>
<programlisting><mail actors="#{president}" subject="readmylips" text="nomoretaxes" /></programlisting>
<para>The subject and text attributes can also be specified as an element like this:</para>
<programlisting><mail actors="#{president}" >
@@ -30,62 +49,108 @@
<text>nomoretaxes</text>
</mail>
</programlisting>
- <para>Each of the fields can contain JSF like expressions. For example:
- </para>
+ <para>
+ Specify the subject and text attributes as an element like this:
+ </para>
+
<programlisting><mail to='#{initiator}' subject='websale' text='your websale of #{quantity} #{item} was approved' /></programlisting>
- <para>There are two attribute to specify recipients: <literal>actors</literal> and
- <literal>to</literal>. The <literal>to</literal> attribute should resolve to a semicolon
- separated list of email addresses. The <literal>actors</literal> attribute should resolve to a
- semicolon separated list of actorIds. Those actorIds will be resolved to email addresses with by
- means of address resolving (<xref linkend="addressresolving"/>).
+ <para>
+ Two attribute specify the recipients: <property>actors</property>
+ and <property>to</property>. The <property>to</property> attribute
+ should "resolve" to a semi-colon separated list of e. mail
+ addresses. The <property>actors</property> attribute should
+ resolve to a semi-colon separated list of
+ <property>actorIds</property>. These <property>actorIds</property>
+ will, in turn, resolve to e. mail addresses. (Refer to <xref
+ linkend="addressresolving" /> for more details.)
</para>
+
<programlisting><mail to='admin(a)mycompany.com' subject='urgent' text='the mailserver is down :-)' /></programlisting>
<para>For more about how to specify recipients, see <xref linkend="specifyingmailrecipients" /></para>
<para>Mails can be defined in templates and in the process you can overwrite properties of the
templates like this:
</para>
<programlisting><mail template='sillystatement' actors="#{president}" /></programlisting>
- <para>More about templates can be found in <xref linkend="mailtemplates" /></para>
+ <note>
+ <para>
+ Learn more about templates by reading <xref
+ linkend="mailtemplates" />
+ </para>
+</note>
</section>
<section id="mailnode">
- <title>Mail node</title>
- <para>Just the same as with mail actions, sending of an email can also be modelled as a node.
- In that case, the runtime behaviour is just the same, but the email will show up as a node
- in the process graph.
+ <title>
+ Mail Node
+ </title>
+
+ <para>
+ As with mail actions, the action of sending an e. mail can be
+ modeled as a node. In this case, the run-time behavior will be
+ identical identical but the e. mail will display as a node in the
+ <firstterm>process graph</firstterm>.
</para>
- <para>The attributes and elements supported by mail nodes are exactly the same as with
- the mail actions (<xref linkend="mailaction" />).
+
+ <para>
+ Mail nodes support exactly the same attributes and elements as the
+ <systemitem>mail action</systemitem>. (See <xref linkend="mailaction" />
+ to find out more.)
</para>
+
<programlisting><mail-node name="send email" to="#{president}" subject="readmylips" text="nomoretaxes">
<transition to="the next node" />
</mail-node></programlisting>
- <para>Mail nodes should have exactly one leaving transition.</para>
+
+<important>
+ <para>
+ Always ensure that mail nodes have exactly one
+ <firstterm>leaving</firstterm> transition.
+ </para>
+</important>
+
</section>
<section id="taskassignmails">
- <title>Task assign mails</title>
- <para>A notification email can be send when a task gets assigned to an actor. Just use
- the <literal>notify="yes"</literal> attribute on a task like this:
+ <title>
+ "Task Assigned" E. Mail
+ </title>
+
+ <para>
+ A notification e. mail can be sent when a task is assigned to an
+ actor. To configure this feature, add the
+ <code>notify="yes"</code> attribute to a task in the following
+ manner:
</para>
+
<programlisting><task-node name='a'>
<task name='laundry' swimlane="grandma" <emphasis role="bold">notify='yes'</emphasis> />
<transition to='b' />
</task-node>
</programlisting>
- <para>Setting notify to yes, true or on will cause jBPM to send an email to
- the actor that will be assigned to this task. The email is based on a template (see
- <xref linkend="mailtemplates" />) and contains a link to the task page of the web application.
+
+ <para>
+ Set notify to <code>yes</code>, <code>true</code> or
+ <code>on</code> to make the Business Process Manager send an e.
+ mail to the actor being assigned to the task. (Note that this e.
+ mail is based on a template and contains a link to the web
+ application's task page.)
</para>
</section>
<section id="taskremindermails">
- <title>Task reminder mails</title>
- <para>Similarly as with assignments, emails can be send as a task reminder. The <literal>reminder</literal>
- element in jPDL is based upon the timer. The most common attributes will be the <literal>duedate</literal>
- and the <literal>repeat</literal>. The only difference is that no action has to be specified.
+ <title>
+ "Task Reminder" E. Mail
+ </title>
+
+ <para>
+ E. mails can be sent as task reminders. JPDL's
+ <property>reminder</property> element utilizes the timer. The
+ most commonly used attributes are <property>duedate</property>
+ and <property>repeat</property>. Note that actions do not have
+ to be specified.
</para>
+
<programlisting><task-node name='a'>
<task name='laundry' swimlane="grandma" notify='yes'>
<reminder duedate="2 business days" repeat="2 business hours"/>
@@ -97,39 +162,72 @@
</section>
<section id="expressionsinmails">
- <title>Expressions in mails</title>
- <para>The fields <literal>to</literal>, <literal>recipients</literal>, <literal>subject</literal>
- and <literal>text</literal> can contain JSF-like expressions.
+ <title>
+ Expressions in Mail
+ </title>
+
+ <para>
+ The fields <code>to</code>, <code>recipients</code>,
+ <code>subject</code> and <code>text</code> can contain
+ JSF-like expressions. (For more information about expressions, see
+ <xref linkend="expressions" />.)
</para>
- <para>The variables in the expressions can be: swimlanes, process variables, transient variables
- beans configured in the jbpm.cfg.xml, ...
+
+ <para>
+ One can use the following variables in expressions:
+ <property>swimlanes</property>, <property>process
+ variables</property> and <property>transient variables
+ beans</property>. Configure them via the
+ <filename>jbpm.cfg.xml</filename> file.
</para>
- <para>These expressions can be combined with the address resolving (<xref linkend="addressresolving" />)
- that is explained later in this chapter. For example, suppose that you have a swimlane called president in
- your process, then look at the following mail specification:
- </para>
+
+ <para>
+ Expressions can be combined with <firstterm>address
+ resolving</firstterm> functionality. (Refer to <xref
+ linkend="addressresolving"/>. for more information.)
+ </para>
<programlisting><mail actors="#{president}" subject="readmylips" text="nomoretaxes" /></programlisting>
- <para>That will send an email to to the person that acts as the president for that perticular process
- execution.
+ <para>
+ The code will send an e. mail to the person that acts as the
+ <literal>president</literal> for that particular process execution.
</para>
</section>
<section id="specifyingmailrecipients">
- <title>Specifying mail recipients</title>
+ <title>
+ Specifying E. Mail Recipients
+ </title>
+
<section id="multiplerecipients">
- <title>Multiple recipients</title>
- <para>In the <literal>actors</literal> and <literal>to</literal> fields, multiple recipients
- can be separated with a comma (,) semi colon (;) or colon (:).</para>
+ <title>Multiple Recipients</title>
+ <para>
+ Multiple recipients can be listed in the
+ <property>actors</property> and <property>to</property> fields.
+ Separate items in the list with either a colon or a semi-colon.
+ </para>
</section>
+
<section id="BCC">
- <title>Sending Mails to a BCC recipient</title>
- <para>Sometimes you want to send emails to a BCC recipient in addition to the normal recipient.
- Currently, there are two supported ways of doing that: First you can specify an <literal>bccActors</literal>
- or <literal>bcc</literal> attribute (according to <literal>actors</literal> and <literal>to</literal>)
- in the process definition.</para>
+ <title>
+ Sending E. Mail to a BCC Address
+ </title>
+
+ <para>
+ In order to send messages to a <firstterm>Blind Carbon
+ Copy</firstterm> (BCC) recipient, use either the
+ <property>bccActors</property> or the <property>bcc</property>
+ attribute in the process definition.
+ </para>
+
<programlisting><mail to='#{initiator}' bcc='bcc(a)mycompany.com' subject='websale' text='your websale of #{quantity} #{item} was approved' /></programlisting>
- <para>The second way is to always send a BCC mail to some location you can configure in a
- property of the configuration file (jbpm.cfg.xml):</para>
+
+ <para>
+ An alternative approach is to always send BCC messages to some
+ location that has been centrally configured in
+ <filename>jbpm.cfg.xml</filename>. This example demonstrates how
+ to do so:
+ </para>
+
<programlisting><jbpm-configuration>
...
<string name="jbpm.mail.bcc.address" value="bcc(a)mycompany.com" />
@@ -142,43 +240,86 @@
<para>There is no provision to send mail to a preconfigured CC recipient though.</para>
</section>
<section id="addressresolving">
- <title>Address resolving</title>
- <para>In all of jBPM, actors are referenced by actorId's. This is a string that servers as the identifier
- of the process participant. An address resolver translates actorId's into email addresses.
+ <title>
+ Address Resolving
+ </title>
+
+ <para>
+ Throughout the Business Process Manager, actors are referenced
+ by <systemitem>actorIds</systemitem>. These are strings that
+ serves to identify process participants. An <firstterm>address
+ resolver</firstterm> translates
+ <systemitem>actorIds</systemitem> into e. mail addresses.
</para>
- <para>Use the attribute <emphasis role="bold">actors</emphasis> in case you want to apply address resolving
- and use the attribute <emphasis role="bold">to</emphasis> in case you are specifying email addresses
- directly and don't want to apply address resolving.
+
+ <para>
+ Use the attribute actors to apply address resolving. Conversely,
+ use the <property>to</property> attribute if adding addresses
+ directly as it will not run apply address resolving.
</para>
- <para>An address resolver should implement the following interface:
+
+ <para>
+ Make sure the address resolver implements the following interface:
</para>
<programlisting>public interface AddressResolver extends Serializable {
Object resolveAddress(String actorId);
}</programlisting>
- <para>An address resolver should return one of the following: a String, a Collection of Strings or an array
- of Strings. All strings should represent email addresses for the given actorId.
+ <para>
+ An address resolver will return one of the following three
+ types: a string, a collection of strings or an array of strings.
+ (Strings must always represent e. mail addresses for the given
+ <systemitem>actorId</systemitem>.)
</para>
- <para>The address resolver implementation should be a bean configured in the jbpm.cfg.xml with
- name <literal>jbpm.mail.address.resolver</literal> like this:
+
+ <para>
+ Ensure that the address resolver implementation is a bean. This
+ bean must be configured in the <filename>jbpm.cfg.xml</filename>
+ file with name
+ <systemitem>jbpm.mail.address.resolver</systemitem>, as per this
+ example:
</para>
+
<programlisting><jbpm-configuration>
...
<bean name='jbpm.mail.address.resolver' class='org.jbpm.identity.mail.IdentityAddressResolver' singleton='true' />
</jbpm-configuration>
</programlisting>
- <para>The identity component of jBPM includes an address resolver. That address resolver
- will look for the User of the given actorId. If the user exists, the user's email is returned,
- otherwise null. More on the identity component can be found in <xref linkend="theidentitycomponent" />.
+
+ <para>
+ The Business Process Manager's <systemitem>identity</systemitem>
+ component includes an address resolver. This address resolver
+ will look for the given <systemitem>actorId</systemitem>'s
+ user. If the user exists, his or her
+ e. mail address will be returned. If not, null will be returned.
+ </para>
+
+ <note>
+ <para>
+ To learn more about the identity
+ component, read <xref linkend="theidentitycomponent"
+ />.
</para>
+ </note>
+
+
</section>
</section>
<section id="mailtemplates">
- <title>Mail templates</title>
- <para>Instead of specifying mails in the processdefinition.xml, mails can be specified in a template
- file. When a template is used, each of the fields can still be overwritten in the processdefinition.xml.
- The mail templates should be specified in an XML file like this:
+
+ <title>
+ E. Mail Templates
+ </title>
+
+
+ <para>
+ Instead of using the <filename>processdefinition.xml</filename>
+ file to specify e. mails, one can use a template. In this case,
+ each of the fields can still be overwritten by
+ <filename>processdefinition.xml</filename>. Specify a templates
+ like this:
</para>
+
<programlisting>
<mail-templates>
@@ -205,12 +346,16 @@
</mail-templates>
</programlisting>
- <para>As you can see in this example (BaseTaskListURL), extra variables can be defined in
- the mail templates that will be available in the expressions.
+ <para>
+ As per the above, extra variables can be defined in the mail
+ templates and these will be available in the expressions.
</para>
- <para>The resource that contains the templates should be configured in the jbpm.cfg.xml
- like this:
+
+ <para>
+ Configure the resource that contains the templates via the
+ <filename>jbpm.cfg.xml</filename> like this:
</para>
+
<programlisting><jbpm-configuration>
...
<string name="resource.mail.templates" value="jbpm.mail.templates.xml" />
@@ -218,10 +363,16 @@
</section>
<section id="mailserverconfiguration">
- <title>Mail server configuration</title>
- <para>The simplest way to configure the mail server is with the
- <literal>jbpm.mail.smtp</literal> properties in the configuration like this:
+ <title>
+ Mail Server Configuration
+ </title>
+
+ <para>
+ Configure the mail server by setting the
+ <property>jbpm.mail.smtp.host</property> property in the
+ <filename>jbpm.cfg.xml</filename> file, as per this example code:
</para>
+
<programlisting><jbpm-configuration>
...
<string name="jbpm.mail.smtp.host" value="localhost" />
@@ -238,11 +389,17 @@
</section>
<section id="fromaddressconfiguration">
- <title>From address configuration</title>
- <para>The default value for the From address used in jPDL mails is <literal>no-reply(a)jbpm.org</literal>.
- The from address of mails can be configured in the configuration file jbpm.cfg.xml under
- key <literal>jbpm.mail.from.address</literal>.
+ <title>
+ "From" Address Configuration
+ </title>
+
+ <para>
+ The default value for the <systemitem>From</systemitem> address
+ field <literal>jbpm@noreply</literal>. Configure it via the
+ <filename>jbpm.xfg.xml</filename> file with key
+ <systemitem>jbpm.mail.from.address</systemitem> like this:
</para>
+
<programlisting><jbpm-configuration>
...
<string name='jbpm.mail.from.address' value='jbpm(a)yourcompany.com' />
@@ -250,20 +407,41 @@
</section>
<section id="customizingmailsupport">
- <title>Customizing mail support</title>
- <para>All the mail support in jBPM is centralized in one class: <literal>org.jbpm.mail.Mail</literal>
- This is an ActionHandler implementation. Whenever an mail is specified in the process xml, this will
- result in a delegation to the mail class. It is possible to inherit from the Mail class and customize
- certain behaviour for your perticular needs. To configure your class to be used for mail delegations,
- specify a 'jbpm.mail.class.name' configuration string in jbpm.cfg.xml like this:
+ <title>
+ Customizing E. Mail Support
+ </title>
+
+ <para>
+ All of the Business Process Manager's e. mail support is
+ centralized in one class, namely
+ <classname>org.jbpm.mail.Mail</classname> This class is an
+ <systemitem>ActionHandler</systemitem> implementation. Whenever
+ an e. mail is specified in the <systemitem>process</systemitem>
+ XML, a delegation to the <classname>mail</classname> class will
+ result. It is possible to inherit from the
+ <classname>mail</classname> class and customize certain behavior
+ for specific needs. To configure a class to be used for mail
+ delegations, specify a <code>jbpm.mail.class.name</code>
+ configuration string in the <filename>jbpm.cfg.xml</filename>
+ like this:
</para>
<programlisting><jbpm-configuration>
...
<string name='jbpm.mail.class.name' value='com.your.specific.CustomMail' />
</jbpm-configuration></programlisting>
- <para>The customized mail class will be read during parsing and actions will be configured in the
- process that reference the configured (or the default) mail classname. So if you change the
- property, all the processes that were already deployed will still refer to the old mail class name.
- But they can be easily updated with one simple update statement to the jbpm database.</para>
+ <para>
+ The customized mail class will be read during parsing. Actions
+ will be configured in the process that reference the configured (or
+ the default) mail classname. Hence, if the property is changed, all the
+ processes that were already deployed will still refer to the old
+ mail classname. Alter them simply by sending an
+ update statement directed at the jBPM database.
+ </para>
+
+ <para>
+ This chapter has provided detailed information on how to configure
+ various e. mail settings. Having studied the examples carefully, one
+ can now practice configuring one's own environment
+ </para>
</section>
</chapter>
Modified: jbpm3/branches/jbpm-3.2-soa/modules/userguide/src/main/docbook/en-US/modelling.xml
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/userguide/src/main/docbook/en-US/modelling.xml 2010-06-22 17:57:45 UTC (rev 6429)
+++ jbpm3/branches/jbpm-3.2-soa/modules/userguide/src/main/docbook/en-US/modelling.xml 2010-06-22 22:03:45 UTC (rev 6430)
@@ -4,60 +4,109 @@
%BOOK_ENTITIES;
]>
<chapter id="processmodelling">
- <title>Process Modelling</title>
+ <title>
+ Process Modeling
+ </title>
- <section id="overview">
- <title>Overview</title>
+ <section id="helpfuldefinitions">
+ <title>
+ Some Helpful Definitions
+ </title>
+
+ <para>
+ Read this section to learn the terminology that you will find
+ used throughout the rest of this book.
+ </para>
+
+ <para>
+ A <firstterm>process definition</firstterm> represents a formal
+ specification of a business process and is based on a
+ <firstterm>directed graph</firstterm>. The graph is composed of
+ nodes and transitions. Every node in the graph is of a specific
+ type. The node type defines the run-time behavior. A process
+ definition only has one start state.
+ </para>
- <para>A process definition represents a formal specification of a business process and
- is based on a directed graph. The graph is composed of nodes and transitions. Every
- node in the graph is of a specific type. The type of the node defines the runtime
- behaviour. A process definition has exactly one start state.</para>
+ <para>
+ A <firstterm>token</firstterm> is one path of execution. A token is
+ the runtime concept that maintains a pointer to a node in the graph.
+ </para>
- <para>A token is one path of execution. A token is the runtime concept that maintains
- a pointer to a node in the graph.</para>
+ <para>
+ A <firstterm>process instance</firstterm> is one execution of a
+ process definition. When a process instance is created, a token is
+ generated for the main path of execution. This token is called the
+ <firstterm>root token</firstterm> of the process instance and it is
+ positioned in the <firstterm>start state</firstterm> of the process
+ definition.
+ </para>
- <para>A process instance is one execution of a process definition. When a process instance
- is created, a token is created for the main path of execution. This token is called the
- root token of the process instance and it is positioned in the start state of the process
- definition.</para>
-
- <para>A signal instructs a token to continue graph execution. When receiving an unnamed
- signal, the token will leave its current node over the default leaving transition. When
- a transition-name is specified in the signal, the token will leave its node over the
- specified transition. A signal given to the process instance is delegated to the
- root token.</para>
+ <para>
+ A signal instructs a token to continue to execute the graph. When it
+ receives an unnamed signal, the token will leave its current node
+ over the default <firstterm>leaving transition</firstterm>. When a
+ <firstterm>transition-name</firstterm> is specified in the signal,
+ the token will leave its node over the specified transition. A
+ signal given to the process instance is delegated to the root token.
+ </para>
- <para>After the token has entered a node, the node is executed. Nodes themselves are
- responsible for the continuation of the graph execution. Continuation of graph execution
- is done by making the token leave the node. Each node type can implement a different
- behaviour for the continuation of the graph execution. A node that does not propagate
- execution will behave as a state.</para>
+ <para>
+ After the token has entered a node, the node is executed. Nodes
+ themselves are responsible for making the graph execution continue.
+ Continuation of graph execution is achieved by making the token
+ leave the node. Each type of node can implement a different behavior
+ for the continuation of the graph execution. A node that does not
+ pass on the execution will behave as a <firstterm>state</firstterm>.
+ </para>
- <para>Actions are pieces of java code that are executed upon events in the process
- execution. The graph is an important instrument in the communication about software
- requirements. But the graph is just one view (projection) of the software being produced.
- It hides many technical details. Actions are a mechanism to add technical details outside
- of the graphical representation. Once the graph is put in place, it can be decorated with
- actions. The main event types are entering a node, leaving a node and taking a
- transition.</para>
- <!-- same paragraph again below?? -->
+ <para>
+ <firstterm>Actions</firstterm> are pieces of Java code that are
+ executed upon events during the process execution. The
+ <firstterm>graph</firstterm> is an important instrument in the
+ communication of software requirements but it is just one view
+ (<firstterm>projection</firstterm>) of the software being produced.
+ It hides many technical details. Actions are a mechanism one uses to
+ add technical details beyond those of the graphical representation.
+ Once the graph is put in place, it can be decorated with actions.
+ The main <firstterm>event types</firstterm> are <systemitem>entering
+ a node</systemitem>, <systemitem>leaving a node</systemitem> and
+ <systemitem>taking a transition</systemitem>.
+ </para>
+
+ <para>
+ Having learned these definitions, read on to find out how
+ process modelling works.
+ </para>
+
</section>
<section id="processgraph">
- <title>Process graph</title>
- <para>The basis of a process definition is a graph that is made up of nodes and transitions.
- That information is expressed in an xml file called <literal>processdefinition.xml</literal>.
- Each node has a type like e.g. state, decision, fork, join,... Each node has a set of leaving
- transitions. A name can be given to the transitions that leave a node in order to make them distinct.
- For example: The following diagram shows a process graph of the jBAY auction process.</para>
+ <title>
+ Process Graph
+ </title>
+
+ <para>
+ A process definition is a graph that is made up of nodes and
+ transitions. This information is expressed in XML and found in a file called
+ <filename>processdefinition.xml</filename>. Each node must have a
+ <firstterm>type</firstterm> (examples being
+ <systemitem>state</systemitem>, <systemitem>decision</systemitem>,
+ <systemitem>fork</systemitem> and <systemitem>join</systemitem>.)
+ Each node has a set of <firstterm>leaving transitions</firstterm>. Names can be given to
+ the transitions that leave a node in order to make them distinct
+ from each other. For example, the following diagram shows a process
+ graph for an auction process.
+ </para>
<figure id="auction.process.graph.image">
<title>The auction process graph</title>
<mediaobject><imageobject><imagedata align="center" fileref="images/auction.process.graph.gif"/></imageobject></mediaobject>
</figure>
- <para>Below is the process graph of the jBAY auction process represented as xml:</para>
+ <para>
+ Below is the process graph for the same auction process, albeit
+ represented in XML this time:
+ </para>
<programlisting><process-definition>
<start-state>
@@ -100,182 +149,281 @@
</section>
<section id="nodes">
- <title>Nodes</title>
- <para>A process graph is made up of nodes and transitions. <!-- For more information about the
- graph and its executional model, refer to <xref linkend="graphorientedprogramming" />. -->
+ <title>
+ Nodes
+ </title>
+
+ <para>
+ A process graph is made up of nodes and transitions. Each node is of
+ a specific type. The node type determines what will happen when an
+ execution arrives in the node at run-time. The Business Process
+ Manager provides a set of node types to use. Alternatively, one
+ can write custom code to implement a specific node behavior.
</para>
- <para>Each node has a specific type. The node type determines what will happen when
- an execution arrives in the node at runtime. jBPM has a set of preimplemented node types
- that you can use. Alternatively, you can write custom code for implementing your own specific
- node behaviour.</para>
<section id="noderesponsibilities">
- <title>Node responsibilities</title>
- <para>Each node has 2 main responsibilities: First, it can execute plain java code.
- Typically the plain java code relates to the function of the node. E.g. creating a
- few task instances, sending a notification, updating a database,... Secondly, a node
- is responsible for propagating the process execution. Basically, each node has the
- following options for propagating the process execution:</para>
- <variablelist>
- <varlistentry>
- <term>1. not propagate the execution.</term>
-
- <listitem><para>In that
- case the node behaves as a wait state. </para></listitem>
- </varlistentry>
-
-
- <varlistentry>
- <term>2. propagate the execution over one of the leaving
- transitions of the node.</term>
-
- <listitem><para>This means that the token that originally
- arrived in the node is passed over one of the leaving transitions with the API call
- executionContext.leaveNode(String). The node will now act as an automatic node in the
- sense it can execute some custom programming logic and then continue process execution
- automatically without waiting. </para></listitem>
- </varlistentry>
+ <title>
+ Node Responsibilities
+ </title>
+
+ <para>
+ Each node has two main responsibilities: firstly, it can execute
+ plain Java code, code which will normally relate to the function
+ of the node. Its second responsibility is to pass on the
+ process execution.
+ </para>
+
+ <para>
+ A node may face the following options when it attempts
+ to pass the process execution on. It will follow that course
+ which is most applicable:
+ </para>
+
+ <orderedlist>
+ <listitem>
+ <para>
+ it can not propagate the execution. (The node behaves as
+ a <systemitem>wait state</systemitem>.)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ it can propagate the execution over one of the node's
+ <systemitem>leaving transitions</systemitem>. (This
+ means that the token that originally arrived in the node
+ is passed over one of the <systemitem>leaving
+ transitions</systemitem> with the API call
+ <methodname>executionContext.leaveNode(String)</methodname>.)
+ The node will now act automatically in the sense that it
+ will execute some custom programming logic and then
+ continue the process execution automatically without
+ waiting.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ a node can "decide" to create new tokens, each of which
+ will represent a new path of execution. Each of these
+ new tokens can be launched over the node's
+ <systemitem>leaving transitions</systemitem>. A good
+ example of this kind of behavior is the <systemitem>fork
+ node</systemitem>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ it can end the path of execution. This means that the
+ token has concluded.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ it can modify the whole <firstterm>run-time
+ structure</firstterm> of the process instance. The
+ run-time structure is a process instance that contains a
+ tree of tokens, each of which represents a path of
+ execution. A node can create and end tokens, put each
+ token in a node of the graph and launch tokens over
+ transitions.
+ </para>
+ </listitem>
+ </orderedlist>
-
- <varlistentry>
- <term>3. create new paths of execution.</term>
-
- <listitem><para>A node can
- decide to create new tokens. Each new token represents a new path of execution and
- each new token can be launched over the node's leaving transitions. A good example of
- this kind of behaviour is the fork node. </para></listitem>
- </varlistentry>
-
-
- <varlistentry>
- <term>4. end paths of execution.</term>
-
- <listitem><para>A node can decide
- to end a path of execution. That means that the token is ended and the path of execution
- is finished. </para></listitem>
- </varlistentry>
-
-
- <varlistentry>
- <term>5. more general, a node can modify the whole runtime
- structure of the process instance.</term>
-
- <listitem><para>The runtime structure is a process instance
- that contains a tree of tokens. Each token represents a path of execution. A node can
- create and end tokens, put each token in a node of the graph and launch tokens over
- transitions. </para></listitem>
- </varlistentry>
- </variablelist>
-
- <para>jBPM contains --as any workflow and BPM engine-- a set of preimplemented node types
- that have a specific documented configuration and behaviour. But the unique thing about
- jBPM and the Graph Oriented Programming foundation.
- is that we open up the model for developers. Developers can write their own node behaviour
- very easy and use it in a process.
- </para>
- <para>That is where traditional workflow and BPM systems are
- much more closed. They usually supply a fixed set of node types (called the process language).
- Their process language is closed and the executional model is hidden in the runtime
- environment. Research of workflow patterns (<ulink url="http://www.workflowpatterns.com" />)
- has shown that any process language is not powerfull enough. We have decided for a simple
- model and allow developers to write their own node types. That way the JPDL process language
- is open ended.</para>
- <para>Next, we discuss the most important node types of JPDL.</para>
+ <para>
+ The Business Process Manager contains a set of pre-implemented
+ node types, each of which has a specific configuration and
+ behavior. However, one can also write one's own node behavior
+ and use it in a process.
+ </para>
</section>
<section id="nodetypetasknode">
- <title>Nodetype task-node</title>
- <para>A task node represents one or more tasks that are to be performed by humans.
- So when execution arrives in a task node, task instances will be created in the task
- lists of the workflow participants. After that, the node will behave as a wait state.
- So when the users perform their task, the task completion will trigger the resuming
- of the execution. In other words, that leads to a new signal being called on the token.
+ <title>
+ Node Type: Task Node
+ </title>
+
+ <para>
+ A <firstterm>task node</firstterm> represents one or more tasks
+ that are to be performed by humans. Thus, when the execution
+ process arrives in a node, task instances will be created in
+ the lists belonging to the workflow participants. After that, the node
+ will enter a <systemitem>wait state</systemitem>. When the
+ users complete their tasks, the execution will be triggered,
+ making it resume.
</para>
</section>
<section id="nodetypetaskstate">
- <title>Nodetype state</title>
- <para>A state is a bare-bones wait state. The difference with a task node is that
- no task instances will be created in any task list. This can be usefull if the process
- should wait for an external system. E.g. upon entry of the node (via an action on the node-enter
- event), a message could be sent to the external system. After that, the process will
- go into a wait state. When the external system send a response message, this can lead to
- a token.signal(), which triggers resuming of the process execution.</para>
+ <title>
+ Node Type: State
+ </title>
+
+ <para>
+ A <firstterm>state</firstterm> is a "bare bones"
+ <systemitem>wait state</systemitem>. It differs from a task node
+ in that no task instances will be created for any task list.
+ This can be useful if the process is waiting for an external
+ system. After that, the process will go into a wait state. When
+ the external system send a response message, a
+ <methodname>token.signal()</methodname> is normally invoked,
+ triggering the resumption of the process execution.
+ </para>
</section>
+
<section id="nodetypedecision">
- <title>Nodetype decision</title>
- <para>Actually there are 2 ways to model a decision. The distinction between the two
- is based on *who* is making the decision. Should the decision made by the process (read:
- specified in the process definition). Or should an external entity provide the result of
- the decision.</para>
- <para>When the decision is to be taken by the process, a decision node should be used.
- There are basically 2 ways to specify the decision criteria. Simplest is by adding
- condition elements on the transitions. Conditions are EL expressions or beanshell scripts
- that return a boolean.</para>
- <para>At runtime the decision node will FIRST loop over its leaving transitions THAT HAVE
- a condition specified. It will evaluate those transitions first in
- the order as specified in the xml. The first transition for which the conditions resolves to
- 'true' will be taken. If all transitions with a condition resolve to false, the default
- transition (the first in the XML) is taken.</para>
- <para>Another approach is to use an expression that returns the name
- of the transition to take. With the 'expression' attribute, you can specify an expression
- on the decision that has to resolve to one of the leaving transitions of the decision node.</para>
- <para>Next aproach is the 'handler' element on the decision, that element can be used to specify
- an implementation of the DecisionHandler interface can be specified on the decision node. Then the
- decision is calculated in a java class and the selected leaving transition is returned by the decide-method
- of the DecisionHandler implementation.</para>
- <para>When the decision is taken by an external party (meaning: not part of the process
- definition), you should use multiple transitions leaving a state or wait state node.
- Then the leaving transition can be provided in the external trigger that resumes execution
- after the wait state is finished. E.g. <literal>Token.signal(String transitionName)</literal>
- and <literal>TaskInstance.end(String transitionName)</literal>.
+ <title>
+ Node Type: Decision
+ </title>
+
+ <para>
+ There are two ways in which one can model a decision,
+ the choice as to which to use being left to the discretion of
+ the user. The options are:
+ <orderedlist>
+ <listitem>
+ <para>the decision is made by the process, and is therefore
+ specified in the process definition,</para>
+ </listitem>
+ <listitem>
+ <para>an external entity decides.</para>
+ </listitem>
+ </orderedlist>
</para>
+
+ <para>
+ When the decision is to be undertaken by the process, use a
+ <systemitem>decision node</systemitem>. Specify the decision
+ criteria in one of two ways, the simplest being to add condition
+ elements to the transitions. (Conditions are EL expressions or
+ beanshell scripts that return a Boolean value.)
+ </para>
+
+ <para>
+ At run-time, the decision node will, firstly, loop over those
+ <systemitem>leaving transitions</systemitem> on which conditions
+ have been specified. It will evaluate those transitions first in
+ the order specified in the XML. The first transition for which the
+ condition resolves to <code>true</code> will be taken. If the
+ conditions for all transitions resolve to <code>false</code>, the
+ default transition, (the first in the XML), will taken instead.
+ </para>
+
+ <para>
+ The second approach is to use an expression that returns the name
+ of the transition to take. Use the
+ <property>expression</property> attribute to specify an
+ expression on the decision. This will need to resolve to one of the
+ decision node's <systemitem>leaving transitions</systemitem>.
+ </para>
+
+ <para>
+ One can also use the <property>handler</property> element on the
+ decision, as this element can be used to specify an implementation
+ of the <interfacename>DecisionHandler</interfacename> interface
+ that can be specified on the decision node. In this scenario, the
+ decision is calculated by a Java class and the selected
+ <systemitem>leaving transition</systemitem> is returned by the
+ <methodname>decide</methodname> method, which belongs to the
+ <interfacename>DecisionHandler</interfacename> implementation.
+ </para>
+
+ <para>
+ When the decision is undertaken by an external party, always use
+ multiple transitions that will leave a
+ <systemitem>state</systemitem> or <systemitem>wait
+ state</systemitem> node. The leaving transition can then be
+ provided in the external trigger that resumes execution after the
+ <systemitem>wait state</systemitem> is finished (these might, for
+ example, be <methodname>Token.signal(String
+ transitionName)</methodname> or
+ <methodname>TaskInstance.end(String transitionName)</methodname>.)
+ </para>
</section>
+
<section id="nodetypefork">
- <title>Nodetype fork</title>
- <para>A fork splits one path of execution into multiple concurrent paths of execution. The
- default fork behaviour is to create a child token for each transition that leaves the fork,
- creating a parent-child relation between the token that arrives in the fork.</para>
+
+ <title>
+ Node Type: Fork
+ </title>
+
+ <para>
+ A fork splits a single path of execution into multiple concurrent
+ ones. By default, the fork creates a child
+ token for each transition that leaves it, (thereby creating a
+ parent-child relation between the tokens that arrives in the
+ fork.)
+ </para>
+
+
</section>
<section id="nodetypejoin">
- <title>Nodetype join</title>
- <para>The default join assumes that all tokens that arrive in the join are children of the
- same parent. This situation is created when using the fork as mentioned above and when all
- tokens created by a fork arrive in the same join. A join will end every token that enters the
- join. Then the join will examine the parent-child relation of the token that enters the
- join. When all sibling tokens have arrived in the join, the parent token will be propagated
- over the (unique!) leaving transition. When there are still sibling tokens active, the join
- will behave as a wait state.</para>
+ <title>
+ Node Type: Join
+ </title>
+
+ <para>
+ By default, the join assumes that all tokens that arrive within
+ itself are children of the same parent. (This situation occurs
+ when using the fork as mentioned above and when all tokens created
+ by a fork arrive in the same join.)
+ </para>
+ <para>
+ A join will end every token
+ that enters it. It will then examine the parent-child relation of
+ those tokens. When all sibling tokens have arrived in
+ the join, the parent token will be passed through to the <systemitem>leaving
+ transition</systemitem>. When there are still sibling tokens active, the join
+ will behave as a <systemitem>wait state</systemitem>.
+ </para>
+
</section>
+
<section id="nodetypenode">
- <title>Nodetype node</title>
- <para>The type node serves the situation where you want to write your own code in a node.
- The nodetype node expects one subelement action. The action is executed when the execution
- arrives in the node. The code you write in the actionhandler can do anything you want but
- it is also responsible for propagating the execution (<xref linkend="noderesponsibilities" />.)
+ <title>
+ Node Type: Node
+ </title>
+
+ <para>
+ Use this node to avoid writing custom code. It expects only one
+ sub-element action, which will be run when the execution arrives
+ in the node. Custom code written in
+ <systemitem>actionhandler</systemitem> can do anything but be
+ aware that it is also responsible for passing on the execution.
+ (See <xref linkend="noderesponsibilities"/> for more information.)
</para>
- <para>This node can be used if you want to use a JavaAPI to implement some functional logic that
- is important for the business analyst. By using a node, the node is visible in the graphical
- representation of the process. For comparison, actions --covered next-- will allow you to
- add code that is invisible in the graphical representation of the process, in case that logic
- is not important for the business analyst.
+
+ <para>
+ This node can also be used when one is utilizing a Java API to
+ implement some functional logic for a corporate business analyst.
+ It is advantageous to do so this way because the node remains
+ visible in the graphical representation of the process. (Use
+ actions to add code that is invisible in the graphical
+ representation of the process.)
</para>
</section>
</section>
<section id="transitions">
- <title>Transitions</title>
- <para>Transitions have a source node and a destination node. The source node is represented with
- the property <literal>from</literal> and the destination node is represented by the property
- <literal>to</literal>.
+ <title>
+ Transitions
+ </title>
+
+ <para>
+ Transitions have both source and destination nodes. The source
+ node is represented by the property <property>from</property>
+ and the destination is represented by <property>to</property>.
</para>
- <para>A transition can optionally have a name. Note that most of the jBPM features depend on the uniqueness
- of the transition name. If more then one transition has the same name, the first transition with
- the given name is taken. In case duplicate transition names occur in a node, the method
- <literal>Map getLeavingTransitionsMap()</literal> will return less elements than
- <literal>List getLeavingTransitions()</literal>.
+
+ <para>
+ A transition can, optionally, be given a name. (Indeed, most features
+ of the Business Process Manager depend on transitions being given
+ unique names.) If more than one transition has the same name, the
+ first of these will be taken. (In case duplicate transition names
+ occur in a node, the <methodname>Map
+ getLeavingTransitionsMap()</methodname> method will return less
+ elements than <methodname>List
+ getLeavingTransitions()</methodname>.)
</para>
- <para>The default transition is the first transition in the list.
- </para>
+
</section>
<section id="actions">
@@ -289,16 +437,24 @@
structure of the graph. The main event types are entering a node, leaving a node and taking a
transition.</para>
- <para>Note the difference between an action that is placed in an event versus an action
- that is placed in a node. Actions that are put in an event are executed when the event
- fires. Actions on events have no way to influence the flow of control of the process.
- It is similar to the observer pattern. On the other hand, an action that is put on a
-node (<xref linkend="nodetypenode" />) has the responsibility (<xref linkend="noderesponsibilities"/>)
- of propagating the execution.</para>
+ <important>
+ <para>
+ There is a difference between an action that is placed on an event
+ and an action that is placed in a node. Actions that are put in
+ events are executed when the event fires. They have
+ no way to influence the flow of control of the process. (It is
+ similar to the <firstterm>observer pattern</firstterm>.) By
+ contrast, an action placed on a node has the responsibility
+ of passing on the execution.
+ </para>
+</important>
- <para>Let's look at an example of an action on an event. Suppose we want to do a database
- update on a given transition. The database update is technically vital but it is not important
- to the business analyst.</para>
+ <para>
+ Read this section to study an example of an action on an event. It demonstrates
+ how to undertake a database update on a given
+ transition. (The database update is technically vital but it is not
+ of importance to the business analyst.)
+ </para>
<figure id="database.update.example.image">
<title>A database update action</title>
@@ -334,51 +490,89 @@
</process-definition></programlisting>
- <section id="actionconfiguration">
- <title>Action configuration</title>
- <para>For more information about adding configurations to your custom actions and how
- to specify the configuration in the <literal>processdefinition.xml</literal>.
+ <note>
+ <para>
+ To learn more about adding configurations to custom actions, see
+ <xref linkend="configurationofdelegations"/>
</para>
+ </note>
</section>
<section id="actionreferences">
- <title>Action references</title>
- <para>Actions can be given a name. Named actions can be referenced from other
- locations where actions can be specified. Named actions can also be put as child
- elements in the process definition.</para>
- <para>This feature is interesting if you want to limit duplication of action
- configurations (e.g. when the action has complicated configurations). Another
- use case is execution or scheduling of runtime actions.</para>
+ <title>
+ Action References
+ </title>
+
+ <para>
+ Actions can be given names. This allows for them be referenced from
+ other locations in which actions are specified. Named actions
+ can also be added to the process definition as <firstterm>child
+ elements</firstterm>.
+ </para>
+
+ <para>
+ Use this feature to limit duplication of action configurations.
+ (This is particularly helpful when the action has complicated
+ configurations or when run-time actions have to be scheduled or
+ executed.)
+ </para>
</section>
<section id="events">
- <title>Events</title>
- <para>Events specify moments in the execution of the process. The jBPM engine
- will fire events during graph execution. This occurs when jbpm calculats the
- next state (read: processing a signal). An event is always relative to an element
- in the process definition like e.g. the process definition, a node or a transition.
- Most process elements can fire different types of events. A node for example can
- fire a <literal>node-enter</literal> event and a <literal>node-leave</literal>
- event. Events are the hooks for actions. Each event has a list of actions.
- When the jBPM engine fires an event, the list of actions is executed.</para>
+ <title>
+ Events
+ </title>
+
+ <para>
+ <firstterm>Events</firstterm> are specific moments in the execution
+ of the process. The Business Process Manager's engine will "fire"
+ events during <firstterm>graph execution</firstterm>, which
+ occurs when the software calculates the next state, (in other
+ words, when it processes a signal.) An event is always relative to an
+ element in the process definition.
+ </para>
+ <para>
+ Most process elements can
+ fire different types of events. A node, for example, can fire both
+ <systemitem>node-enter</systemitem> and
+ <systemitem>node-leave</systemitem> events. (Events are the
+ "hooks" for actions. Each event has a list of actions. When the
+ jBPM engine fires an event, the list of actions is executed.)
+ </para>
</section>
<section id="eventpropagation">
- <title>Event propagation</title>
- <para>Superstates create a parent-child relation in the elements of a process definition.
- Nodes and transitions contained in a superstate have that superstate as a parent. Top level
- elements have the process definition as a parent. The process definition does not have a
- parent. When an event is fired, the event will be propagated up the parent hierarchy.
- This allows e.g. to capture all transition events in a process and associate actions
- with these events in a centralized location.</para>
+ <title>
+ Passing On Events
+ </title>
+ <para>
+ A <firstterm>super-state</firstterm> creates a parent-child
+ relation in the elements of a process definition. (Nodes and
+ transitions contained in a super-state will have that superstate
+ as a parent. Top-level elements have the process definition as their
+ parent which, itself, does not have a further parent.) When an
+ event is fired, the event will be passed up the parent
+ hierarchy. This allows it both to
+ capture all transition events in a process and to associate
+ actions with these events via a centralized location.
+ </para>
+
+
</section>
<section id="script">
- <title>Script</title>
- <para>A script is an action that executes a beanshell script. For more information about beanshell,
- see <ulink url="http://www.beanshell.org/">the beanshell website</ulink>.
- By default, all process variables are available as script-variables and no script-variables will be
- written to the process variables. Also the following script-variables will be available :
+ <title>
+ Scripts
+ </title>
+ <para>
+ A <firstterm>script</firstterm> is an action that executes a
+ <application>Beanshell</application> script. (For more information
+ about <application>Beanshell</application>, see <ulink
+ url="http://www.beanshell.org/" />.)
+ By default, all process variables are
+ available as script variables but no script variables will be
+ written to the process variables. The following
+ script-variables are available:
</para>
<itemizedlist>
@@ -398,9 +592,12 @@
...
</process-definition></programlisting>
- <para>To customize the default behaviour of loading and storing variables into the script, the
- <literal>variable</literal> element can be used as a sub-element of script. In that case,
- the script expression also has to be put in a subelement of script: <literal>expression</literal>.
+ <para>
+ To customize the default behavior of loading and storing
+ variables into the script, use the <property>variable</property>
+ element as a sub-element of script. If doing so, also place the
+ script expression into the script as a sub-element:
+ <property>expression</property>.
</para>
<programlisting><process-definition>
@@ -417,78 +614,118 @@
...
</process-definition></programlisting>
- <para>Before the script starts, the process variables <literal>YYY</literal> and
- <literal>ZZZ</literal> will be made available to the script as script-variables
- <literal>b</literal> and <literal>c</literal> respectively. After the script is
- finished, the value of script-variable <literal>a</literal> is stored into the
- process variable <literal>XXX</literal>.</para>
+ <para>
+ Before the script starts, the process variables
+ <code>YYY</code> and <code>ZZZ</code> will be made
+ available to the script as script-variables <code>b</code>
+ and <code>c</code> respectively. After the script is
+ finished, the value of script-variable <code>a</code> is
+ stored into the process variable <code>XXX</code>.
+ </para>
- <para>If the <literal>access</literal> attribute of <literal>variable</literal> contains
- '<literal>read</literal>', the
- process variable will be loaded as a script-variable before script evaluation. If the
- <literal>access</literal> attribute contains '<literal>write</literal>', the script-variable
- will be stored as a process variable after evaluation.
- The attribute <literal>mapped-name</literal> can make the process variable available under another
- name in the script. This can be handy when your process variable names contain spaces or other
- invalid script-literal-characters.
+ <para>
+ If the variable's <property>access</property> attribute contains
+ <code>read</code>, the process variable will be loaded as a script
+ variable before the script is evaluated. If the
+ <property>access</property> attribute contains <code>write</code>,
+ the script variable will be stored as a process variable after
+ evaluation. The <property>mapped-name</property> attribute can make
+ the process variable available under another name in the script.
+ Use this when the process variable names contain spaces or
+ other invalid characters.
</para>
</section>
<section id="customevents">
- <title>Custom events</title>
- <para>Note that it's possible to fire your own custom events at will during the
- execution of a process. Events are uniquely defined by the combination of a graph
- element (nodes, transitions, process definitions and superstates are graph elements)
- and an event-type (java.lang.String). jBPM defines a set of events that are fired for
- nodes, transitions and other graph elements. But as a user, you are free to fire your
- own events. In actions, in your own custom node implementations, or even outside the execution
- of a process instance, you can call the <literal>GraphElement.fireEvent(String eventType,
- ExecutionContext executionContext);</literal>. The names of the event types can
- be chosen freely.
+ <title>
+ Custom Events
+ </title>
+
+ <para>
+ Run custom events at will during the execution of a process by
+ calling the <methodname>GraphElement.fireEvent(String eventType,
+ ExecutionContext executionContext);</methodname> method. Choose
+ the names of the event types freely.
</para>
</section>
- </section>
+
<section id="superstates">
- <title>Superstates</title>
- <para>A Superstate is a group of nodes. Superstates can be nested recursively. Superstates
- can be used to bring some hierarchy in the process definition. For example, one application
- could be to group all the nodes of a process in phases. Actions can be associated with
- superstate events. A consequence is that a token can be in multiple nested nodes at a given
- time. This can be convenient to check wether a process execution is e.g. in the start-up phase.
- In the jBPM model, you are free to group any set of nodes in a superstate.
+ <title>
+ Super-States
+ </title>
+
+ <para>
+ A super-state is a group of nodes. They can be nested
+ recursively and are used to add a hierarchy to the process
+ definition. (For example, use this functionality
+ to group all of the nodes belonging to a process in phases.)
+ </para>
+ <para>
+ Actions can be associated with super-state events. A consequence
+ of this is that a token can be in multiple nested nodes at any
+ given time. This can be convenient when checking if a process
+ execution is in, for example, the start-up phase. One is free to
+ group any set of nodes into a super-state.
</para>
<section id="superstatetransitions">
- <title>Superstate transitions</title>
- <para>All transitions leaving a superstate can be taken by tokens in nodes contained within
- the super state. Transitions can also arrive in superstates. In that case, the token will be
- redirected to the first node in the superstate. Nodes from outside the superstate can have
- transitions directly to nodes inside the superstate. Also, the other way round, nodes within
- superstates can have transitions to nodes outside the superstate or to the superstate itself.
- Superstates also can have self references.</para>
+ <title>
+ Super-State Transitions
+ </title>
+
+ <para>
+ Any of the transitions leaving a super-state can be taken by
+ tokens in the nodes found within that same super state.
+ Transitions can also arrive in super-states, in which case the
+ token will be redirected to the first node in it.
+ Furthermore, nodes which are outside the super-state can have
+ transitions directly to nodes that are inside it
+ and vice versa. Finally, super-states can also be
+ self-referential.
+ </para>
</section>
<section id="superstateevents">
- <title>Superstate events</title>
- <para>There are 2 events unique to superstates: <literal>superstate-enter</literal> and
- <literal>superstate-leave</literal>. These events will be fired no matter over which
- transitions the node is entered or left respectively. As long as a token takes transitions
- within the superstate, these events are not fired.</para>
+ <title>
+ Super-State Events
+ </title>
+
+ <para>
+ Two events are unique to super-states, these being
+ <systemitem>superstate-enter</systemitem> and
+ <systemitem>superstate-leave</systemitem>. They will be
+ fired irrespective of which transitions the node has entered or
+ left. (As long as a token takes transitions within the
+ super-state, these events will not be fired.)
+ </para>
- <para>Note that we have created separate event types for states and superstates. This is
- to make it easy to distinct between superstate events and node events that are propagated
- from within the superstate.</para>
+ <note>
+ <para>
+ There are separate event types for states and super-states. The
+ software was designed this way in order to make it easy to distinguish
+ between actual super-state events and node events which have
+ been passed from within the super-state.
+ </para>
+ </note>
</section>
<section id="hierarchicalnames">
- <title>Hierarchical names</title>
- <para>Node names have to be unique in their scope. The scope of the node is its node-collection.
- Both the process definintion and the superstate are node collections. To refer to nodes in
- superstates, you have to specify the relative, slash (/) separated name. The slash separates
- the node names. Use '..' to refer to an upper level. The next example shows how to reference
- a node in a superstate:</para>
+ <title>
+ Hierarchical Names
+ </title>
+
+ <para>
+ Node names have to be unique (within their
+ <firstterm>scope</firstterm>.) The scope of the node is its
+ <firstterm>node-collection</firstterm>. (Both the process
+ definition and the super-state are node collections.) To refer
+ to nodes in super-states, specify the relative, slash
+ (<code>/</code>) separated name. (The slash separates the node
+ names. Use <code>.</code> to refer to an upper level.) The next
+ example shows how to refer to a node in a super-state:
+ </para>
<programlisting><process-definition>
...
@@ -501,7 +738,10 @@
...
</process-definition></programlisting>
- <para>The next example will show how to go up the superstate hierarchy</para>
+ <para>
+ The next example shows how to travel up the super-state
+ hierarchy:
+ </para>
<programlisting><process-definition>
...
@@ -520,45 +760,69 @@
</section>
<section id="exceptionhandling">
- <title>Exception handling</title>
- <para>The exception handling mechanism of jBPM only applies to java exceptions.
- Graph execution on itself cannot result in problems. It is only the execution
- of delegation classes that can lead to exceptions.
+ <title>
+ Exception Handling
+ </title>
+
+ <para>
+ The Business Process Manager's exception handling mechanism only
+ works for Java exceptions. Graph execution cannot, of itself,
+ result in problems. It is only when <firstterm>delegation
+ classes</firstterm> are executed that exceptions can occur.
</para>
- <para>On <literal>process-definition</literal>s, <literal>node</literal>s and
- <literal>transition</literal>s, a list of <literal>exception-handler</literal>s
- can be specified. Each <literal>exception-handler</literal> has a list of actions.
- When an exception occurs in a delegation class, the process
- element parent hierarchy is serached for an appropriate <literal>exception-handler</literal>.
- When it is found, the actions of the <literal>exception-handler</literal> are
- executed.
+ <para>
+ A list of <systemitem>exception-handler</systemitem>s can be
+ specified on <systemitem>process-definition</systemitem>s,
+ <systemitem>node</systemitem>s and
+ <systemitem>transition</systemitem>s. Each of these exception
+ handlers has a list of actions. When an exception occurs in a
+ delegation class, the process element's parent hierarchy is
+ searched for an appropriate
+ <systemitem>exception-handler</systemitem>, the actions for
+ which are executed.
</para>
-
- <para>Note that the exception handling mechanism of jBPM is not completely similar to
- the java exception handling. In java, a caught exception can have an influence on
- the control flow. In the case of jBPM, control flow cannot be changed by the
- jBPM exception handling mechanism. The exception is either caught or uncaught.
- Uncaught exceptions are thrown to the client (e.g. the client that called the
- <literal>token.signal()</literal>) or the exception is caught by a jBPM
- <literal>exception-handler</literal>. For caught exceptions, the graph execution
- continues as if no exception has occurred.</para>
-
- <para>Note that in an <literal>action</literal> that handles an exception, it
- is possible to put the token in an arbitrary node in the graph with
- <literal>Token.setNode(Node node)</literal>.
+
+ <important>
+ <para>
+ The Business Process Manager's exception handling differs in some
+ ways from the Java exception handling. In Java, a caught exception
+ can have an influence on the <firstterm>control flow</firstterm>. In
+ the case of jBPM, control flow cannot be changed by the exception
+ handling mechanism. The exception is either caught or it is not.
+ Exceptions which have not been caught are thrown to the client that
+ called the <methodname>token.signal()</methodname> method. For those
+ exceptions that are caught, the graph execution continues as if
+ nothing had occurred.
+ </para>
+</important>
+
+<note>
+ <para>
+ Use <methodname>Token.setNode(Node node)</methodname> to put the
+ token in an arbitrary node within the graph of an exception-handling
+ <systemitem>action</systemitem>.
</para>
+</note>
+
</section>
- <section id="processcomposition">
- <title>Process composition</title>
- <para>Process composition is supported in jBPM by means of the <literal>process-state</literal>.
- The process state is a state that is associated with another process definition. When graph
- execution arrives in the process state, a new process instance of the sub-process is created
- and it is associated with the path of execution that arrived in the process state. The
- path of execution of the super process will wait till the sub process instance has ended.
- When the sub process instance ends, the path of execution of the super process will leave
- the process state and continue graph execution in the super process.
+ <section id="modelling_processcomposition">
+ <title>
+ Process Composition
+ </title>
+
+ <para>
+ The Business Process Manager supports <firstterm>process
+ composition</firstterm> by means of the
+ <systemitem>process-state</systemitem>. This is a state that is
+ associated with another process definition. When graph execution
+ arrives in the <systemitem>process-state</systemitem>, a new
+ instance of the sub-process is created. This sub-process is then
+ associated with the path of execution that arrived in the process
+ state. The super-process' path of execution will wait until the
+ sub-process has ended and then leave the process state and continue
+ graph execution in the super-process.
</para>
<programlisting><process-definition name="hire">
@@ -574,41 +838,57 @@
...
</process-definition></programlisting>
- <para>This 'hire' process contains a <literal>process-state</literal>
- that spawns an 'interview' process.
- When execution arrives in the 'first interview', a new execution (=process instance) of
- the 'interview' process is created. If no explicit version is specified, the latest version
- of the sub process as known when deploying the 'hire' process is used. To make jBPM
- instantiate a specific version the optional <literal>version</literal> attribute can be
- specified. To postpone binding the specified or latest version until actually creating the
- sub process, the optional <literal>binding</literal> attribute should be set to
- <literal>late</literal>.
+ <para>
+ In the example above, the <literal>hire</literal> process contains a
+ <systemitem>process-state</systemitem> that spawns an
+ <literal>interview</literal> process. When execution arrives in the
+ <literal>first interview</literal>, a new execution (that is,
+ process instance) of the <literal>interview</literal> process is
+ created. If a version is not explicitly specified, the latest
+ version of the sub-process is used. To make the Business Process
+ Manager instantiate a specific version, specify the optional
+ <property>version</property> attribute. To postpone binding the
+ specified or latest version until the sub-process is actually
+ created, set the optional <property>binding</property> attribute to
+ <code>late</code>.
+ </para>
- Then variable 'a' from
- the hire process is copied into variable 'aa' from the interview process.
- The same way, hire variable 'b' is copied into interview variable 'bb'.
- When the interview process finishes, only variable 'aa' from the
- interview process is copied back into the 'a' variable of the
- hire process.</para>
+ <para>
+ Next, <literal>hire</literal> process variable <code>a</code> is
+ copied into <literal>interview</literal> process variable
+ <code>aa</code>. In the same way, <literal>hire</literal> variable
+ <code>b</code> is copied into interview variable <code>bb</code>. When the
+ interview process finishes, only variable <code>aa</code> is copied
+ back into the <code>a</code> variable.
+ </para>
- <para>In general, When a subprocess is started, all <literal>variable</literal>s with
- <literal>read</literal>
- access are read from the super process and fed into the newly created sub process before the signal
- is given to leave the start state. When the sub process instances is finished, all the
- <literal>variable</literal>s with <literal>write</literal> access will be copied from the sub
- process to the super process. The <literal>mapped-name</literal> attribute of the <literal>variable</literal>
- element allows you to specify the variable name that should be used in the sub process.</para>
+ <para>
+ In general, when a sub-process is started, all of the variables with
+ read access are read from the super-process and fed into the newly
+ created sub-process. This occurs before the signal is given to leave
+ the start state. When the sub-process instances are finished, all of
+ the variables with write access will be copied from the sub-process
+ to the super-process. Use the variable's
+ <property>mapped-name</property> attribute to specify the variable
+ name that should be used in the sub-process.
+ </para>
+
</section>
<section id="customnodebehaviour">
- <title>Custom node behaviour</title>
- <para>In jBPM, it's quite easy to write your own custom nodes. For creating custom nodes, an
- implementation of the ActionHandler has to be written. The implementation can execute any
- business logic, but also has the responsibility to propagate the graph execution. Let's look
- at an example that will update an ERP-system. We'll read an amout from the ERP-system, add
- an amount that is stored in the process variables and store the result back in the ERP-system.
- Based on the size of the amount, we have to leave the node via the 'small amounts' or the
- 'large amounts' transition.
+ <title>
+ Custom Node Behavior
+ </title>
+
+ <para>
+ Create custom nodes by using a special implementation of the
+ <classname>ActionHandler</classname> that can execute any business
+ logic, but also has the responsibility to pass on the graph
+ execution. Here is an example that reads a value from an ERP system,
+ adds an amount (from the process variables) and stores the result
+ back in the ERP system. Based on the size of the amount, use either the
+ <systemitem>small amounts</systemitem> or the <systemitem>large
+ amounts</systemitem> transition to exit.
</para>
<figure id="update.erp.example.image">
@@ -633,127 +913,214 @@
}
}</programlisting>
- <para>It is also possible to create and join tokens in custom node
- implementations. For an example on how to do this, check out the Fork and
- Join node implementation in the jbpm source code :-).</para>
-
+ <note>
+ <para>
+ One can also create and join tokens in custom node implementations.
+ To learn how to do this, study the Fork and Join node implementation
+ in the jBPM source code.
+ </para>
+</note>
</section>
<section id="graphexecution">
- <title>Graph execution</title>
- <para>The graph execution model of jBPM is based on interpretation of the
- process definition and the chain of command pattern.</para>
+ <title>
+ Graph Execution
+ </title>
+
+ <para>
+ The Business Process Manager's graph execution model is based on an
+ interpretation of the process definition and the "chain of command"
+ pattern.
+ </para>
- <para>Interpretation of the process definition means that the process
- definition data is stored in the database. At runtime the process definition
- information is used during process execution. Note for the concerned :
- we use hibernate's second level cache to avoid loading of definition information
- at runtime. Since the process definitions don't change (see process versioning)
- hibernate can cache the process definitions in memory.</para>
+ <para>
+ The process definition data is stored in the database and is
+ used during process execution.
+ </para>
+
+ <note>
+ <para>
+ Be aware that <application>Hibernate</application>'s second
+ level cache is used so as to avoid loading definition
+ information at run-time. Since the process definitions do not
+ change, <application>Hibernate</application> can cache them in
+ memory.
+ </para>
+ </note>
+
+ <para>
+ The "chain of command pattern" makes each node in the graph
+ responsible for passing on the process execution. If a node does not
+ pass it on, it behaves as though it were a <systemitem>wait
+ state</systemitem>.
+ </para>
- <para>The chain of command pattern means that each node in the graph is
- responsible for propagating the process execution. If a node does not
- propagate execution, it behaves as a wait state.</para>
+ <para>
+ Let the execution start on process instances and it will continue
+ until it enters a <systemitem>wait state</systemitem>.
+ </para>
- <para>The idea is to start execution on process instances and that the execution
- continues till it enters a wait state.</para>
+ <para>
+ A token represents a path of execution. It has a pointer to a
+ node in the process graph. During <systemitem>wait
+ state</systemitem>, the tokens can be made to persist in the
+ database.
+ </para>
- <para>A token represents a path of execution. A token has a pointer to a node
- in the process graph. During waitstates, the tokens can be persisted
- in the database. Now we are going to look at the algorithm for calculating the
- execution of a token. Execution starts when a signal is sent to a token.
- The execution is then passed over the transitions and nodes via the chain of
- command pattern. These are the relevant methods in a class diagram.</para>
+ <para>
+ This algorithm is used to calculate the execution of a token.
+ Execution starts when a signal is sent to the tokenand it is then
+ passed over the transitions and nodes via the chain of command
+ pattern. These are the relevant methods:
+ </para>
<figure id="graph.execution.image">
<title>The graph execution related methods</title>
<mediaobject><imageobject><imagedata align="center" fileref="images/graph.execution.gif"/></imageobject></mediaobject>
</figure>
- <para>When a token is in a node, signals can be sent to the token. Sending a
- signal is an instruction to start execution. A signal must therefore specify
- a leaving transition of the token's current node. The first transition is the
- default. In a signal to a token, the token takes its current node
- and calls the <literal>Node.leave(ExecutionContext,Transition)</literal> method. Think
- of the ExecutionContext as a Token because the main object in an ExecutionContext
- is a Token. The <literal>Node.leave(ExecutionContext,Transition)</literal> method will
- fire the <literal>node-leave</literal> event and call the
- <literal>Transition.take(ExecutionContext)</literal>. That method will fire
- the <literal>transition</literal> event and call the
- <literal>Node.enter(ExecutionContext)</literal> on the destination node of the
- transition. That method will fire the <literal>node-enter</literal> event and
- call the <literal>Node.execute(ExecutionContext)</literal>. Each type of node
- has its own behaviour that is implementated in the execute method. Each node
- is responsible for propagating graph execution by calling the
- <literal>Node.leave(ExecutionContext,Transition)</literal> again. In summary:</para>
+ <para>
+ When a token is in a node, signals can be sent to it. A
+ signal is treated as an instruction to start execution and must,
+ therefore, specify a <systemitem>leaving transition</systemitem>
+ from the token's current
+ node. The first transition is the default. In a signal to a
+ token, it takes its current node and calls the
+ <methodname>Node.leave(ExecutionContext,Transition)</methodname>
+ method. (It is best to think of the <methodname>ExecutionContext</methodname> as a token because the
+ main object in it is a token.) The
+ <methodname>Node.leave(ExecutionContext,Transition)</methodname>
+ method will fire the <systemitem>node-leave</systemitem> event and
+ call the <methodname>Transition.take(ExecutionContext)</methodname>.
+ That method will then run the transition event
+ and call the <methodname>Node.enter(ExecutionContext)</methodname> on
+ the transition's destination node. That method will then fire
+ the <systemitem>node-enter</systemitem> event and call the
+ <methodname>Node.execute(ExecutionContext)</methodname>.
+ </para>
+ <para>
+ Every type of node has its own behaviour, these being
+ implemented via the <methodname>execute</methodname> method.
+ Each node is responsible for passing on the graph execution by
+ calling the
+ <methodname>Node.leave(ExecutionContext,Transition)</methodname>
+ again. In summary:
+ </para>
+
<itemizedlist>
- <listitem><para>Token.signal(Transition)</para></listitem>
- <listitem><para>--> Node.leave(ExecutionContext,Transition)</para></listitem>
- <listitem><para>--> Transition.take(ExecutionContext)</para></listitem>
- <listitem><para>--> Node.enter(ExecutionContext)</para></listitem>
- <listitem><para>--> Node.execute(ExecutionContext)</para></listitem>
+ <listitem><para><methodname>Token.signal(Transition)</methodname></para></listitem>
+ <listitem><para><methodname>Node.leave(ExecutionContext,Transition)</methodname></para></listitem>
+ <listitem><para><methodname>Transition.take(ExecutionContext)</methodname></para></listitem>
+ <listitem><para><methodname>Node.enter(ExecutionContext)</methodname></para></listitem>
+ <listitem><para><methodname>Node.execute(ExecutionContext)</methodname></para></listitem>
</itemizedlist>
- <para>Note that the complete calculation of the next state, including the invocation
- of the actions is done in the thread of the client. A common misconception is that
- all calculations *must* be done in the thread of the client. As with any asynchronous
- invocation, you can use asynchronous messaging (JMS) for that. When the message is
- sent in the same transaction as the process instance update, all synchronization issues
- are taken care of. Some workflow systems use asynchronous messaging between all nodes
- in the graph. But in high throughput environments, this algorithm gives much more control
- and flexibility for tweaking performance of a business process.</para>
+<note>
+ <para>
+ The next state, including the invocation of the actions, is
+ calculated via the client's thread. A common misconception is that
+ all calculations must be undertaken in this way. Rather, as is the
+ case with any <firstterm>asynchronous invocation</firstterm>, one
+ can use <firstterm>asynchronous messaging</firstterm> (via Java
+ Message Service) for that. When the message is sent in the same
+ transaction as the process instance update, all synchronization
+ issues are handled correctly. Some workflow systems use asynchronous
+ messaging between all nodes in the graph but, in high throughput
+ environments, this algorithm gives much more control and flexibility
+ to those wishing to maximise business process performance.
+ </para>
+</note>
+
</section>
<section id="transactiondemarcation">
- <title>Transaction demarcation</title>
- <para>As explained in <xref linkend="graphexecution" />, jBPM runs the process in the thread of
- the client and is by nature synchronous. Meaning that the <literal>token.signal()</literal>
- or <literal>taskInstance.end()</literal> will only return when the process has entered a new
- wait state.
+ <title>
+ Transaction Demarcation
+ </title>
+
+ <para>
+ As explained in <xref linkend="graphexecution" />, the Business
+ Process Manager runs the process in the thread of the client and
+ is, by nature, synchronous. In practice, this means that the
+ <methodname>token.signal()</methodname> or
+ <methodname>taskInstance.end()</methodname> will only return
+ when the process has entered a new <systemitem>wait
+ state</systemitem>.
+ </para>
+
+<note>
+ <para>
+ To learn more about the jPDL feature being described in this
+ section, read <xref linkend="asynchronouscontinuations" />.
</para>
- <para>The jPDL feature that we describe here from a modelling perspective is
- <xref linkend="asynchronouscontinuations" />.
+</note>
+
+ <para>
+ In most situations this is the most straightforward approach because
+ one can easily bind the the process execution to server-side
+ transactions: the process moves from one state to the next in the space of one
+ transaction.
</para>
- <para>In most situations this is the most straightforward approach because the process
- execution can easily be bound to server side transactions: the process moves from one
- state to the next in one transaction.
+
+ <para>
+ Sometimes, in-process calculations take a lot of time, so this
+ behavior might be undesirable. To cope with this issue, the Business
+ Process Manager includes an asynchronous messaging system that
+ allows it to continue a process in a manner, which is, as the name
+ implies, asynchronous. (Of course, in a Java enterprise environment,
+ jBPM can be configured to use a Java Message Service broker instead
+ of the in-built messaging system.)
</para>
- <para>In some scenarios where in-process calculations take a lot of time, this behaviour
- might be undesirable. To cope with this, jBPM includes an asynchronous messaging system
- that allows to continue a process in an asynchronous manner. Of course, in a java enterprise
- environment, jBPM can be configured to use a JMS message broker instead of the built in
- messaging system.
+
+ <para>
+ jPDL supports the <code>async="true"</code> attribute in
+ every node. Asynchronous nodes will not be executed in the thread of
+ the client. Instead, a message is sent over the asynchronous
+ messaging system and the thread is returned to the client (in other
+ words, <methodname>token.signal()</methodname> or
+ <methodname>taskInstance.end()</methodname> will be returned.)
</para>
- <para>In any node, jPDL supports the attribute <literal>async="true"</literal>.
- Asynchronous nodes will not be executed in the thread of the client. Instead, a message is
- sent over the asynschronous messaging system and the thread is returned to the client
- (meaning that the <literal>token.signal()</literal> or <literal>taskInstance.end()</literal>
- will return).
+ <para>
+ The Business Process Manager's client code can now commit the
+ transaction. Send messages in the same transaction as that
+ containing the process updates. (The overall result of such a
+ transaction will be that the token is moved to the next node (which
+ has not yet been executed) and a
+ <classname>org.jbpm.command.ExecuteNodeCommand</classname> message
+ will be sent from the asynchronous messaging system to the
+ <systemitem>jBPM Command Executor</systemitem>. This reads the
+ commands from the queue and executes them. In the case of the
+ <classname>org.jbpm.command.ExecuteNodeCommand</classname>, the
+ process will be continued when the node is executed. (Each command
+ is executed in a separate transaction.)
</para>
- <para>Note that the jbpm client code can now commit the transaction. The sending of the
- message should be done in the same transaction as the process updates. So the net result of
- the transaction is that the token has moved to the next node (which has not yet been executed)
- and a <literal>org.jbpm.command.ExecuteNodeCommand</literal>-message has been sent on the
- asynchronous messaging system to the jBPM Command Executor.
+
+<important>
+ <para>
+ Ensure that a <systemitem>jBPM Command Executor</systemitem> is
+ running so that asynchronous processes can continue. Do so by
+ configuring the web application's
+ <classname>CommandExecutionServlet</classname>.
</para>
- <para>The jBPM Command Executor reads commands from the queue and executes them. In the case
- of the <literal>org.jbpm.command.ExecuteNodeCommand</literal>, the process will be continued
- with executing the node. Each command is executed in a separate transaction.
+</important>
+
+
+ <note>
+ <para>
+ Process modelers do not need to be excessively concerned with
+ asynchronous messaging. The main point to remember is transaction
+ demarcation: by default, the Business Process Manager will operate
+ in the client transaction, undertaking the whole calculation until
+ the process enters a <systemitem>wait state</systemitem>. (Use
+ <code>async="true"</code> to demarcate a transaction in
+ the process.)
</para>
- <para>So in order for asynchronous processes to continue, a jBPM Command Executor needs to
- be running. The simplest way to do that is to configure the <literal>CommandExecutionServlet</literal>
- in your web application. Alternatively, you should make sure that the CommandExecutor thread is
- up and running in any other way.
+</note>
+
+ <para>
+ Here is an example:
</para>
- <para>As a process modeller, you should not really be concerned with all this asynchronous
- messaging. The main point to remember is transaction demarcation: By default jBPM will operate
- in the transaction of the client, doing the whole calculation until the process enters a wait
- state. Use <literal>async="true"</literal> to demarcate a transaction in the process.
- </para>
-
- <para>Let's look at an example:
- </para>
<programlisting>...
<start-state>
<transition to="one" />
@@ -772,9 +1139,12 @@
</node>
<end-state name="end" />
...</programlisting>
- <para>Client code to interact with process executions (starting and
- resuming) is exactly the same as with normal (synchronous) processes:
+
+ <para>
+ The client code needed to both start and resume process executions
+ is exactly the same as that needed for normal synchronous processes.
</para>
+
<programlisting>...start a transaction...
JbpmContext jbpmContext = jbpmConfiguration.createContext();
try {
@@ -784,18 +1154,24 @@
} finally {
jbpmContext.close();
}</programlisting>
- <para>After this first transaction, the root token of the process instance
- will point to node <literal>one</literal> and a
- <literal>ExecuteNodeCommand</literal>message will have been sent to the
- command executor.
+
+<para>
+ After this first transaction occurs, the process execution's
+ <systemitem>root token</systemitem> will point to <literal>node
+ one</literal> and an <classname>ExecuteNodeCommand</classname>
+ message is sent to the command executor.
</para>
- <para>In a subsequent transaction, the command executor will read the message
- from the queue and execute node <literal>one</literal>. The action can decide to
- propagate the execution or enter a wait state. If the action decides to propagate
- the execution, the transaction will be ended when the execution arrives at
- node two. And so on, and so on...
+
+ <para>
+ In a subsequent transaction, the command executor will read the
+ message from the queue and execute <literal>node one</literal>. The
+ action can decide to pass the execution on or enter a
+ <systemitem>wait state</systemitem>. If it chooses to pass it on,
+ the transaction will be ended when the execution arrives at
+ <literal>node two</literal>.
</para>
+
</section>
</chapter>
Modified: jbpm3/branches/jbpm-3.2-soa/modules/userguide/src/main/docbook/en-US/persistence.xml
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/userguide/src/main/docbook/en-US/persistence.xml 2010-06-22 17:57:45 UTC (rev 6429)
+++ jbpm3/branches/jbpm-3.2-soa/modules/userguide/src/main/docbook/en-US/persistence.xml 2010-06-22 22:03:45 UTC (rev 6430)
@@ -4,20 +4,29 @@
%BOOK_ENTITIES;
]>
<chapter id="persistence">
- <title>Persistence</title>
-
- <para>In most scenarios, jBPM is used to maintain execution of processes that
- span a long time. In this context, "a long time" means spanning several
- transactions. The main purpose of persistence is to store process executions
- during wait states. So think of the process executions as state machines.
- In one transaction, we want to move the process execution state machine from
- one state to the next.
+ <title>
+ Persistence
+ </title>
+ <para>
+ This chapter provides the reader with detailed insight into the
+ Business Process Manager's "persistence" functionality.
+ </para>
+
+ <para>
+ Most of the time, the jBPM is used to execute processes that span
+ several transactions. The main purpose of the
+ <firstterm>persistence</firstterm> functionality is to store process
+ executions when <firstterm>wait states</firstterm> occur. It is helpful
+ to think of the process executions as <firstterm>state
+ machines</firstterm>. The intention is to move the process execution
+ state machine from one state to the next within a single transaction.
</para>
- <para>A process definition can be represented in 3 different forms : as xml, as
- java objects and as records in the jBPM database. Executional (=runtime)
- information and logging information can be represented in 2 forms : as
- java objects and as records in the jBPM database.
+ <para>
+ A process definition can be represented in any of three different forms,
+ namely XML, Java object or a jBPM database record. (Run-time data and
+ log information can also be represented in either of
+ the latter two formats.)
</para>
<figure id="model.transformations.image">
@@ -25,21 +34,34 @@
<mediaobject><imageobject><imagedata align="center" fileref="images/model.transformations.jpg"/></imageobject></mediaobject>
</figure>
- <para>For more information about the xml representation of process definitions
- and process archives, see JPDL.</para>
+ <note>
+ <para>
+ To learn more about XML representations of process definitions
+ and process archives, see <xref linkend="jpdl" />.
+ </para>
+ </note>
<!--
<para>More information on how to deploy a process archive to the database
can be found in <xref linkend="deployingaprocessarchive" /> </para> -->
- <section>
- <title>The persistence API</title>
+ <section id="sect-persistance_API">
+ <title>
+ The Persistence Application Programming Interface
+ </title>
- <section id="relationtotheconfigurationframework"><title>Relation to the configuration framework</title>
+ <section id="relationtotheconfigurationframework">
+ <title>
+ Relationship with the Configuration Framework
+ </title>
- <para>The persistence API is an integrated with the
- configuration framework (<xref linkend="configuration"/>) by exposing some convenience persistence methods
- on the JbpmContext. Persistence API operations can therefore be
- called inside a jBPM context block like this:
+ <para>
+ The persistence application programming interface is integrated with
+ the configuration framework, (see <xref linkend="configuration"/>.)
+ This has been achieved by the exposure of some of the
+ <methodname>convenience persistence</methodname> methods on the
+ <interfacename>JbpmContext</interfacename>, allowing the jBPM
+ <systemitem>context block</systemitem> to call persistence API
+ operations.
</para>
<programlisting>JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
@@ -65,19 +87,25 @@
</section>
<section id="conveniencemethodsonjbpmcontext">
- <title>Convenience methods on JbpmContext</title>
+ <title>
+ Convenience Methods on JbpmContext
+ </title>
- <para>The three most common persistence operations are:</para>
- <itemizedlist>
- <listitem><para>Deploying a process</para></listitem>
- <listitem><para>Starting a new execution of a process</para></listitem>
- <listitem><para>Continuing an execution</para></listitem>
- </itemizedlist>
+ <para>The three most commonly-performed persistence operations are:</para>
+ <orderedlist>
+ <listitem><para>process. deployment</para></listitem>
+ <listitem><para>new process execution commencement</para></listitem>
+ <listitem><para>process execution continuation</para></listitem>
+ </orderedlist>
+
- <para>First deploying a process definition. Typically, this will be done directly
- from the graphical process designer or from the deployprocess ant task. But here
- you can see how this is done programmatically:
+
+ <para>
+ <firstterm>Process deployment</firstterm> is normally undertaken directly from the
+ <application>Graphical Process Designer</application> or from the
+ <filename>deployprocess</filename> <application>ant</application>
+ task. However, to do it directly from Java, use this code:
</para>
<programlisting>JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
@@ -88,10 +116,12 @@
jbpmContext.close();
}</programlisting>
- <para>For the creation of a new process execution, we need to specify of which process
- definition this execution will be an instance. The most common way to specify this
- is to refer to the name of the process and let jBPM find the latest version of that
- process in the database:
+ <para>
+ Create a new process execution by specifying the process
+ definition of which it will be an instance. The most common way to
+ do this is by referring to the name of the process. The jBPM will then
+ find the latest version of that process in the database. Here is
+ some demonstration code:
</para>
<programlisting>JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
@@ -103,12 +133,15 @@
jbpmContext.close();
}</programlisting>
- <para>For continuing a process execution, we need to fetch the process instance, the
- token or the taskInstance from the database, invoke some methods on the POJO jBPM
- objects and afterwards save the updates made to the processInstance into the database
- again.
+ <para>
+ To continue a process execution, fetch the process instance, the
+ token or the <classname>taskInstance</classname> from the database
+ and invoke some methods on the POJO (<firstterm>Plain Old Java
+ Object</firstterm>) jBPM objects. Afterwards, save the updates made
+ to the <classname>processInstance</classname> into the database.
</para>
+
<programlisting>JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
try {
long processInstanceId = ...;
@@ -120,13 +153,19 @@
jbpmContext.close();
}</programlisting>
- <para>Note that if you use the xxx<emphasis role="bold">ForUpdate</emphasis> methods in
- the JbpmContext, an explicit invocation of the jbpmContext.save is not necessary any
- more because it will then occur automatically during the close of the jbpmContext.
- E.g. suppose we want to inform jBPM about a taskInstance that has been completed.
- Note that task instance completion can trigger execution to continue so the
- processInstance related to the taskInstance must be saved. The most convenient way
- to do this is to use the loadTaskInstanceForUpdate method:
+ <para>
+ Note that it is not necessary to explicitly invoke the
+ <methodname>jbpmContext.save</methodname> method if the
+ <methodname>ForUpdate</methodname> methods are used in the
+ <classname>JbpmContext</classname> class. This is because the save
+ process will run automatically when the
+ <classname>jbpmContext</classname> class is closed. For example, one
+ may wish to inform the jBPM that a
+ <classname>taskInstance</classname> has completed. This can cause an
+ execution to continue, so the <classname>processInstance</classname>
+ related to the <classname>taskInstance</classname> must be saved. The
+ most convenient way to do this is by using the
+ <methodname>loadTaskInstanceForUpdate</methodname> method:
</para>
<programlisting>JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
@@ -139,29 +178,51 @@
jbpmContext.close();
}</programlisting>
- <para>Just as background information, the next part is an explanation of how jBPM manages
- the persistence through Hibernate.
+ <important>
+ <para>
+ Read the following explanation to learn how the jBPM manages
+ the persistence feature and uses
+ <application>Hibernate</application>'s functionality.
</para>
- <para>The <literal>JbpmConfiguration</literal> maintains a list of
- <literal>ServiceFactory</literal> instances. The service factories are configured in
- <literal>jbpm.cfg.xml</literal> and instantiated as needed.
- The <literal>DbPersistenceServiceFactory</literal> manages a Hibernate
- <literal>SessionFactory</literal>. The session factory is built on demand as well,
- since not every operation in <literal>DbPersistenceServiceFactory</literal> requires it.
+ <para>
+ The <classname>JbpmConfiguration</classname> maintains a set of
+ <methodname>ServiceFactories</methodname>. They are configured via
+ the <filename>jbpm.cfg.xml</filename> file and instantiated as they
+ are needed.
+ </para>
+ <para>
+ The <classname>DbPersistenceServiceFactory</classname>
+ is only instantiated the first time that it is needed. After that,
+ <methodname>ServiceFactory</methodname>s are maintained in the
+ <classname>JbpmConfiguration</classname>.
+ </para>
+ <para>
+ A <classname>DbPersistenceServiceFactory</classname> manages a
+ <application>Hibernate</application>
+ <methodname>ServiceFactory</methodname> but this is only
+ instantiated the first time that it is requested.
</para>
+</important>
<figure id="persistence.api.image">
<title>Classes related to persistence</title>
<mediaobject><imageobject><imagedata align="center" fileref="images/persistence.api.gif"/></imageobject></mediaobject>
</figure>
- <para>During the invocation of <literal>jbpmConfiguration.createJbpmContext()</literal>,
- only the <literal>JbpmContext</literal> is created. No further persistence related
- initializations are done at that time. The <literal>JbpmContext</literal> maintains
- a sequence of <literal>Service</literal> instances, created as needed.
- The <literal>DbPersistenceService</literal> wraps a Hibernate session
- which is opened when the first persistence operation is performed.
+ <para>
+ When the
+ <classname>jbpmConfiguration.createJbpmContext()</classname> class
+ is invoked, only the <classname>JbpmContext</classname> is created.
+ No further persistence-related initializations occur at this time.
+ The <classname>JbpmContext</classname> manages a
+ <classname>DbPersistenceService</classname> class, which is
+ instantiated when it is first requested. The
+ <classname>DbPersistenceService</classname> class manages the
+ <application>Hibernate</application> session, which is also only
+ instantiated the first time it is required. (In other words, a
+ <application>Hibernate</application> session will only be opened
+ when the first operation that requires persistence is invoked.)
</para>
</section><section id="managedtransactions"><title>Managed transactions</title>
@@ -283,8 +344,9 @@
</section>
<section id="configurationthepersistenceservice">
- <title>Configuring the persistence service</title>
-
+ <title>
+ Configuring the Persistence Service
+ </title>
<section id="thedbpersistenceservicefactory">
<title>The DbPersistenceServiceFactory</title>
@@ -507,60 +569,97 @@
</section>
<section id="databasecompatibility">
- <title>Database compatibility</title>
+ <title>
+ Database Compatibility
+ </title>
- <para>jBPM runs on any database that is supported by hibernate.
+ <para>
+ The jBPM runs on any database that is supported by
+ <application>Hibernate</application>.
</para>
- <para>The example configuration files in jBPM (<literal>src/config.files</literal>) specify
- the use of the hypersonic in-memory database. That database is ideal during development and
- for testing. The hypersonic in-memory database keeps all its data in memory and doesn't
- store it on disk.
+ <para>
+ The example configuration file,
+ <filename>src/config.files</filename>, specifies the use of the
+ <application>Hypersonic</application> in-memory database, which is
+ ideal for development and testing purposes.
+ (<application>Hypersonic</application> retains all data in memory
+ and does not store anything on disk.)
</para>
- <section id="jdbcconnectionisolation">
- <title>Isolation level of the JDBC connection</title>
- <para>Make sure that the database isolation level that you configure for your
- JDBC connection is at least READ_COMMITTED.
+ <section id="isolationlevelofthejdbcconnection">
+ <title>
+ Isolation Level of the JDBC Connection
+ </title>
+
+ <para>
+ Set the database isolation level for the JDBC connection to at
+ least <code>READ_COMMITTED</code>.
</para>
- <para>Almost all features run OK even with READ_UNCOMMITTED (isolation level 0
- and the only isolation level supported by HSQLDB). But race conditions might occur in the
- job executor and with synchronizing multiple tokens.
+
+<warning>
+ <para>
+ If it is set to <code>READ_UNCOMMITTED</code>, (isolation level
+ zero, the only isolation level supported by
+ <application>Hypersonic</application>), race conditions might occur
+ in the <systemitem>job executor</systemitem> .These might also
+ appear when synchronization of multiple tokens is occurring.
</para>
+</warning>
+
</section>
<section id="changingthejbpmdb">
- <title>Changing the jBPM DB</title>
- <para>Following is an indicative list of things to do when changing jBPM to
- use a different database:
+ <title>
+ Changing the Database
+ </title>
+
+
+ <para>
+ In order to reconfigure Business Process Manger to use a
+ different database, follow these steps:
</para>
<itemizedlist>
- <listitem><para>put the jdbc-driver library archive in the classpath</para>
+ <listitem><para>put the JDBC driver library archive in the classpath.</para>
</listitem>
- <listitem><para>update the hibernate configuration used by jBPM</para>
+ <listitem><para>update the <application>Hibernate</application> configuration used by jBPM.</para>
</listitem>
- <listitem><para>create the schema in the new database</para>
+ <listitem><para>create a schema in the new database.</para>
</listitem>
</itemizedlist>
</section>
- <section id="jbpmdbschema">
- <title>The jBPM database schema</title>
- <para>The <literal>database</literal> and <literal>config</literal> directories
- in the distribution contain scripts and Hibernate configuration files
- to help you get started on your choice database.
+ <section id="thejbpmdbschema">
+ <title>
+ The Database Schema
+ </title>
+
+ <para>
+ The <systemitem>jbpm.db</systemitem> sub-project contains drivers,
+ instructions and scripts to help the user to start using the
+ database of his or her choice. Refer to the
+ <filename>readme.html</filename> (found in the root of the
+ <systemitem>jbpm.db</systemitem> project) for more information.
</para>
- <para>While jBPM is capable of generating DDL scripts for any database
- supported by Hibernate, the resulting
- schemas are not always optimized. You might want to have your DBA review
- the DDL that is generated to optimize the column types and use of indexes.
+
+ <note>
+ <para>
+ Whilst the jBPM is capable of generating DDL scripts for any
+ database, these schemas are not always optimized. Consider
+ asking your corporation's Database Adminstrator to review the
+ generated DDL, so that he or she can optimize the column types
+ and indexes.
</para>
- <para>In development you might be interested in the following hibernate configuration:
- If you set hibernate configuration property <literal>hibernate.hbm2ddl.auto</literal>
- to <literal>create-drop</literal> in the Hibernate configuration file,
- the database schema will be automatically created
- the first time the application accesses the database. When the application closes
- down, the schema will be dropped.
+ </note>
+
+ <para>
+ The following <application>Hibernate</application> configuration
+ option may be of use in a development environment: set
+ <property>hibernate.hbm2ddl.auto</property> to
+ <code>create-drop</code> and the schema will be created
+ automatically the first time the database is used in an
+ application. When the application closes down, the schema will
+ be dropped.
</para>
<section id="programmaticdbschema">
<title>Programmatic database schema operations</title>
@@ -657,30 +756,34 @@
</section>
<section>
- <title>Combining your hibernate classes</title>
+ <title>
+ Combining Hibernate Classes
+ </title>
- <para>In your project, you might use hibernate for your persistence. Combining your
- persistent classes with the jBPM persistent classes is optional. There are two major
- benefits when combining your hibernate persistence with jBPM's hibernate persistence:
+ <para>
+ Combining <application>Hibernate</application> and jBPM
+ persistent classes brings about two major
+ benefits. Firstly, session, connection and transaction
+ management become easier because, by combining them into one
+ <application>Hibernate</application> session factory, there will
+ be only one <application>Hibernate</application> session and one
+ JDBC connection. Hence, the jBPM updates will be in the same
+ transaction as the updates for the domain model. This
+ eliminates the need for a transaction manager.
</para>
- <para>First, session, connection and transaction management become easier. By combining
- jBPM and your persistence into one hibernate session factory,
- there is one hibernate session, one jdbc connection that handles both yours and
- jBPM's persistence. So automatically the jBPM updates are in the same transaction
- as the updates to your own domain model. This can eliminates the need for using
- a transaction manager.
+ <para>
+ Secondly, it enables one to drop one's
+ <application>Hibernate</application> persistence object into the
+ process variables without any additional work.
</para>
-
- <para>Secondly, this enable you to drop your hibernatable persistent object in to the
- process variables without any further hassle.
- </para>
- <para>The easiest way
- to integrate your persistent classes with the jBPM persistent classes is by
- creating one central hibernate.cfg.xml. You can take the jBPM
- <literal>hibernate.cfg.xml</literal> as a starting point and
- add references to your own hibernate mapping files in there.
+ <para>
+ To make this occur, create one central
+ <filename>hibernate.cfg.xml</filename> file. It is easiest to use
+ the default jBPM <filename>hibernate.cfg.xml</filename> as a
+ starting point and add references to one's own
+ <application>Hibernate</application> mapping files to customize it.
</para>
</section>
@@ -725,6 +828,13 @@
execution. But in that case, deploying new process definitions would not be
possible as that operation is not read-only.
</para>
+ <para>
+ Having read this chapter, you have learned a great deal of theoretical
+ information and practical advice relating to the topic of persistence in
+ jBPM, including how to utilize <application>Hibernate</application> to
+ its fullest potential.
+</para>
+
</section>
</chapter>
Modified: jbpm3/branches/jbpm-3.2-soa/modules/userguide/src/main/docbook/en-US/scheduler.xml
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/userguide/src/main/docbook/en-US/scheduler.xml 2010-06-22 17:57:45 UTC (rev 6429)
+++ jbpm3/branches/jbpm-3.2-soa/modules/userguide/src/main/docbook/en-US/scheduler.xml 2010-06-22 22:03:45 UTC (rev 6430)
@@ -4,17 +4,29 @@
%BOOK_ENTITIES;
]>
<chapter id="scheduler">
- <title>Scheduler</title>
- <para>This chapter describes how to work with timers in jBPM.</para>
+ <title>
+ Scheduler
+ </title>
- <para>Upon events in the process, timers can be created. When a timer
- expires, an action can be executed or a transition can be taken.</para>
+ <para>
+ Read this chapter to learn about the role of
+ <firstterm>timers</firstterm> in the
+ Business Process Manager.
+ </para>
+ <para>
+ Timers can be created upon events in the process. Set them to
+ trigger either action executions or event transitions.
+ </para>
<section id="timers">
- <title>Timers</title>
+ <title>
+ Timers
+ </title>
- <para>The easiest way to specify a timer is by adding a timer element
- to the node.</para>
+ <para>
+ The easiest way to set a timer is by adding a <firstterm>timer
+ element</firstterm> to the node. This sample code shows how to do so:
+ </para>
<programlisting><state name='catch crooks'>
<timer name='reminder'
@@ -26,44 +38,62 @@
<transition name='time-out-transition' to='...' />
</state></programlisting>
- <para>A timer that is specified on a node, is not executed after the node
- is left. Both the transition and the action are optional. When a timer
- is executed, the following events occur in sequence : </para>
+ <para>
+ A timer specified on a node is not executed after that node
+ is exited. Both the transition and the action are optional. When a timer
+ is executed, the following events occur in sequence:
+ </para>
- <itemizedlist>
- <listitem><para>an event is fired of type <literal>timer</literal></para></listitem>
- <listitem><para>if an action is specified, the action is executed.</para></listitem>
- <listitem><para>if a transition is specified, a signal will be sent to resume execution
- over the given transition.</para></listitem>
- </itemizedlist>
+ <orderedlist>
+ <listitem><para>an event of type <systemitem>timer</systemitem> is fired.</para></listitem>
+ <listitem><para>if an action is specified, it executes.</para></listitem>
+ <listitem><para>a signal is to resume execution
+ over any specified transition.</para></listitem>
+ </orderedlist>
- <para>Every timer must have a unique name. If no name is specified in the
- <literal>timer</literal> element, the name of the node is taken as the name
- of the timer.</para>
-
- <para>The timer action can be any supported action element like e.g.
- <literal>action</literal> or <literal>script</literal>.</para>
+ <para>
+ Every timer must have a unique name. If no name is specified
+ in the <systemitem>timer</systemitem> element, the name of
+ the node is used by default.
+ </para>
- <para>Timers are created and cancelled by actions. The 2 action-elements are
- <literal>create-timer</literal> and <literal>cancel-timer</literal>. Actually, the
- timer element shown above is just a short notation for a create-timer action
- on <literal>node-enter</literal> and a cancel-timer action on
- <literal>node-leave</literal>.</para>
+ <para>
+ Use the timer action to support any action element (such as
+ <systemitem>action</systemitem> or
+ <systemitem>script</systemitem>.)
+ </para>
+
+ <para>
+ Timers are created and canceled by actions. The two pertinent
+ <systemitem>action-elements</systemitem> are
+ <systemitem>create-timer</systemitem> and
+ <systemitem>cancel-timer</systemitem>. In actual fact, the timer
+ element shown above is just short-hand notation for a
+ <systemitem>create-timer</systemitem> action on
+ <systemitem>node-enter</systemitem> and a
+ <systemitem>cancel-timer</systemitem> action on
+ <systemitem>node-leave</systemitem>.
+ </para>
</section>
<section id="schedulerdeployment">
- <title>Scheduler deployment</title>
+ <title>
+ Scheduler Deployment
+ </title>
- <para>Process executions create and cancel timers. The timers are stored in
- a timer store. A separate timer runner must check the timer store and execute
- the timers when they are due.</para>
+ <para>
+ Process executions create and cancel timers, storing them in a
+ <firstterm>timer store</firstterm>. A separate <systemitem>timer
+ runner</systemitem> checks this store and execute each timers at the
+ due moment.
+ </para>
<figure id="scheduler.overview.image">
<title>Scheduler components overview</title>
<mediaobject><imageobject><imagedata align="center" fileref="images/scheduler.overview.gif"/></imageobject></mediaobject>
</figure>
-
+
</section>
-
+
</chapter>
Modified: jbpm3/branches/jbpm-3.2-soa/modules/userguide/src/main/docbook/en-US/tutorial.xml
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/userguide/src/main/docbook/en-US/tutorial.xml 2010-06-22 17:57:45 UTC (rev 6429)
+++ jbpm3/branches/jbpm-3.2-soa/modules/userguide/src/main/docbook/en-US/tutorial.xml 2010-06-22 22:03:45 UTC (rev 6430)
@@ -5,19 +5,30 @@
]>
<chapter id="tutorial">
- <title>Tutorial</title>
+ <title>
+ Tutorial
+ </title>
- <para>This tutorial will show you basic process constructs in jpdl and
- the usage of the API for managing the runtime executions.</para>
+ <para>
+ Study the following tutorial to learn how to use basic
+ <firstterm>process constructs</firstterm> in the JPDL. The tutorial
+ also demonstrates ways in which to manage run-time executions via the
+ application programming interface.
+ </para>
- <para>The format of this tutorial is explaining a set of examples.
- The examples focus on a particular topic and contain extensive
- comments. The examples can also be fond in the jBPM download package
- in the directory <literal>src/java.examples</literal>.</para>
+ <para>
+ Each of the extensively-commented examples in the tutorial can be
+ found in the jBPM download package, located in the
+ <filename>src/java.examples</filename> sub-directory.
+ </para>
- <para>The best way to learn is to create a project and experiment
- by creating variations on the examples given.</para>
-
+<note>
+ <para>
+ Red Hat recommends creating a project at this point. One can then
+ freely experiment and create variations of each of the examples in
+ turn.
+ </para>
+</note>
<para>To get started first,
download and install jBPM. <xref linkend="downloadingandinstallingjbpm" /></para>
@@ -28,13 +39,18 @@
</para>
<section id="helloworldexample">
- <title>Hello World example</title>
+ <title>
+ "Hello World" Example
+ </title>
- <para>A process definition is a directed graph, made up of nodes and
- transitions. The hello world process has 3 nodes. To see how the pieces fit
- together, we're going to start with a simple process without the use of the
- designer tool. The following picture shows the graphical representation of
- the hello world process:
+ <para>
+ A <firstterm>process definition</firstterm> is a <firstterm>directed
+ graph</firstterm>, made up of nodes and transitions. The
+ <systemitem>Hello World</systemitem> process definition has three of
+ these nodes. (It is best to learn how the pieces fit together by
+ studying this simple process without using the <application>Designer
+ Tool</application>.) The following diagram presents a graphical
+ representation of the <systemitem>Hello World</systemitem> process:
</para>
<figure id="hello.world.image">
@@ -99,17 +115,31 @@
</section>
<section id="databaseexample">
- <title>Database example</title>
- <para>One of the basic features of jBPM is the ability to persist executions of processes
- in the database when they are in a wait state. The next example will show you how to
- store a process instance in the jBPM database. The example also suggests a context in
- which this might occur. Separate methods are created for different pieces of user code.
- E.g. an piece of user code in a webapplication starts a process and persists the
- execution in the database. Later, a message driven bean loads the process instance from the
- database and resumes its execution.
+ <title>
+ Database Example
+ </title>
+
+ <para>
+ One of the jBPM's basic features is the ability to make the
+ execution of database processes persist whilst they are in a
+ <systemitem>wait state</systemitem>. The next example demonstrates
+ this ability, storing a process instance in the jBPM database.
+ </para>
+
+ <para>
+ It works by creating separate <systemitem>methods</systemitem> for
+ different pieces of user code. For instance, a piece of user code in
+ a web application starts a process and "persists" the execution in
+ the database. Later, a message-driven bean loads that process
+ instance and resumes the execution of it.
</para>
- <para>More about the jBPM persistence can be found in <xref linkend="persistence" />.</para>
+ <note>
+ <para>
+ More information about jBPM persistence can be found in <xref
+ linkend="persistence" />.
+ </para>
+ </note>
<programlisting>public class HelloWorldDbTest extends TestCase {
@@ -306,16 +336,32 @@
</section>
<section>
- <title>Context example: process variables</title>
+ <title>
+ Contextual Example: Process Variables
+ </title>
- <para>The process variables contain the context information during process executions.
- The process variables are similar to a <literal>java.util.Map</literal> that maps
- variable names to values, which are java objects. The process variables are persisted
- as a part of the process instance. To keep things simple, in this example we only show
- the API to work with variables, without persistence.</para>
-
- <para>More information about variables can be found in <xref linkend="context" /></para>
-
+ <para>
+ Whilst processes are executed, the context information is held in
+ <firstterm>process variables</firstterm>. These are
+ similar to <classname>java.util.Map</classname> classes, in that they map variable
+ names to values, the latter being Java objects. (The process variables are
+ "persisted" as part of the process instance.)
+ </para>
+
+<note>
+ <para>
+ In order to keep the following example simple, only the application
+ programming interface that is needed to work with variables is shown
+ (without any persistence functionality.)
+ </para>
+</note>
+
+<note>
+ <para>
+ Find out more about variables by reading <xref linkend="context" />
+ </para>
+</note>
+
<programlisting><emphasis role="bold">// This example also starts from the hello world process.</emphasis>
<emphasis role="bold">// This time even without modification.</emphasis>
ProcessDefinition processDefinition = ProcessDefinition.parseXmlString(
@@ -361,16 +407,19 @@
</section>
<section id="taskassignmentexample">
- <title>Task assignment example</title>
- <para>In the next example we'll show how you can assign a task to a user. Because
- of the separation between the jBPM workflow engine and the organisational model,
- an expression language for calculating actors would always be too limited.
- Therefore, you have to specify an implementation of AssignmentHandler for
- including the calculation of actors for tasks.
+ <title>
+ Task Assignment Example
+ </title>
+
+ <para>
+ The next example demonstrates how to assign a task to a user.
+ Because of the separation between the jBPM workflow engine and the
+ organizational model, expression languages will always be too
+ limited to use to calculate actors. Instead, specify an
+ implementation of <classname>AssignmentHandler</classname> and use
+ it to include the calculation of actors for tasks.
</para>
-
-
<programlisting>public void testTaskAssignment() {
<emphasis role="bold">// The process shown below is based on the hello world process.</emphasis>
<emphasis role="bold">// The state node is replaced by a task-node. The task-node </emphasis>
@@ -435,24 +484,36 @@
</section>
<section id="customactionexample">
- <title>Custom action example</title>
- <para>Actions are a mechanism to bind your custom java code into a jBPM process.
- Actions can be associated with its own nodes (if they are relevant in the graphical
- representation of the process). Or actions can be placed on events like e.g.
- taking a transition, leaving a node or entering a node. In that case, the actions
- are not part of the graphical representation, but they are executed when execution
- fires the events in a runtime process execution.</para>
+ <title>
+ Example of a Custom Action
+ </title>
+ <para>
+ <firstterm>Actions</firstterm> are mechanisms designed to bind
+ custom Java code to jBPM processes. They can be associated with
+ their own nodes (if these are relevant to the graphical
+ representation of the process.) Alternatively, actions can be
+ "placed on" events (for instance, when taking a transition, or
+ entering or leaving a node.) If they are placed on events, the
+ actions are not treated as part of the graphical representation (but
+ they are still run when the events are "fired" during a run-time
+ process execution.)
+ </para>
- <para>We'll start with a look at the action implementation that we are going to
- use in our example : <literal>MyActionHandler</literal>. This action handler
- implementation does not do really spectacular things... it just sets the
- boolean variable <literal>isExecuted</literal> to <literal>true</literal>.
- The variable <literal>isExecuted</literal> is static so it can be accessed from
- within the action handler as well as from the action to verify it's value.
+ <para>
+ Firstly, look at the action handler implementation to be used in the
+ next example: <systemitem>MyActionHandler</systemitem>. It is not
+ particularly impressive of itself: it merely sets the Boolean
+ variable <systemitem>isExecuted</systemitem> to <code>true</code>.
+ Note that this variable is static so one can access it from within
+ the action handler (and from the action itself) to verify its value.
</para>
-
- <para>More information about actions can be found in <xref linkend="actions" /></para>
-
+
+<note>
+ <para>
+ More information about "actions" can be found in <xref linkend="actions" />
+ </para>
+</note>
+
<programlisting><emphasis role="bold">// MyActionHandler represents a class that could execute </emphasis>
<emphasis role="bold">// some user code during the execution of a jBPM process.</emphasis>
public class MyActionHandler implements ActionHandler {
@@ -469,16 +530,23 @@
}
}</programlisting>
- <para>As mentioned before, before each test, we'll set the static field
- <literal>MyActionHandler.isExecuted</literal> to false;</para>
-
+ <important>
+ <para>
+ Prior to each test, set the static field
+ <classname>MyActionHandler.isExecuted</classname> to
+ <code>false</code>.
+ </para>
+ </important>
+
<programlisting> <emphasis role="bold">// Each test will start with setting the static isExecuted </emphasis>
<emphasis role="bold">// member of MyActionHandler to false.</emphasis>
public void setUp() {
MyActionHandler.isExecuted = false;
}</programlisting>
- <para>We'll start with an action on a transition.</para>
+ <para>
+ The first example illustrates an action on a transition:
+ </para>
<programlisting>public void testTransitionAction() {
<emphasis role="bold">// The next process is a variant of the hello world process.</emphasis>
@@ -525,13 +593,17 @@
assertTrue(MyActionHandler.isExecuted);
}</programlisting>
- <para>The next example shows the same action, but now the actions are placed on
- the <literal>enter-node</literal> and <literal>leave-node</literal> events
- respectively. Note that a node has more than one event type in contrast to
- a transition, which has only one event. Therefore actions placed on a
- node should be put in an event element.
+ <para>
+ The next example shows the same action now being placed on both the
+ <systemitem>enter-node</systemitem> and
+ <systemitem>leave-node</systemitem> events. Note that a node has
+ more than one event type. This is in contrast to a
+ <firstterm>transition</firstterm>, which has only one event. Hence,
+ when placing actions on a node, always put them in an event
+ element.
</para>
+
<programlisting>ProcessDefinition processDefinition = ProcessDefinition.parseXmlString(
"<process-definition>" +
" <start-state>" +
15 years, 10 months
JBoss JBPM SVN: r6429 - in jbpm4/trunk/modules: pvm/src/main/java/org/jbpm/pvm/internal/email/impl and 5 other directories.
by do-not-reply@jboss.org
Author: alex.guizar(a)jboss.com
Date: 2010-06-22 13:57:45 -0400 (Tue, 22 Jun 2010)
New Revision: 6429
Modified:
jbpm4/trunk/modules/pvm/pom.xml
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/email/impl/MailServer.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/wire/binding/HibernateConfigurationBinding.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/wire/binding/MailSessionBinding.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/wire/binding/PropertiesBinding.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/wire/descriptor/JndiDescriptor.java
jbpm4/trunk/modules/pvm/src/main/resources/jbpm.default.cfg.xml
jbpm4/trunk/modules/pvm/src/test/java/org/jbpm/pvm/internal/wire/MailSessionWireTest.java
jbpm4/trunk/modules/userguide/src/main/docbook/en/modules/ch06-Jpdl.xml
jbpm4/trunk/modules/userguide/src/main/docbook/en/modules/ch09-Configuration.xml
Log:
JBPM-1171: fetch mail session from jndi
document mail configuration in user guide
Modified: jbpm4/trunk/modules/pvm/pom.xml
===================================================================
--- jbpm4/trunk/modules/pvm/pom.xml 2010-06-22 16:55:56 UTC (rev 6428)
+++ jbpm4/trunk/modules/pvm/pom.xml 2010-06-22 17:57:45 UTC (rev 6429)
@@ -159,6 +159,12 @@
<artifactId>spring</artifactId>
<scope>provided</scope>
</dependency>
+ <dependency>
+ <groupId>asm</groupId>
+ <artifactId>asm</artifactId>
+ <version>1.5.3</version>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<!-- Plugins -->
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/email/impl/MailServer.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/email/impl/MailServer.java 2010-06-22 16:55:56 UTC (rev 6428)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/email/impl/MailServer.java 2010-06-22 17:57:45 UTC (rev 6429)
@@ -43,8 +43,16 @@
public Session getMailSession() {
if (mailSession == null) {
- mailSession = Session.getInstance(sessionProperties, authenticator);
+ synchronized (this) {
+ if (mailSession == null) {
+ mailSession = Session.getInstance(sessionProperties, authenticator);
+ }
+ }
}
return mailSession;
}
+
+ protected void setMailSession(Session mailSession) {
+ this.mailSession = mailSession;
+ }
}
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/wire/binding/HibernateConfigurationBinding.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/wire/binding/HibernateConfigurationBinding.java 2010-06-22 16:55:56 UTC (rev 6428)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/wire/binding/HibernateConfigurationBinding.java 2010-06-22 17:57:45 UTC (rev 6429)
@@ -22,24 +22,22 @@
package org.jbpm.pvm.internal.wire.binding;
import java.io.File;
-import java.io.InputStream;
import java.net.URL;
-import java.util.Enumeration;
import java.util.List;
import org.hibernate.cfg.Configuration;
+import org.w3c.dom.Element;
+
import org.jbpm.internal.log.Log;
import org.jbpm.pvm.internal.stream.FileStreamInput;
import org.jbpm.pvm.internal.stream.ResourceStreamInput;
import org.jbpm.pvm.internal.stream.StreamInput;
import org.jbpm.pvm.internal.stream.UrlStreamInput;
-import org.jbpm.pvm.internal.util.ReflectUtil;
import org.jbpm.pvm.internal.util.XmlUtil;
import org.jbpm.pvm.internal.wire.descriptor.HibernateConfigurationDescriptor;
import org.jbpm.pvm.internal.wire.descriptor.PropertiesDescriptor;
import org.jbpm.pvm.internal.xml.Parse;
import org.jbpm.pvm.internal.xml.Parser;
-import org.w3c.dom.Element;
/** parses a descriptor for creating a hibernate Configuration.
*
@@ -51,8 +49,6 @@
private static final Log log = Log.getLog(HibernateConfigurationBinding.class.getName());
- private static final PropertiesBinding propertiesBinding = new PropertiesBinding();
-
public HibernateConfigurationBinding() {
super("hibernate-configuration");
}
@@ -134,7 +130,7 @@
}
} else if ("properties".equals(configElement.getLocalName())) {
- PropertiesDescriptor propertiesDescriptor = (PropertiesDescriptor) propertiesBinding.parse(configElement, parse, parser);
+ PropertiesDescriptor propertiesDescriptor = PropertiesBinding.parseDescriptor(configElement, parse, parser);
descriptor.setPropertiesDescriptor(propertiesDescriptor);
} else if ("cache-configuration".equals(configElement.getLocalName())) {
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/wire/binding/MailSessionBinding.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/wire/binding/MailSessionBinding.java 2010-06-22 16:55:56 UTC (rev 6428)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/wire/binding/MailSessionBinding.java 2010-06-22 17:57:45 UTC (rev 6429)
@@ -24,18 +24,20 @@
import java.util.ArrayList;
import java.util.List;
+import org.w3c.dom.Element;
+
+import org.jbpm.pvm.internal.email.impl.AddressFilter;
import org.jbpm.pvm.internal.email.impl.MailServer;
import org.jbpm.pvm.internal.email.impl.MailSessionImpl;
-import org.jbpm.pvm.internal.email.impl.AddressFilter;
import org.jbpm.pvm.internal.email.spi.MailSession;
import org.jbpm.pvm.internal.util.XmlUtil;
import org.jbpm.pvm.internal.wire.Descriptor;
+import org.jbpm.pvm.internal.wire.descriptor.JndiDescriptor;
import org.jbpm.pvm.internal.wire.descriptor.ListDescriptor;
import org.jbpm.pvm.internal.wire.descriptor.ObjectDescriptor;
import org.jbpm.pvm.internal.wire.descriptor.PatternDescriptor;
import org.jbpm.pvm.internal.xml.Parse;
import org.jbpm.pvm.internal.xml.Parser;
-import org.w3c.dom.Element;
/**
* Parses a descriptor for creating a {@link MailSession}.
@@ -44,9 +46,6 @@
*/
public class MailSessionBinding extends WireDescriptorBinding {
- private static final PropertiesBinding propertiesBinding = new PropertiesBinding();
- private static final ObjectBinding objectBinding = new ObjectBinding();
-
public MailSessionBinding() {
super("mail-session");
}
@@ -86,23 +85,29 @@
serverDescriptor.addInjection("addressFilter", filterDescriptor);
}
- // mail session properties
- Element propertiesElement = XmlUtil.element(serverElement, "session-properties");
- if (propertiesElement != null) {
- Descriptor propertiesDescriptor =
- (Descriptor) propertiesBinding.parse(propertiesElement, parse, parser);
- serverDescriptor.addInjection("sessionProperties", propertiesDescriptor);
+ if (serverElement.hasAttribute("session-jndi")) {
+ // session jndi name
+ String jndiName = serverElement.getAttribute("session-jndi");
+ Descriptor jndiDescriptor = new JndiDescriptor(jndiName);
+ serverDescriptor.addInjection("mailSession", jndiDescriptor);
}
else {
- parse.addProblem("missing mail session properties", element);
- }
+ // session properties
+ Element propertiesElement = XmlUtil.element(serverElement, "session-properties");
+ if (propertiesElement != null) {
+ Descriptor propertiesDescriptor = PropertiesBinding.parseDescriptor(propertiesElement, parse, parser);
+ serverDescriptor.addInjection("sessionProperties", propertiesDescriptor);
+ }
+ else {
+ parse.addProblem("missing mail session properties or jndi name", serverElement);
+ }
- // authenticator
- Element authenticatorElement = XmlUtil.element(serverElement, "authenticator");
- if (authenticatorElement != null) {
- Descriptor authenticatorDescriptor =
- (Descriptor) objectBinding.parse(authenticatorElement, parse, parser);
- serverDescriptor.addInjection("authenticator", authenticatorDescriptor);
+ // authenticator
+ Element authenticatorElement = XmlUtil.element(serverElement, "authenticator");
+ if (authenticatorElement != null) {
+ Descriptor authenticatorDescriptor = ObjectBinding.parseObjectDescriptor(authenticatorElement, parse, parser);
+ serverDescriptor.addInjection("authenticator", authenticatorDescriptor);
+ }
}
}
@@ -116,20 +121,23 @@
return sessionDescriptor;
}
- protected Descriptor parsePattern(Element patternElement, Parse parse, Parser parser) {
- PatternDescriptor patternDescriptor =
- new PatternDescriptor(XmlUtil.getContentText(patternElement));
+ public static PatternDescriptor parsePattern(Element element, Parse parse, Parser parser) {
+ // content
+ String regex = XmlUtil.getContentText(element);
+ PatternDescriptor patternDescriptor = new PatternDescriptor(regex);
// literal
- String literalAttr = XmlUtil.attribute(patternElement, "literal");
+ String literalAttr = XmlUtil.attribute(element, "literal");
if (literalAttr != null) {
Boolean literal = XmlUtil.parseBooleanValue(literalAttr);
- if (literal != null) patternDescriptor.setLiteral(literal);
+ if (literal != null)
+ patternDescriptor.setLiteral(literal);
}
// canonEq
- String canonEqAttr = XmlUtil.attribute(patternElement, "canonEq");
+ String canonEqAttr = XmlUtil.attribute(element, "canonEq");
if (canonEqAttr != null) {
Boolean canonEq = XmlUtil.parseBooleanValue(canonEqAttr);
- if (canonEq != null) patternDescriptor.setCanonEq(canonEq);
+ if (canonEq != null)
+ patternDescriptor.setCanonEq(canonEq);
}
return patternDescriptor;
}
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/wire/binding/PropertiesBinding.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/wire/binding/PropertiesBinding.java 2010-06-22 16:55:56 UTC (rev 6428)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/wire/binding/PropertiesBinding.java 2010-06-22 17:57:45 UTC (rev 6429)
@@ -45,6 +45,10 @@
}
public Object parse(Element element, Parse parse, Parser parser) {
+ return parseDescriptor(element, parse, parser);
+ }
+
+ public static PropertiesDescriptor parseDescriptor(Element element, Parse parse, Parser parser) {
PropertiesDescriptor descriptor = new PropertiesDescriptor();
if (element.hasAttribute("file")) {
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/wire/descriptor/JndiDescriptor.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/wire/descriptor/JndiDescriptor.java 2010-06-22 16:55:56 UTC (rev 6428)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/wire/descriptor/JndiDescriptor.java 2010-06-22 17:57:45 UTC (rev 6429)
@@ -21,22 +21,22 @@
*/
package org.jbpm.pvm.internal.wire.descriptor;
+import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import org.jbpm.pvm.internal.wire.WireContext;
import org.jbpm.pvm.internal.wire.WireException;
-
/**
* @author Tom Baeyens
*/
public class JndiDescriptor extends AbstractDescriptor {
private static final long serialVersionUID = 1L;
-
- String jndiName;
-
+
+ private String jndiName;
+
protected JndiDescriptor() {
}
@@ -46,10 +46,16 @@
public Object construct(WireContext wireContext) {
try {
- InitialContext initialContext = new InitialContext();
- return initialContext.lookup(jndiName);
- } catch (NamingException e) {
- throw new WireException("couldn't lookup '"+jndiName+"' from the initial context");
+ Context initialContext = new InitialContext();
+ try {
+ return initialContext.lookup(jndiName);
+ }
+ finally {
+ initialContext.close();
+ }
}
+ catch (NamingException e) {
+ throw new WireException("failed to retrieve named object: " + jndiName, e);
+ }
}
}
Modified: jbpm4/trunk/modules/pvm/src/main/resources/jbpm.default.cfg.xml
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/resources/jbpm.default.cfg.xml 2010-06-22 16:55:56 UTC (rev 6428)
+++ jbpm4/trunk/modules/pvm/src/main/resources/jbpm.default.cfg.xml 2010-06-22 17:57:45 UTC (rev 6429)
@@ -33,8 +33,7 @@
Task "${task.name}" has been assigned to you.
${task.description}
-Sent by JBoss jBPM
-]]></text>
+Sent by jBPM]]></text>
</mail-template>
<mail-template name='task-reminder'>
@@ -44,8 +43,7 @@
Do not forget about task "${task.name}".
${task.description}
-Sent by JBoss jBPM
-]]></text>
+Sent by jBPM]]></text>
</mail-template>
</process-engine-context>
Modified: jbpm4/trunk/modules/pvm/src/test/java/org/jbpm/pvm/internal/wire/MailSessionWireTest.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/test/java/org/jbpm/pvm/internal/wire/MailSessionWireTest.java 2010-06-22 16:55:56 UTC (rev 6428)
+++ jbpm4/trunk/modules/pvm/src/test/java/org/jbpm/pvm/internal/wire/MailSessionWireTest.java 2010-06-22 17:57:45 UTC (rev 6429)
@@ -27,30 +27,34 @@
import javax.mail.Authenticator;
import javax.mail.PasswordAuthentication;
+import javax.mail.Session;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
import org.jbpm.api.JbpmException;
import org.jbpm.pvm.internal.email.impl.AddressFilter;
import org.jbpm.pvm.internal.email.impl.MailServer;
import org.jbpm.pvm.internal.email.impl.MailSessionImpl;
+import com.mockrunner.ejb.JNDIUtil;
+
/**
* @author Alejandro Guizar
*/
public class MailSessionWireTest extends WireTestCase {
public void testSessionProperties() {
- WireContext wireContext =
- createWireContext("<objects>"
- + " <mail-session>"
- + " <mail-server>"
- + " <session-properties>"
- + " <property name='mail.host' value='localhost' />"
- + " <property name='mail.user' value='aguizar' />"
- + " <property name='mail.from' value='noreply(a)jbpm.org' />"
- + " </session-properties>"
- + " </mail-server>"
- + " </mail-session>"
- + "</objects>");
+ WireContext wireContext = createWireContext("<objects>"
+ + " <mail-session>"
+ + " <mail-server>"
+ + " <session-properties>"
+ + " <property name='mail.host' value='localhost' />"
+ + " <property name='mail.user' value='aguizar' />"
+ + " <property name='mail.from' value='noreply(a)jbpm.org' />"
+ + " </session-properties>"
+ + " </mail-server>"
+ + " </mail-session>"
+ + "</objects>");
MailSessionImpl mailSession = wireContext.get(MailSessionImpl.class);
List<MailServer> mailServers = mailSession.getMailServers();
@@ -71,55 +75,62 @@
+ " <mail-server />"
+ " </mail-session>"
+ "</objects>");
- fail("expected wire context creation to puke");
+ fail("expected mail session binding to complain");
}
catch (JbpmException e) {
// session properties are mandatory
}
}
- public static class MyAuthenticator extends Authenticator {
+ public static class BasicAuthenticator extends Authenticator {
+
+ String userName;
+ String password;
+
@Override
protected PasswordAuthentication getPasswordAuthentication() {
- return new PasswordAuthentication("aguizar", "wontsay");
+ return new PasswordAuthentication(userName, password);
}
}
public void testAuthenticator() {
- WireContext wireContext =
- createWireContext("<objects>" +
- " <mail-session>" +
- " <mail-server>" +
- " <session-properties />" +
- " <authenticator class='" +
- MyAuthenticator.class.getName() +
- "' />" +
- " </mail-server>" +
- " </mail-session>" +
- "</objects>");
+ WireContext wireContext = createWireContext("<objects>"
+ + " <mail-session>"
+ + " <mail-server>"
+ + " <session-properties />"
+ + " <authenticator class='"
+ + BasicAuthenticator.class.getName()
+ + "'>"
+ + " <field name='userName'><string value='aguizar'/></field>"
+ + " <field name='password'><string value='wontsay'/></field>"
+ + " </authenticator>"
+ + " </mail-server>"
+ + " </mail-session>"
+ + "</objects>");
MailSessionImpl mailSession = wireContext.get(MailSessionImpl.class);
List<MailServer> mailServers = mailSession.getMailServers();
assertEquals(1, mailServers.size());
MailServer mailServer = mailServers.get(0);
- assertSame(MyAuthenticator.class, mailServer.getAuthenticator().getClass());
+ BasicAuthenticator authenticator = (BasicAuthenticator) mailServer.getAuthenticator();
+ assertEquals("aguizar", authenticator.userName);
+ assertEquals("wontsay", authenticator.password);
}
public void testAddressFilter() {
- WireContext wireContext =
- createWireContext("<objects>"
- + " <mail-session>"
- + " <mail-server>"
- + " <address-filter>"
- + " <include>.+(a)jbpm.org</include>"
- + " <exclude>.+(a)jboss.com</exclude>"
- + " <exclude>.+(a)redhat.com</exclude>"
- + " </address-filter>"
- + " <session-properties />"
- + " </mail-server>"
- + " </mail-session>"
- + "</objects>");
+ WireContext wireContext = createWireContext("<objects>"
+ + " <mail-session>"
+ + " <mail-server>"
+ + " <address-filter>"
+ + " <include>.+(a)jbpm.org</include>"
+ + " <exclude>.+(a)jboss.com</exclude>"
+ + " <exclude>.+(a)redhat.com</exclude>"
+ + " </address-filter>"
+ + " <session-properties />"
+ + " </mail-server>"
+ + " </mail-session>"
+ + "</objects>");
MailSessionImpl mailSession = wireContext.get(MailSessionImpl.class);
List<MailServer> mailServers = mailSession.getMailServers();
@@ -141,14 +152,13 @@
}
public void testNoAddressFilter() {
- WireContext wireContext =
- createWireContext("<objects>"
- + " <mail-session>"
- + " <mail-server>"
- + " <session-properties />"
- + " </mail-server>"
- + " </mail-session>"
- + "</objects>");
+ WireContext wireContext = createWireContext("<objects>"
+ + " <mail-session>"
+ + " <mail-server>"
+ + " <session-properties />"
+ + " </mail-server>"
+ + " </mail-session>"
+ + "</objects>");
MailSessionImpl mailSession = wireContext.get(MailSessionImpl.class);
List<MailServer> mailServers = mailSession.getMailServers();
@@ -160,23 +170,46 @@
}
public void testMultipleMailServers() {
- WireContext wireContext =
- createWireContext("<objects>"
- + " <mail-session>"
- + " <mail-server>"
- + " <session-properties />"
- + " </mail-server>"
- + " <mail-server>"
- + " <session-properties />"
- + " </mail-server>"
- + " <mail-server>"
- + " <session-properties />"
- + " </mail-server>"
- + " </mail-session>"
- + "</objects>");
+ WireContext wireContext = createWireContext("<objects>"
+ + " <mail-session>"
+ + " <mail-server>"
+ + " <session-properties />"
+ + " </mail-server>"
+ + " <mail-server>"
+ + " <session-properties />"
+ + " </mail-server>"
+ + " <mail-server>"
+ + " <session-properties />"
+ + " </mail-server>"
+ + " </mail-session>"
+ + "</objects>");
MailSessionImpl mailSession = wireContext.get(MailSessionImpl.class);
List<MailServer> mailServers = mailSession.getMailServers();
assertEquals(3, mailServers.size());
}
+
+ public void testJndiName() throws NamingException {
+ JNDIUtil.initMockContextFactory();
+ try {
+ Session session = Session.getInstance(new Properties());
+ new InitialContext().bind("java:comp/env/mail/smtp", session);
+
+ WireContext wireContext = createWireContext("<objects>"
+ + " <mail-session>"
+ + " <mail-server session-jndi='java:comp/env/mail/smtp' />"
+ + " </mail-session>"
+ + "</objects>");
+
+ MailSessionImpl mailSession = wireContext.get(MailSessionImpl.class);
+ List<MailServer> mailServers = mailSession.getMailServers();
+ assertEquals(1, mailServers.size());
+
+ MailServer mailServer = mailServers.get(0);
+ assertSame(session, mailServer.getMailSession());
+ }
+ finally {
+ JNDIUtil.resetMockContextFactory();
+ }
+ }
}
Modified: jbpm4/trunk/modules/userguide/src/main/docbook/en/modules/ch06-Jpdl.xml
===================================================================
--- jbpm4/trunk/modules/userguide/src/main/docbook/en/modules/ch06-Jpdl.xml 2010-06-22 16:55:56 UTC (rev 6428)
+++ jbpm4/trunk/modules/userguide/src/main/docbook/en/modules/ch06-Jpdl.xml 2010-06-22 17:57:45 UTC (rev 6429)
@@ -2640,17 +2640,7 @@
</mail>
<state name="end"/>
</process></programlisting>
-
- <para>The default configuration after installation includes a
- <literal>jbpm.mail.properties</literal> file specifying the SMTP host
- that jBPM employs to send mail. To use a mail server other than the
- local host, set the <literal>mail.smtp.host</literal> property in the
- mail properties file.</para>
-
- <para>Refer to the Developers Guide for (unsupported) advanced mail
- configuration and usage.</para>
</section>
-
</section>
<!-- ##################################################################### -->
Modified: jbpm4/trunk/modules/userguide/src/main/docbook/en/modules/ch09-Configuration.xml
===================================================================
--- jbpm4/trunk/modules/userguide/src/main/docbook/en/modules/ch09-Configuration.xml 2010-06-22 16:55:56 UTC (rev 6428)
+++ jbpm4/trunk/modules/userguide/src/main/docbook/en/modules/ch09-Configuration.xml 2010-06-22 17:57:45 UTC (rev 6429)
@@ -4,12 +4,12 @@
<section>
<title>Business calendar</title>
<para>To customize the business calendar configuration,
- remove the import of the default business calendar configuration
- and replace it with your customized calendar configuration. E.g.
+ remove the default business calendar configuration import
+ and replace it with the custom values.
</para>
<programlisting><jbpm-configuration>
- <import resource="jbpm.default.cfg.xml" />
+ <import resource="jbpm.businesscalendar.cfg.xml" />
...
<process-engine-context>
@@ -24,14 +24,12 @@
</process-engine-context>
</jbpm-configuration></programlisting>
-
</section>
<section>
-
<title>Console</title>
<para>By default the server host and port of the console
- webapplication are respectively <literal>localhost</literal>
+ web app are respectively <literal>localhost</literal>
and <literal>8080</literal>. It is not hard to imagine
situations where it is needed to change those defaults.
Hence they are made configurable. To customize,
@@ -47,13 +45,47 @@
</process-engine-context>
</jbpm-configuration></programlisting>
-
</section>
<section>
<title>Email</title>
- <para>TODO document supported config customization
- of the jbpm.mail.properties</para>
+ <para>The default configuration looks for a <literal>jbpm.mail.properties</literal>
+ classpath resource containing <ulink
+ url="http://java.sun.com/products/javamail/javadocs/">JavaMail properties</ulink>.
+ To send mail through a server other than local host, set the
+ <literal>mail.smtp.host</literal> property in the mail properties file.</para>
+
+ <programlisting><![CDATA[mail.smtp.host=localhost
+mail.smtp.port=25
+mail.from=noreply(a)jbpm.org]]></programlisting>
+
+ <para>If the SMTP server requires authentication, the application can supply a
+ custom authenticator in the configuration file.</para>
+
+ <programlisting><![CDATA[<mail-session>
+ <mail-server>
+ <session-properties resource="jbpm.mail.properties" />
+ <authenticator class='BasicAuthenticator'>
+ <field name='userName'><string value='aguizar'/></field>
+ <field name='password'><string value='wontsay'/></field>
+ </authenticator>
+ </mail-server>
+</mail-session>]]></programlisting>
+
+ <para>In Java EE environments it is often the case that a mail session is already
+ configured and bound to JNDI. To employ such a session, specify its JNDI name in
+ the configuration file.</para>
+
+ <programlisting><![CDATA[<mail-session>
+ <mail-server session-jndi='java:comp/env/mail/smtp' />
+</mail-session>]]></programlisting>
+
+ <important><para>If present, the session JNDI name has precedence over the session
+ properties and the authenticator. The combined absence of session-properties
+ and session-jndi constitutes an error.</para></important>
+
+ <para>Refer to the <ulink
+ url="http://docs.jboss.com/jbpm/v4/devguide/html_single/#mailsupport">Developer
+ Guide</ulink> for advanced, yet unsupported, email settings.</para>
</section>
-
</chapter>
15 years, 10 months
JBoss JBPM SVN: r6428 - in jbpm4/trunk/modules: test-db/src/test/java/org/jbpm/test/activity/foreach and 1 other directory.
by do-not-reply@jboss.org
Author: swiderski.maciej
Date: 2010-06-22 12:55:56 -0400 (Tue, 22 Jun 2010)
New Revision: 6428
Modified:
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/ExecutionImpl.java
jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/activity/foreach/ForEachTest.java
Log:
JBPM-2414: added fix for multi executions left test case, changed order of operations, first skip task then remove execution from its parent
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/ExecutionImpl.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/ExecutionImpl.java 2010-06-21 11:39:59 UTC (rev 6427)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/ExecutionImpl.java 2010-06-22 16:55:56 UTC (rev 6428)
@@ -367,7 +367,7 @@
if (parent!=null) {
- parent.removeExecution(this);
+
if (dbSession!=null) {
// make sure task attached to this execution are completed or skipped
@@ -378,6 +378,7 @@
dbSession.delete(this);
}
+ parent.removeExecution(this);
}
else {
// this is a process instance
Modified: jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/activity/foreach/ForEachTest.java
===================================================================
--- jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/activity/foreach/ForEachTest.java 2010-06-21 11:39:59 UTC (rev 6427)
+++ jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/activity/foreach/ForEachTest.java 2010-06-22 16:55:56 UTC (rev 6428)
@@ -435,4 +435,61 @@
assertEquals(1, historyTasks.size());
assertEquals(HistoryTask.STATE_OBSOLETE, historyTasks.get(0).getState());
}
-}
+
+ public void testForEachJoinMultiplicityLeftTasks() {
+ deployJpdlXmlString(""
+ + "<process name='ForEachJoinMultiplicity' xmlns='http://jbpm.org/jpdl/4.4'>"
+ + " <start g='179,17,32,29' name='start1'>"
+ + " <transition g='-43,-18' name='to foreach1' to='foreach1'/>"
+ + " </start>"
+ + " <foreach g='185,95,49,50' name='foreach1' var='assign' in='#{actors}'>"
+ + " <transition name='left' to='task1' g='-44,-18'/>"
+ + " </foreach>"
+ + " <task name='task1' g='90,177,73,44' assignee='#{assign}'>"
+ + " <transition name='to state' to='join2' g='-43,-18'/>"
+ + " </task>"
+ + " <join name='join2' g='192,511,57,44' multiplicity='#{actors.size()-2}'>"
+ + " <transition name='to Big car' to='Big car' g='-42,-18'/>"
+ + " </join>"
+ + " <!
state name='Big car' > "
+ + " <transition name='to end1' to='end1' g='-43,-18'/>"
+ + " </state> "
+ + " <end g='193,606,38,33' name='end1'/>"
+ + "</process>");
+
+ Map<String, ?> variables = Collections.singletonMap("actors", Arrays.asList("alex", "mike", "bob"));
+ ProcessInstance processInstance = executionService.startProcessInstanceByKey("ForEachJoinMultiplicity", variables);
+
+ Task taskAlex = taskService.createTaskQuery().assignee("alex").uniqueResult();
+ assertEquals("task1", taskAlex.getActivityName());
+ taskService.completeTask(taskAlex.getId());
+
+ Task taskMike = taskService.createTaskQuery().assignee("mike").uniqueResult();
+ assertNull(taskMike);
+
+ Task taskBob = taskService.createTaskQuery().assignee("bob").uniqueResult();
+ assertNull(taskBob);
+
+ processInstance = executionService.findProcessInstanceById(processInstance.getId());
+
+ executionService.signalExecutionById(processI!
nstance.getId());
+
+ HistoryProcessInstance history = hist!
oryServi
ce.createHistoryProcessInstanceQuery()
+ .processInstanceId(processInstance.getId())
+ .uniqueResult();
+ assertEquals(ProcessInstance.STATE_ENDED, history.getState());
+ assertEquals("end1", history.getEndActivityName());
+
+ List<HistoryTask> historyTasks = historyService.createHistoryTaskQuery().assignee("alex").list();
+ assertEquals(1, historyTasks.size());
+ assertEquals(HistoryTask.STATE_COMPLETED, historyTasks.get(0).getState());
+
+ historyTasks = historyService.createHistoryTaskQuery().assignee("mike").list();
+ assertEquals(1, historyTasks.size());
+ assertEquals(HistoryTask.STATE_OBSOLETE, historyTasks.get(0).getState());
+
+ historyTasks = historyService.createHistoryTaskQuery().assignee("bob").list();
+ assertEquals(1, historyTasks.size());
+ assertEquals(HistoryTask.STATE_OBSOLETE, historyTasks.get(0).getState());
+ }
+}
\ No newline at end of file
15 years, 10 months
JBoss JBPM SVN: r6427 - jbpm4/trunk/modules/distro/src/main/files/install.
by do-not-reply@jboss.org
Author: rebody
Date: 2010-06-21 07:39:59 -0400 (Mon, 21 Jun 2010)
New Revision: 6427
Modified:
jbpm4/trunk/modules/distro/src/main/files/install/build.xml
Log:
fix tomcat server.xml token replace problem. replace ${hsql.bind.address} to real property value.
Modified: jbpm4/trunk/modules/distro/src/main/files/install/build.xml
===================================================================
--- jbpm4/trunk/modules/distro/src/main/files/install/build.xml 2010-06-19 09:20:36 UTC (rev 6426)
+++ jbpm4/trunk/modules/distro/src/main/files/install/build.xml 2010-06-21 11:39:59 UTC (rev 6427)
@@ -609,6 +609,9 @@
overwrite="true">
<filterset filtersfile="${jdbc.properties.dir}/${database}.properties" />
</copy>
+ <replace file="${tomcat.home}/conf/server.xml"
+ token="$${hsql.bind.address}"
+ value="${hsql.bind.address}" />
</target>
<!-- ### INSTALL EXAMPLES INTO TOMCAT ################################################ -->
15 years, 10 months