/**
* Copyright (c) 2014 - 2017 Frank Appel
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Frank Appel - initial API and implementation
*/
package com.codeaffine.workflow.internal;
import static com.codeaffine.workflow.WorkflowContext.VARIABLE_CONTEXT;
import static com.codeaffine.workflow.WorkflowContext.VARIABLE_TASK_LIST;
import com.codeaffine.workflow.NodeDefinition;
import com.codeaffine.workflow.NodeLoader;
import com.codeaffine.workflow.Workflow;
import com.codeaffine.workflow.WorkflowContext;
import com.codeaffine.workflow.definition.Activity;
import com.codeaffine.workflow.definition.ActivityAspect;
import com.codeaffine.workflow.definition.Task;
import com.codeaffine.workflow.definition.VariableDeclaration;
import com.codeaffine.workflow.definition.WorkflowDefinition;
import com.codeaffine.workflow.persistence.WorkflowMemento;
public class WorkflowImpl implements Workflow {
private final WorkflowDefinitionImpl definition;
private final ActivityExecutor activityExecutor;
private final FlowProcessor flowProcessor;
private final WorkflowContextImpl context;
private final NodeLoader nodeLoader;
private final TaskListImpl taskList;
public WorkflowImpl(
WorkflowDefinition definition, TaskListImpl taskList, FlowEventNotifier notifier, NodeLoader nodeLoader )
{
this.definition = ( WorkflowDefinitionImpl )definition;
this.taskList = taskList;
this.nodeLoader = nodeLoader;
this.context = new WorkflowContextImpl();
this.activityExecutor = new ActivityExecutor();
this.flowProcessor = new FlowProcessor( nodeLoader, notifier, context, this.definition );
defineDefaultVariables();
}
public String getDefinitionId() {
return definition.getId();
}
@Override
public boolean matches( Object value ) {
boolean result = false;
if( definition.getMatcher() != null ) {
result = definition.getMatcher().matches( value );
}
return result;
}
@Override
@SuppressWarnings( "unchecked" )
public void copyContext( WorkflowContext workflowContext ) {
for( VariableDeclaration<?> variableDeclaration : workflowContext.getVariableDeclarations() ) {
VariableDeclaration<Object> variableDeclaration2 = (com.codeaffine.workflow.definition.VariableDeclaration<Object> )variableDeclaration;
defineVariable( variableDeclaration2, workflowContext.getVariableValue( variableDeclaration ) );
}
}
@Override
public <T> T defineVariable( VariableDeclaration<T> declaration, T value ) {
return context.defineVariable( declaration, value );
}
@Override
public WorkflowContext getContext() {
return context;
}
public WorkflowMemento save() {
return new WorkflowMemento( flowProcessor.save(), context.save() );
}
public void restore( WorkflowMemento memento ) {
flowProcessor.restore( memento.getFlowProcessorMemento() );
context.restore( memento.getContextMemento() );
defineDefaultVariables();
}
@Override
public void addActivityAspect( ActivityAspect activityConditionCheck ) {
activityExecutor.add( activityConditionCheck );
}
@Override
public void start() {
continueWorkflow();
}
public void continueWorkflow() {
flowProcessor.move();
if( flowProcessor.isAvailable() ) {
handleNode( flowProcessor.acquire() );
}
}
private void handleNode( NodeDefinition nodeDefinition ) {
Class<?> type = nodeDefinition.getType();
if( Activity.class.isAssignableFrom( type ) ) {
Activity activity = ( Activity )nodeLoader.load( type, context );
activityExecutor.execute( activity );
continueWorkflow();
} else {
Task task = ( Task )nodeLoader.load( type, context );
taskList.add( task, this );
}
}
private void defineDefaultVariables() {
defineVariable( VARIABLE_CONTEXT, context );
defineVariable( VARIABLE_TASK_LIST, taskList );
}
}