Skip to content

Commit

Permalink
added new interface
Browse files Browse the repository at this point in the history
added StaticAdapter interface, updated docu and Execution methods

Issue #534
  • Loading branch information
rsoika committed Jul 16, 2019
1 parent 63bca42 commit 26d7f0b
Show file tree
Hide file tree
Showing 3 changed files with 149 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,14 @@
import org.imixs.workflow.exceptions.AdapterException;

/**
* An Adapter defines an adapter pattern used by the WorkfklowEngine to
* An Adapter defines an adapter pattern used by the WorkflowKernel to
* call adapter implementations defined by the BPMN model.
* <p>
* An adapter class must be associated with a BPMN Signal Event.
*
* @author Ralph Soika
* @version 1.0
* @see org.imixs.workflow.engine.WorkflowService
* @see org.imixs.workflow.engine.WorkflowKernel
*/

public interface Adapter {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*******************************************************************************
* Imixs Workflow
* Copyright (C) 2001, 2011 Imixs Software Solutions GmbH,
* http://www.imixs.com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program 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
* General Public License for more details.
*
* You can receive a copy of the GNU General Public
* License at http://www.gnu.org/licenses/gpl.html
*
* Project:
* http://www.imixs.org
* http://java.net/projects/imixs-workflow
*
* Contributors:
* Imixs Software Solutions GmbH - initial API and implementation
* Ralph Soika - Software Developer
*******************************************************************************/

package org.imixs.workflow;

/**
* A StaticAdapter extends the Adapter Interface. A StaticAdapter is called by
* the WorkfklowKernel during the processing life-cycle. A StaticAdapter can be
* a CDI implementation.
* <p>
* StaticAdapters are called before any Signal-Adapter or plugin was executed.
* <p>
* A StaticAdapter is independent from the BPMN Model and should not be
* associated with a BPMN Signal Event. A StaticAdapter provides static code to
* be executed before the plugin life cylce.
*
* @author Ralph Soika
* @version 1.0
* @see org.imixs.workflow.engine.WorkflowKernel
*/

public interface StaticAdapter extends Adapter {

}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
Expand Down Expand Up @@ -101,6 +102,7 @@ public class WorkflowKernel {

private List<Plugin> pluginRegistry = null;
private Map<String, Adapter> adapterRegistry = null;

private WorkflowContext ctx = null;
private Vector<String> vectorEdgeHistory = new Vector<String>();
private List<ItemCollection> splitWorkitems = null;
Expand Down Expand Up @@ -272,8 +274,7 @@ public List<Plugin> getPluginRegistry() {
* @return updated workitem
* @throws PluginException,ModelException
*/
public ItemCollection process(final ItemCollection workitem)
throws PluginException, ModelException {
public ItemCollection process(final ItemCollection workitem) throws PluginException, ModelException {

// check document context
if (workitem == null)
Expand All @@ -290,7 +291,7 @@ public ItemCollection process(final ItemCollection workitem)
throw new ProcessingErrorException(WorkflowKernel.class.getSimpleName(), UNDEFINED_ACTIVITYID,
"processing error: $eventID undefined (" + workitem.getEventID() + ")");

//ItemCollection documentResult = new ItemCollection(workitem);
// ItemCollection documentResult = new ItemCollection(workitem);
// we do no longer clone the woritem - Issue #507
ItemCollection documentResult = workitem;
vectorEdgeHistory = new Vector<String>();
Expand Down Expand Up @@ -423,17 +424,19 @@ private ItemCollection updateEventList(final ItemCollection documentContext) {

/**
* This method processes a single event on a workflow instance. All registered
* adapter and plug-in classes will be executed.
* handler, adapter and plug-in classes will be executed.
* <p>
* During the processing life-cycle more than one event can be processed. This
* depends on the model definition which can define follow-up-events,
* split-events and conditional events.
* <p>
* After all adapter and plug-in classes are executed, the attributes type,
* $taskID, $workflowstatus and $workflowgroup are updated based on the
* After all handler, adapter and plug-in classes are executed, the attributes
* type, $taskID, $workflowstatus and $workflowgroup are updated based on the
* definition of the target task element.
* <p>
* In case of an AdapterException, the exception data will be wrapped into items with the prefix 'adapter.'
* In case of an AdapterException, the exception data will be wrapped into items
* with the prefix 'adapter.'
*
* @throws PluginException,ModelException
*/
private ItemCollection processEvent(final ItemCollection documentContext, final ItemCollection event)
Expand All @@ -449,32 +452,12 @@ private ItemCollection processEvent(final ItemCollection documentContext, final
}
logger.info(msg);

// execute adapters if adapter class is defined....
String adapterClass = event.getItemValueString("adapter.id");
if (!adapterClass.isEmpty() && adapterClass.matches("^(?:\\w+|\\w+\\.\\w+)+$")) {
Adapter adapter = adapterRegistry.get(adapterClass);
if (adapter != null) {
// execute...
try {
// remove adapter errors..
documentResult.removeItem("adapter.error_context");
documentResult.removeItem("adapter.error_code");
documentResult.removeItem("adapter.error_params");
documentResult.removeItem("adapter.error_message");
documentResult = adapter.execute(documentResult, event);
} catch (AdapterException e) {
logger.warning("...execution of adapter failed: " + e.getMessage());
// update workitem with adapter exception....
documentResult.setItemValue("adapter.error_context", e.getErrorContext());
documentResult.setItemValue("adapter.error_code", e.getErrorCode());
documentResult.setItemValue("adapter.error_params", e.getErrorParameters());
documentResult.setItemValue("adapter.error_message", e.getMessage());
e.printStackTrace();
}
} else {
logger.warning("...Adapter '" + adapterClass + "' not registered - verify model!");
}
}
// execute StaticAdapters
executeStaticAdapters(documentResult, event);

// execute Signal Adapters
executeSignalAdapters(documentResult, event);

// execute plugins - PluginExceptions will bubble up....
try {
documentResult = runPlugins(documentResult, event);
Expand Down Expand Up @@ -532,6 +515,87 @@ private ItemCollection processEvent(final ItemCollection documentContext, final
return documentResult;
}

/**
* This method executes all SignalAdapters associated with the model.
* <p>
* A StaticAdaper should not be associated with a BPMN Signal Event.
*
* @param documentResult
* @param event
*/
private void executeSignalAdapters(ItemCollection documentResult, ItemCollection event) {
logger.finest("......executing SignalAdapters...");
// execute adapters if adapter class is defined....
String adapterClass = event.getItemValueString("adapter.id");
if (!adapterClass.isEmpty() && adapterClass.matches("^(?:\\w+|\\w+\\.\\w+)+$")) {
Adapter adapter = adapterRegistry.get(adapterClass);
if (adapter != null) {

if (adapter instanceof StaticAdapter) {
logger.warning(
"...StaticAdapter '" + adapterClass + "' should not be associated with a Signal Event!");
// ...stop execution as the StaticAdaper was already executed by the method
// executeStaticAdapters...
} else {
// execute...
try {
// remove adapter errors..
documentResult.removeItem("adapter.error_context");
documentResult.removeItem("adapter.error_code");
documentResult.removeItem("adapter.error_params");
documentResult.removeItem("adapter.error_message");
documentResult = adapter.execute(documentResult, event);
} catch (AdapterException e) {
logger.warning("...execution of adapter failed: " + e.getMessage());
// update workitem with adapter exception....
documentResult.setItemValue("adapter.error_context", e.getErrorContext());
documentResult.setItemValue("adapter.error_code", e.getErrorCode());
documentResult.setItemValue("adapter.error_params", e.getErrorParameters());
documentResult.setItemValue("adapter.error_message", e.getMessage());
e.printStackTrace();
}
}
} else {
logger.warning("...Adapter '" + adapterClass + "' not registered - verify model!");
}
}
}

/**
* This method executes all StaticAdapters. StaticAdapters are executed before
* the SignalAdapters
*
* @param documentResult
* @param event
*/
private void executeStaticAdapters(ItemCollection documentResult, ItemCollection event) {
logger.finest("......executing StaticAdapters...");
// execute all StaticAdapters
Collection<Adapter> adapters = adapterRegistry.values();
for (Adapter adapter : adapters) {
// test if Adapter is static
if (adapter instanceof StaticAdapter) {
// execute...
try {
// remove adapter errors..
documentResult.removeItem("adapter.error_context");
documentResult.removeItem("adapter.error_code");
documentResult.removeItem("adapter.error_params");
documentResult.removeItem("adapter.error_message");
documentResult = adapter.execute(documentResult, event);
} catch (AdapterException e) {
logger.warning("...execution of adapter failed: " + e.getMessage());
// update workitem with adapter exception....
documentResult.setItemValue("adapter.error_context", e.getErrorContext());
documentResult.setItemValue("adapter.error_code", e.getErrorCode());
documentResult.setItemValue("adapter.error_params", e.getErrorParameters());
documentResult.setItemValue("adapter.error_message", e.getMessage());
e.printStackTrace();
}
}
}
}

/**
* This method returns the first conditional Task or Event of a given Event
* object. The method evaluates conditional expressions to 'true'. If no
Expand Down

0 comments on commit 26d7f0b

Please sign in to comment.