提交 eaa269fe 编写于 作者: M meyerd

ACT-773 Adding configurable interceptor for client code

上级 41f7bfa1
......@@ -23,6 +23,8 @@ import org.activiti.engine.ActivitiException;
import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.ExecutionListener;
import org.activiti.engine.delegate.Expression;
import org.activiti.engine.impl.context.Context;
import org.activiti.engine.impl.delegate.ExecutionListenerInvocation;
import org.activiti.engine.impl.pvm.delegate.ActivityBehavior;
import org.activiti.engine.impl.pvm.delegate.ActivityExecution;
import org.activiti.engine.impl.pvm.delegate.CompositeActivityBehavior;
......@@ -221,7 +223,9 @@ public abstract class MultiInstanceActivityBehavior extends FlowNodeActivityBeha
List<ExecutionListener> listeners = activity.getExecutionListeners(org.activiti.engine.impl.pvm.PvmEvent.EVENTNAME_END);
for (ExecutionListener executionListener : listeners) {
try {
executionListener.notify((ExecutionListenerExecution) execution);
Context.getProcessEngineConfiguration()
.getDelegateInterceptor()
.handleInvocation(new ExecutionListenerInvocation(executionListener, execution));
} catch (Exception e) {
throw new ActivitiException("Couldn't execute end listener", e);
}
......
......@@ -15,6 +15,9 @@ package org.activiti.engine.impl.bpmn.behavior;
import org.activiti.engine.ActivitiException;
import org.activiti.engine.delegate.Expression;
import org.activiti.engine.delegate.JavaDelegate;
import org.activiti.engine.impl.context.Context;
import org.activiti.engine.impl.delegate.ActivityBehaviorInvocation;
import org.activiti.engine.impl.delegate.JavaDelegateInvocation;
import org.activiti.engine.impl.pvm.delegate.ActivityBehavior;
import org.activiti.engine.impl.pvm.delegate.ActivityExecution;
import org.activiti.engine.impl.pvm.delegate.SignallableActivityBehavior;
......@@ -50,10 +53,14 @@ public class ServiceTaskDelegateExpressionActivityBehavior extends TaskActivityB
Object delegate = expression.getValue(execution);
if (delegate instanceof ActivityBehavior) {
((ActivityBehavior) delegate).execute(execution);
Context.getProcessEngineConfiguration()
.getDelegateInterceptor()
.handleInvocation(new ActivityBehaviorInvocation((ActivityBehavior) delegate, execution));
} else if (delegate instanceof JavaDelegate) {
((JavaDelegate) delegate).execute(execution);
Context.getProcessEngineConfiguration()
.getDelegateInterceptor()
.handleInvocation(new JavaDelegateInvocation((JavaDelegate) delegate, execution));
leave(execution);
} else {
......
......@@ -13,9 +13,11 @@
package org.activiti.engine.impl.bpmn.behavior;
import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.ExecutionListener;
import org.activiti.engine.delegate.JavaDelegate;
import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.impl.context.Context;
import org.activiti.engine.impl.delegate.JavaDelegateInvocation;
import org.activiti.engine.impl.pvm.delegate.ActivityBehavior;
import org.activiti.engine.impl.pvm.delegate.ActivityExecution;
......@@ -44,6 +46,8 @@ public class ServiceTaskJavaDelegateActivityBehavior extends TaskActivityBehavio
}
public void execute(DelegateExecution execution) throws Exception {
javaDelegate.execute(execution);
Context.getProcessEngineConfiguration()
.getDelegateInterceptor()
.handleInvocation(new JavaDelegateInvocation(javaDelegate, execution));
}
}
......@@ -25,14 +25,14 @@ import org.activiti.engine.delegate.ExecutionListener;
import org.activiti.engine.delegate.JavaDelegate;
import org.activiti.engine.delegate.TaskListener;
import org.activiti.engine.impl.bpmn.behavior.AbstractBpmnActivityBehavior;
import org.activiti.engine.impl.bpmn.behavior.ParallelMultiInstanceBehavior;
import org.activiti.engine.impl.bpmn.behavior.SequentialMultiInstanceBehavior;
import org.activiti.engine.impl.bpmn.behavior.ServiceTaskJavaDelegateActivityBehavior;
import org.activiti.engine.impl.bpmn.parser.FieldDeclaration;
import org.activiti.engine.impl.context.Context;
import org.activiti.engine.impl.delegate.ExecutionListenerInvocation;
import org.activiti.engine.impl.delegate.TaskListenerInvocation;
import org.activiti.engine.impl.pvm.delegate.ActivityBehavior;
import org.activiti.engine.impl.pvm.delegate.ActivityExecution;
import org.activiti.engine.impl.pvm.delegate.SignallableActivityBehavior;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.impl.util.ReflectUtil;
......@@ -64,8 +64,10 @@ public class ClassDelegate extends AbstractBpmnActivityBehavior implements TaskL
public void notify(DelegateExecution execution) throws Exception {
if (executionListenerInstance == null) {
executionListenerInstance = getExecutionListenerInstance();
}
executionListenerInstance.notify(execution);
}
Context.getProcessEngineConfiguration()
.getDelegateInterceptor()
.handleInvocation(new ExecutionListenerInvocation(executionListenerInstance, execution));
}
protected ExecutionListener getExecutionListenerInstance() {
......@@ -84,7 +86,13 @@ public class ClassDelegate extends AbstractBpmnActivityBehavior implements TaskL
if (taskListenerInstance == null) {
taskListenerInstance = getTaskListenerInstance();
}
taskListenerInstance.notify(delegateTask);
try {
Context.getProcessEngineConfiguration()
.getDelegateInterceptor()
.handleInvocation(new TaskListenerInvocation(taskListenerInstance, delegateTask));
}catch (Exception e) {
throw new ActivitiException("Exception while invoking TaskListener: "+e.getMessage(), e);
}
}
protected TaskListener getTaskListenerInstance() {
......
......@@ -17,6 +17,9 @@ import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.ExecutionListener;
import org.activiti.engine.delegate.Expression;
import org.activiti.engine.delegate.JavaDelegate;
import org.activiti.engine.impl.context.Context;
import org.activiti.engine.impl.delegate.ExecutionListenerInvocation;
import org.activiti.engine.impl.delegate.JavaDelegateInvocation;
/**
......@@ -36,9 +39,13 @@ public class DelegateExpressionExecutionListener implements ExecutionListener {
Object delegate = expression.getValue(execution);
if (delegate instanceof ExecutionListener) {
((ExecutionListener) delegate).notify(execution);
Context.getProcessEngineConfiguration()
.getDelegateInterceptor()
.handleInvocation(new ExecutionListenerInvocation((ExecutionListener) delegate, execution));
} else if (delegate instanceof JavaDelegate) {
((JavaDelegate) delegate).execute(execution);
Context.getProcessEngineConfiguration()
.getDelegateInterceptor()
.handleInvocation(new JavaDelegateInvocation((JavaDelegate) delegate, execution));
} else {
throw new ActivitiException("Delegate expression " + expression
+ " did not resolve to an implementation of " + ExecutionListener.class
......
......@@ -16,6 +16,8 @@ import org.activiti.engine.ActivitiException;
import org.activiti.engine.delegate.DelegateTask;
import org.activiti.engine.delegate.Expression;
import org.activiti.engine.delegate.TaskListener;
import org.activiti.engine.impl.context.Context;
import org.activiti.engine.impl.delegate.TaskListenerInvocation;
/**
......@@ -35,7 +37,13 @@ public class DelegateExpressionTaskListener implements TaskListener {
Object delegate = expression.getValue(delegateTask.getExecution());
if (delegate instanceof TaskListener) {
((TaskListener) delegate).notify(delegateTask);
try {
Context.getProcessEngineConfiguration()
.getDelegateInterceptor()
.handleInvocation(new TaskListenerInvocation((TaskListener)delegate, delegateTask));
}catch (Exception e) {
throw new ActivitiException("Exception while invoking TaskListener: "+e.getMessage(), e);
}
} else {
throw new ActivitiException("Delegate expression " + expression
+ " did not resolve to an implementation of " + TaskListener.class );
......
......@@ -63,6 +63,7 @@ import org.activiti.engine.impl.cfg.standalone.StandaloneMybatisTransactionConte
import org.activiti.engine.impl.db.DbIdGenerator;
import org.activiti.engine.impl.db.DbSqlSessionFactory;
import org.activiti.engine.impl.db.IbatisVariableTypeHandler;
import org.activiti.engine.impl.delegate.DefaultDelegateInterceptor;
import org.activiti.engine.impl.el.ExpressionManager;
import org.activiti.engine.impl.form.AbstractFormType;
import org.activiti.engine.impl.form.BooleanFormType;
......@@ -76,6 +77,7 @@ import org.activiti.engine.impl.history.handler.HistoryParseListener;
import org.activiti.engine.impl.interceptor.CommandContextFactory;
import org.activiti.engine.impl.interceptor.CommandExecutor;
import org.activiti.engine.impl.interceptor.CommandInterceptor;
import org.activiti.engine.impl.interceptor.DelegateInterceptor;
import org.activiti.engine.impl.interceptor.SessionFactory;
import org.activiti.engine.impl.jobexecutor.JobExecutor;
import org.activiti.engine.impl.jobexecutor.JobHandler;
......@@ -256,6 +258,8 @@ public abstract class ProcessEngineConfigurationImpl extends ProcessEngineConfig
protected boolean isDbHistoryUsed = true;
protected boolean isDbCycleUsed = false;
protected DelegateInterceptor delegateInterceptor;
// buildProcessEngine ///////////////////////////////////////////////////////
public ProcessEngine buildProcessEngine() {
......@@ -287,6 +291,7 @@ public abstract class ProcessEngineConfigurationImpl extends ProcessEngineConfig
initSqlSessionFactory();
initSessionFactories();
initJpa();
initDelegateInterceptor();
}
// command executors ////////////////////////////////////////////////////////
......@@ -783,6 +788,12 @@ public abstract class ProcessEngineConfigurationImpl extends ProcessEngineConfig
}
}
protected void initDelegateInterceptor() {
if(delegateInterceptor == null) {
delegateInterceptor = new DefaultDelegateInterceptor();
}
}
// JPA //////////////////////////////////////////////////////////////////////
protected void initJpa() {
......@@ -1470,5 +1481,14 @@ public abstract class ProcessEngineConfigurationImpl extends ProcessEngineConfig
public void setDeploymentCache(DeploymentCache deploymentCache) {
this.deploymentCache = deploymentCache;
}
public ProcessEngineConfigurationImpl setDelegateInterceptor(DelegateInterceptor delegateInterceptor) {
this.delegateInterceptor = delegateInterceptor;
return this;
}
public DelegateInterceptor getDelegateInterceptor() {
return delegateInterceptor;
}
}
\ No newline at end of file
package org.activiti.engine.impl.delegate;
import org.activiti.engine.impl.pvm.delegate.ActivityBehavior;
import org.activiti.engine.impl.pvm.delegate.ActivityExecution;
/**
*
* @author Daniel Meyer
*/
public class ActivityBehaviorInvocation extends DelegateInvocation {
protected final ActivityBehavior behaviorInstance;
protected final ActivityExecution execution;
public ActivityBehaviorInvocation(ActivityBehavior behaviorInstance, ActivityExecution execution) {
this.behaviorInstance = behaviorInstance;
this.execution = execution;
}
protected void invoke() throws Exception {
behaviorInstance.execute(execution);
}
}
package org.activiti.engine.impl.delegate;
import org.activiti.engine.impl.interceptor.DelegateInterceptor;
/**
* Default implementation, simply proceeding the call.
*
* @author Daniel Meyer
*/
public class DefaultDelegateInterceptor implements DelegateInterceptor {
public void handleInvocation(DelegateInvocation invocation) throws Exception {
invocation.proceed();
}
}
package org.activiti.engine.impl.delegate;
import org.activiti.engine.impl.interceptor.DelegateInterceptor;
/**
* Provides context about the invocation of usercode and handles the actual
* invocation
*
* @author Daniel Meyer
* @see DelegateInterceptor
*/
public abstract class DelegateInvocation {
protected Object invocationResult;
protected Object[] invocationParameters;
/**
* make the invocation proceed, performing the actual invocation of the user
* code.
*
* @throws Exception
* the exception thrown by the user code
*/
public void proceed() throws Exception {
invoke();
}
protected abstract void invoke() throws Exception;
/**
* @return the result of the invocation (can be null if the invocation does
* not return a result)
*/
public Object getInvocationResult() {
return invocationResult;
}
/**
* @return an array of invocation parameters (null if the invocation takes no
* parameters)
*/
public Object[] getInvocationParameters() {
return invocationParameters;
}
}
package org.activiti.engine.impl.delegate;
import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.ExecutionListener;
/**
* Class handling invocations of ExecutionListeners
*
* @author Daniel Meyer
*/
public class ExecutionListenerInvocation extends DelegateInvocation {
protected final ExecutionListener executionListenerInstance;
protected final DelegateExecution execution;
public ExecutionListenerInvocation(ExecutionListener executionListenerInstance, DelegateExecution execution) {
this.executionListenerInstance = executionListenerInstance;
this.execution = execution;
}
protected void invoke() throws Exception {
executionListenerInstance.notify(execution);
}
}
package org.activiti.engine.impl.delegate;
import org.activiti.engine.impl.javax.el.ELContext;
import org.activiti.engine.impl.javax.el.ValueExpression;
/**
* Class responsible for handling Expression.getValue invocations
*
* @author Daniel Meyer
*/
public class ExpressionGetInvocation extends ExpressionInvocation {
protected final ELContext elContext;
public ExpressionGetInvocation(ValueExpression valueExpression, ELContext elContext) {
super(valueExpression);
this.elContext = elContext;
}
@Override
protected void invoke() throws Exception {
invocationResult = valueExpression.getValue(elContext);
}
}
package org.activiti.engine.impl.delegate;
import org.activiti.engine.impl.javax.el.ValueExpression;
/**
* Baseclass responsible for handling invocations of Expressions
*
* @author Daniel Meyer
*/
public abstract class ExpressionInvocation extends DelegateInvocation {
protected final ValueExpression valueExpression;
public ExpressionInvocation(ValueExpression valueExpression) {
this.valueExpression = valueExpression;
}
}
package org.activiti.engine.impl.delegate;
import org.activiti.engine.impl.javax.el.ELContext;
import org.activiti.engine.impl.javax.el.ValueExpression;
/**
* Class responsible for handling Expression.setValue() invocations.
*
* @author Daniel Meyer
*/
public class ExpressionSetInvocation extends ExpressionInvocation {
protected final Object value;
protected ELContext elContext;
public ExpressionSetInvocation(ValueExpression valueExpression, ELContext elContext, Object value) {
super(valueExpression);
this.value = value;
this.elContext = elContext;
this.invocationParameters = new Object[] {value};
}
@Override
protected void invoke() throws Exception {
valueExpression.setValue(elContext, value);
}
}
package org.activiti.engine.impl.delegate;
import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.JavaDelegate;
/**
* Class handling invocations of JavaDelegates
*
* @author Daniel Meyer
*/
public class JavaDelegateInvocation extends DelegateInvocation {
protected final JavaDelegate delegateInstance;
protected final DelegateExecution execution;
public JavaDelegateInvocation(JavaDelegate delegateInstance, DelegateExecution execution) {
this.delegateInstance = delegateInstance;
this.execution = execution;
}
protected void invoke() throws Exception {
delegateInstance.execute((DelegateExecution) execution);
}
}
package org.activiti.engine.impl.delegate;
import org.activiti.engine.delegate.DelegateTask;
import org.activiti.engine.delegate.TaskListener;
/**
* Class handling invocations of {@link TaskListener TaskListeners}
*
* @author Daniel Meyer
*/
public class TaskListenerInvocation extends DelegateInvocation {
protected final TaskListener executionListenerInstance;
protected final DelegateTask delegateTask;
public TaskListenerInvocation(TaskListener executionListenerInstance, DelegateTask delegateTask) {
this.executionListenerInstance = executionListenerInstance;
this.delegateTask = delegateTask;
}
protected void invoke() throws Exception {
executionListenerInstance.notify(delegateTask);
}
}
package org.activiti.engine.impl.delegate;
import org.activiti.engine.impl.interceptor.DelegateInterceptor;
import org.activiti.engine.impl.persistence.entity.ExecutionEntity;
import org.activiti.engine.runtime.Execution;
/**
* Provides context about the invocation of usercode and handles the actual
* invocation
*
* @author Daniel Meyer
* @see DelegateInterceptor
*/
public abstract class UserCodeInvocation {
protected Object invocationResult;
protected final ExecutionEntity execution;
public UserCodeInvocation(ExecutionEntity execution) {
this.execution = execution;
}
/**
* make the invocation proceed, performing the actual invocation of the user
* code.
*
* @throws Exception
* the exception thrown by the user code
*/
public void proceed() throws Exception {
handleInvocation();
}
protected abstract void handleInvocation() throws Exception;
/**
* return the result of the invocation
*/
public Object getInvocationResult() {
return invocationResult;
}
/**
* @return the current {@link Execution}
*/
public ExecutionEntity getExecution() {
return execution;
}
}
......@@ -15,6 +15,9 @@ package org.activiti.engine.impl.el;
import org.activiti.engine.ActivitiException;
import org.activiti.engine.delegate.VariableScope;
import org.activiti.engine.impl.context.Context;
import org.activiti.engine.impl.delegate.ExpressionGetInvocation;
import org.activiti.engine.impl.delegate.ExpressionSetInvocation;
import org.activiti.engine.impl.javax.el.ELContext;
import org.activiti.engine.impl.javax.el.ELException;
import org.activiti.engine.impl.javax.el.MethodNotFoundException;
......@@ -43,19 +46,32 @@ public class JuelExpression implements Expression {
public Object getValue(VariableScope variableScope) {
ELContext elContext = expressionManager.getElContext(variableScope);
try {
return valueExpression.getValue(elContext);
ExpressionGetInvocation invocation = new ExpressionGetInvocation(valueExpression, elContext);
Context.getProcessEngineConfiguration()
.getDelegateInterceptor()
.handleInvocation(invocation);
return invocation.getInvocationResult();
} catch (PropertyNotFoundException pnfe) {
throw new ActivitiException("Unknown property used in expression", pnfe);
} catch (MethodNotFoundException mnfe) {
throw new ActivitiException("Unknown method used in expression", mnfe);
} catch(ELException ele) {
throw new ActivitiException("Error while evalutaing expression", ele);
} catch (Exception e) {
throw new ActivitiException("Error while evalutaing expression", e);
}
}
public void setValue(Object value, VariableScope variableScope) {
ELContext elContext = expressionManager.getElContext(variableScope);
valueExpression.setValue(elContext, value);
try {
ExpressionSetInvocation invocation = new ExpressionSetInvocation(valueExpression, elContext, value);
Context.getProcessEngineConfiguration()
.getDelegateInterceptor()
.handleInvocation(invocation);
}catch (Exception e) {
throw new ActivitiException("Error while evalutaing expression", e);
}
}
@Override
......
package org.activiti.engine.impl.interceptor;
import org.activiti.engine.impl.delegate.DelegateInvocation;
/**
* Interceptor responsible for handling calls to 'user code'. User code
* represents external Java code (e.g. services and listeners). The following is
* a list of classes that represent user code:
* <ul>
* <li>{@link org.activiti.engine.delegate.JavaDelegate}</li>
* <li>{@link org.activiti.engine.delegate.ExecutionListener}</li>
* <li>{@link org.activiti.engine.delegate.Expression}</li>
* <li>{@link org.activiti.engine.delegate.TaskListener}</li>
* </ul>
*
* The interceptor is passed in an instance of {@link DelegateInvocation}.
* Implementations are responsible for calling
* {@link DelegateInvocation#proceed()} to make the call to the usercode.
*
* @author Daniel Meyer
*/
public interface DelegateInterceptor {
public void handleInvocation(DelegateInvocation invocation) throws Exception;
}
......@@ -31,6 +31,7 @@ import org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.activiti.engine.impl.context.Context;
import org.activiti.engine.impl.db.DbSqlSession;
import org.activiti.engine.impl.db.PersistentObject;
import org.activiti.engine.impl.delegate.TaskListenerInvocation;
import org.activiti.engine.impl.interceptor.CommandContext;
import org.activiti.engine.impl.pvm.delegate.ActivityExecution;
import org.activiti.engine.impl.task.TaskDefinition;
......@@ -504,7 +505,13 @@ public class TaskEntity extends VariableScopeImpl implements Task, DelegateTask,
if (execution != null) {
setEventName(taskEventName);
}
taskListener.notify(this);
try {
Context.getProcessEngineConfiguration()
.getDelegateInterceptor()
.handleInvocation(new TaskListenerInvocation(taskListener, (DelegateTask)this));
}catch (Exception e) {
throw new ActivitiException("Exception while invoking TaskListener: "+e.getMessage(), e);
}
}
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册