/**
* 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_SERVICE;
import static java.lang.String.format;
import java.util.HashMap;
import java.util.Map;
import com.codeaffine.workflow.NodeLoader;
import com.codeaffine.workflow.TaskList;
import com.codeaffine.workflow.Workflow;
import com.codeaffine.workflow.WorkflowFactory;
import com.codeaffine.workflow.WorkflowService;
import com.codeaffine.workflow.definition.VariableDeclaration;
import com.codeaffine.workflow.definition.WorkflowDefinitionProvider;
import com.codeaffine.workflow.event.FlowListener;
import com.codeaffine.workflow.event.TaskListener;
import com.codeaffine.workflow.persistence.ClassFinder;
import com.codeaffine.workflow.persistence.Memento;
public class WorkflowServiceImpl implements WorkflowService {
static final String ERROR_DEFINITON_NOT_FOUND = "Could not find definintion with id <%s>.";
private final Map<String, WorkflowDefinitionImpl> definitions;
private final FlowEventNotifier flowEventNotifier;
private final TaskEventNotifier taskEventNotifier;
private final DefinitionFactory definitionFactory;
private final ClassFinderImpl classFinderImpl;
private final WorkflowFactory flowFactory;
private final ScopeImpl serviceScope;
private final TaskListImpl taskList;
private final NodeLoader nodeLoader;
public WorkflowServiceImpl() {
this( new NodeLoaderImpl() );
}
public WorkflowServiceImpl( NodeLoader nodeLoader ) {
this.definitionFactory = new DefinitionFactory();
this.flowEventNotifier = new FlowEventNotifier();
this.taskEventNotifier = new TaskEventNotifier();
this.taskList = new TaskListImpl( taskEventNotifier );
this.nodeLoader = nodeLoader;
this.definitions = new HashMap<String, WorkflowDefinitionImpl>();
this.classFinderImpl = new ClassFinderImpl( definitions );
this.serviceScope = new ScopeImpl();
this.flowFactory = new WorkflowFactoryImpl( serviceScope, definitions, taskList, flowEventNotifier, nodeLoader );
defineVariable( VARIABLE_SERVICE, this );
}
@Override
public Workflow create( String id ) {
synchronized( definitions ) {
return checkExistence( flowFactory.create( id ), id );
}
}
@Override
public String[] getWorkflowDefinitionIds() {
synchronized( definitions ) {
return definitions.keySet().toArray( new String[ definitions.keySet().size() ]);
}
}
@Override
public TaskList getTaskList() {
return taskList;
}
@Override
public <T> T defineVariable( VariableDeclaration<T> declaration, T value ) {
return serviceScope.defineVariable( declaration, value );
}
@Override
public Memento save() {
return taskList.save();
}
@Override
public void restore( Memento memento ) {
taskList.restore( memento );
}
@Override
public void addFlowListener( FlowListener flowListener ) {
flowEventNotifier.addFlowListener( flowListener );
}
@Override
public void removeFlowListener( FlowListener flowListener ) {
flowEventNotifier.removeFlowListener( flowListener );
}
@Override
public void addTaskListener( TaskListener taskListener ) {
taskEventNotifier.addTaskListener( taskListener );
}
@Override
public void removeTaskListener( TaskListener taskListener ) {
taskEventNotifier.removeTaskListener( taskListener );
}
public void addWorkflowDefinition( WorkflowDefinitionProvider definitionProvider ) {
synchronized( definitions ) {
WorkflowDefinitionImpl definition = definitionFactory.defineWorkflow( definitionProvider );
definitions.put( definition.getId(), definition );
}
}
public void removeWorkflowDefinition( WorkflowDefinitionProvider definitionProvider ) {
synchronized( definitions ) {
WorkflowDefinitionImpl definition = definitionFactory.defineWorkflow( definitionProvider );
definitions.remove( definition.getId() );
}
}
public NodeLoader getNodeLoader() {
return nodeLoader;
}
public ClassFinder getClassFinder() {
return classFinderImpl;
}
public ScopeImpl getServiceScope() {
return serviceScope;
}
private static Workflow checkExistence( Workflow result, String id ) {
if( result == null ) {
throw new IllegalArgumentException( format( ERROR_DEFINITON_NOT_FOUND, id ) );
}
return result;
}
}