summaryrefslogtreecommitdiff
path: root/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process
diff options
context:
space:
mode:
authorThomas Lenz <thomas.lenz@egiz.gv.at>2019-12-04 19:43:32 +0100
committerThomas Lenz <thomas.lenz@egiz.gv.at>2019-12-04 19:43:32 +0100
commit759ac5f42c6aff901dbeede4fbf1a1d2e08cad0f (patch)
tree2132024fc058b1ef5338bf50df575a3244cc3f9f /eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process
parent4f15bdc45b08724d20c66c9fd74ea6a43a03c32f (diff)
downloadEAAF-Components-759ac5f42c6aff901dbeede4fbf1a1d2e08cad0f.tar.gz
EAAF-Components-759ac5f42c6aff901dbeede4fbf1a1d2e08cad0f.tar.bz2
EAAF-Components-759ac5f42c6aff901dbeede4fbf1a1d2e08cad0f.zip
common EGIZ code-style refactoring
Diffstat (limited to 'eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process')
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ExecutionContextImpl.java188
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ExpressionEvaluationContextImpl.java89
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ProcessDefinitionParser.java430
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ProcessDefinitionParserException.java83
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ProcessEngineImpl.java968
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ProcessInstance.java337
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ProcessInstanceState.java81
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/dao/ProcessInstanceStore.java138
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/dao/ProcessInstanceStoreDAOImpl.java97
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/dao/ProcessInstanceStoreDaoImpl.java94
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/model/EndEvent.java94
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/model/ProcessDefinition.java319
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/model/ProcessNode.java144
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/model/StartEvent.java100
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/model/TaskInfo.java195
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/model/Transition.java258
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/spring/SpringExpressionEvaluator.java105
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/springweb/AbstractAuthSourceServlet.java217
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/springweb/AbstractTask.java177
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/springweb/SpringWebExpressionEvaluator.java232
20 files changed, 2120 insertions, 2226 deletions
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ExecutionContextImpl.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ExecutionContextImpl.java
index 3cd696df..619911c1 100644
--- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ExecutionContextImpl.java
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ExecutionContextImpl.java
@@ -1,29 +1,22 @@
-/*******************************************************************************
- * Copyright 2017 Graz University of Technology
- * EAAF-Core Components has been developed in a cooperation between EGIZ,
- * A-SIT Plus, A-SIT, and Graz University of Technology.
+/*
+ * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a
+ * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology.
*
- * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European
+ * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in
+ * compliance with the Licence. You may obtain a copy of the Licence at:
* https://joinup.ec.europa.eu/news/understanding-eupl-v12
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+*/
+
package at.gv.egiz.eaaf.core.impl.idp.process;
import java.io.Serializable;
@@ -31,87 +24,88 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
-
import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext;
/**
* ExecutionContext implementation, related to a certain process instance.
- *
+ *
* @author tknall
- *
+ *
*/
public class ExecutionContextImpl implements ExecutionContext {
- private static final long serialVersionUID = 1L;
-
- private final Map<String, Serializable> ctxData = Collections.synchronizedMap(new HashMap<String, Serializable>());
-
- private String processInstanceId;
- private boolean markedAsCancelled = false;
-
- /**
- * Creates a new instance.
- */
- public ExecutionContextImpl() {
- }
-
- /**
- * Creates a new instance and associated it with a certain process instance.
- */
- public ExecutionContextImpl(String processInstanceId) {
- this.processInstanceId = processInstanceId;
- }
-
- @Override
- public void setProcessInstanceId(String processInstanceId) {
- this.processInstanceId = processInstanceId;
- }
-
- @Override
- public String getProcessInstanceId() {
- return processInstanceId;
- }
-
- @Override
- public Serializable get(String key) {
- return ctxData.get(key);
- }
-
- @Override
- public Serializable remove(String key) {
- return ctxData.remove(key);
- }
-
- @Override
- public void put(String key, Serializable object) {
- ctxData.put(key, object);
- }
-
- @Override
- public Set<String> keySet() {
- return Collections.unmodifiableSet(ctxData.keySet());
- }
-
- @Override
- public String toString() {
- final StringBuilder builder = new StringBuilder();
- builder.append("ExecutionContextImpl [");
- builder.append("id=").append(processInstanceId);
- builder.append(", variables=");
- builder.append(ctxData.keySet());
- builder.append("]");
- return builder.toString();
- }
-
- @Override
- public boolean isProcessCancelled() {
- return markedAsCancelled;
- }
-
- @Override
- public void setCanceleProcessFlag() {
- markedAsCancelled = true;
-
- }
+ private static final long serialVersionUID = 1L;
+
+ private final Map<String, Serializable> ctxData =
+ Collections.synchronizedMap(new HashMap<String, Serializable>());
+
+ private String processInstanceId;
+ private boolean markedAsCancelled = false;
+
+ /**
+ * Creates a new instance.
+ */
+ public ExecutionContextImpl() {
+
+ }
+
+ /**
+ * Creates a new instance and associated it with a certain process instance.
+ */
+ public ExecutionContextImpl(final String processInstanceId) {
+ this.processInstanceId = processInstanceId;
+ }
+
+ @Override
+ public void setProcessInstanceId(final String processInstanceId) {
+ this.processInstanceId = processInstanceId;
+ }
+
+ @Override
+ public String getProcessInstanceId() {
+ return processInstanceId;
+ }
+
+ @Override
+ public Serializable get(final String key) {
+ return ctxData.get(key);
+ }
+
+ @Override
+ public Serializable remove(final String key) {
+ return ctxData.remove(key);
+ }
+
+ @Override
+ public void put(final String key, final Serializable object) {
+ ctxData.put(key, object);
+ }
+
+ @Override
+ public Set<String> keySet() {
+ return Collections.unmodifiableSet(ctxData.keySet());
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder builder = new StringBuilder();
+ builder.append("ExecutionContextImpl [");
+ builder.append("id=").append(processInstanceId);
+ builder.append(", variables=");
+ builder.append(ctxData.keySet());
+ builder.append("]");
+ return builder.toString();
+ }
+
+ @Override
+ public boolean isProcessCancelled() {
+ return markedAsCancelled;
+ }
+
+ @Override
+ public void setCanceleProcessFlag() {
+ markedAsCancelled = true;
+
+ }
}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ExpressionEvaluationContextImpl.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ExpressionEvaluationContextImpl.java
index 694b8d0d..72ad456f 100644
--- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ExpressionEvaluationContextImpl.java
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ExpressionEvaluationContextImpl.java
@@ -1,29 +1,22 @@
-/*******************************************************************************
- * Copyright 2017 Graz University of Technology
- * EAAF-Core Components has been developed in a cooperation between EGIZ,
- * A-SIT Plus, A-SIT, and Graz University of Technology.
+/*
+ * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a
+ * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology.
*
- * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European
+ * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in
+ * compliance with the Licence. You may obtain a copy of the Licence at:
* https://joinup.ec.europa.eu/news/understanding-eupl-v12
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+*/
+
package at.gv.egiz.eaaf.core.impl.idp.process;
import java.io.Serializable;
@@ -31,40 +24,38 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
-
import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext;
import at.gv.egiz.eaaf.core.api.idp.process.ExpressionEvaluationContext;
/**
* Context implementation used for expression evaluation only.
- *
+ *
* @author tknall
- *
+ *
*/
public class ExpressionEvaluationContextImpl implements ExpressionEvaluationContext {
- private static final long serialVersionUID = 1L;
-
- private Map<String, Serializable> ctxData;
-
- /**
- * Creates a new instance and initializes it with data from a given process instance.
- *
- * @param processInstance
- * The process instance.
- */
- ExpressionEvaluationContextImpl(ProcessInstance processInstance) {
- ExecutionContext executionContext = processInstance.getExecutionContext();
- Set<String> keys = executionContext.keySet();
- ctxData = Collections.synchronizedMap(new HashMap<String, Serializable>(keys.size()));
- for (String key : keys) {
- ctxData.put(key, executionContext.get(key));
- }
- }
-
- @Override
- public Map<String, Serializable> getCtx() {
- return Collections.unmodifiableMap(ctxData);
- }
+ private static final long serialVersionUID = 1L;
+
+ private final Map<String, Serializable> ctxData;
+
+ /**
+ * Creates a new instance and initializes it with data from a given process instance.
+ *
+ * @param processInstance The process instance.
+ */
+ ExpressionEvaluationContextImpl(final ProcessInstance processInstance) {
+ final ExecutionContext executionContext = processInstance.getExecutionContext();
+ final Set<String> keys = executionContext.keySet();
+ ctxData = Collections.synchronizedMap(new HashMap<String, Serializable>(keys.size()));
+ for (final String key : keys) {
+ ctxData.put(key, executionContext.get(key));
+ }
+ }
+
+ @Override
+ public Map<String, Serializable> getCtx() {
+ return Collections.unmodifiableMap(ctxData);
+ }
}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ProcessDefinitionParser.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ProcessDefinitionParser.java
index f817f9fb..63ae66d5 100644
--- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ProcessDefinitionParser.java
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ProcessDefinitionParser.java
@@ -1,29 +1,22 @@
-/*******************************************************************************
- * Copyright 2017 Graz University of Technology
- * EAAF-Core Components has been developed in a cooperation between EGIZ,
- * A-SIT Plus, A-SIT, and Graz University of Technology.
+/*
+ * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a
+ * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology.
*
- * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European
+ * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in
+ * compliance with the Licence. You may obtain a copy of the Licence at:
* https://joinup.ec.europa.eu/news/understanding-eupl-v12
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+*/
+
package at.gv.egiz.eaaf.core.impl.idp.process;
import java.io.IOException;
@@ -32,7 +25,6 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
-
import javax.xml.XMLConstants;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLEventReader;
@@ -48,203 +40,225 @@ import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.xml.sax.SAXException;
-
import at.gv.egiz.eaaf.core.impl.idp.process.model.EndEvent;
import at.gv.egiz.eaaf.core.impl.idp.process.model.ProcessDefinition;
import at.gv.egiz.eaaf.core.impl.idp.process.model.ProcessNode;
import at.gv.egiz.eaaf.core.impl.idp.process.model.StartEvent;
import at.gv.egiz.eaaf.core.impl.idp.process.model.TaskInfo;
import at.gv.egiz.eaaf.core.impl.idp.process.model.Transition;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xml.sax.SAXException;
/**
* Parses an XML representation of a process definition as defined by the respective XML schema.
- * <p/
* The parser is thread-safe.
+ *
* @author tknall
*
*/
public class ProcessDefinitionParser {
-
- private static final String NS = "http://reference.e-government.gv.at/namespace/moa/process/definition/v1";
-
- private static Logger log = LoggerFactory.getLogger(ProcessDefinitionParser.class);
-
- private static class LazyProcessDefinitionSchemaHolder {
- private static final Schema PD_SCHEMA_INSTANCE;
- static {
- try (InputStream in = ProcessDefinitionParser.class.getResourceAsStream("/process/ProcessDefinition.xsd")) {
- log.trace("Compiling process definition schema.");
- SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
- // schema is thread-safe
- PD_SCHEMA_INSTANCE = factory.newSchema(new StreamSource(in));
- } catch (Exception e) {
- throw new RuntimeException("Unable to compile process definition schema.", e);
- }
- }
- }
-
- /**
- * Parses an XML representation of a process definition. The representation is being validated in order to suffice
- * the related XML schema.
- *
- * @param processDefinitionInputStream
- * The process definition.
- * @return A new process definition.
- * @throws ProcessDefinitionParserException
- * Thrown in case of error parsing the process definition.
- */
- public ProcessDefinition parse(InputStream processDefinitionInputStream) throws ProcessDefinitionParserException {
- XMLEventReader reader = null;
- final ProcessDefinition pd = new ProcessDefinition();
- log.debug("Parsing and validating process definition.");
- try {
-
- // Standard implementation of XMLInputFactory seems not to be thread-safe
- XMLInputFactory inputFactory = XMLInputFactory.newInstance();
- reader = inputFactory.createXMLEventReader(processDefinitionInputStream);
-
- final List<StartElement> transitionElements = new ArrayList<>();
- final List<StartEvent> startEvents = new ArrayList<>();
-
- reader = new EventReaderDelegate(reader) {
-
- @Override
- public XMLEvent nextEvent() throws XMLStreamException {
- XMLEvent event = super.nextEvent();
-
- switch (event.getEventType()) {
- case XMLStreamConstants.START_ELEMENT:
- StartElement element = event.asStartElement();
- QName qname = element.getName();
-
- if (NS.equals(qname.getNamespaceURI())) {
- log.trace("Found process description element '{}'.", qname.getLocalPart());
- Attribute id = element.getAttributeByName(new QName("id"));
-
- switch (qname.getLocalPart()) {
- case "ProcessDefinition":
- if (id != null) {
- pd.setId(id.getValue());
- }
- break;
- case "StartEvent":
- StartEvent startEvent = new StartEvent();
- if (id != null) {
- startEvent.setId(id.getValue());
- }
- startEvents.add(startEvent);
- break;
- case "EndEvent":
- EndEvent endEvent = new EndEvent();
- if (id != null) {
- endEvent.setId(id.getValue());
- pd.getEndEvents().put(id.getValue(), endEvent);
- }
- break;
- case "Transition":
- transitionElements.add(element);
- break;
- case "Task":
- TaskInfo taskInfo = new TaskInfo();
- if (id != null) {
- taskInfo.setId(id.getValue());
- pd.getTaskInfos().put(id.getValue(), taskInfo);
- }
- Attribute async = element.getAttributeByName(new QName("async"));
- if (async != null) {
- taskInfo.setAsync(Boolean.valueOf(async.getValue()));
- }
- Attribute implementingClass = element.getAttributeByName(new QName("class"));
- if (implementingClass != null) {
- taskInfo.setTaskImplementingClass(implementingClass.getValue());
- }
- break;
- }
-
- }
-
- break;
- }
-
- return event;
- }
-
- };
-
- // validator is not thread-safe
- Validator validator = LazyProcessDefinitionSchemaHolder.PD_SCHEMA_INSTANCE.newValidator();
- validator.validate(new StAXSource(reader));
- log.trace("Process definition successfully schema validated.");
-
- // perform some basic checks
- log.trace("Building model and performing some plausibility checks.");
- if (startEvents.size() != 1) {
- throw new ProcessDefinitionParserException("A ProcessDefinition must contain exactly one single StartEvent.");
- }
- pd.setStartEvent(startEvents.get(0));
-
- // link transitions
- Iterator<StartElement> transitions = transitionElements.iterator();
- while (transitions.hasNext()) {
- StartElement element = transitions.next();
- Transition transition = new Transition();
- Attribute id = element.getAttributeByName(new QName("id"));
- if (id != null) {
- transition.setId(id.getValue());
- }
- Attribute conditionExpression = element.getAttributeByName(new QName("conditionExpression"));
- if (conditionExpression != null) {
- transition.setConditionExpression(conditionExpression.getValue());
- }
- Attribute from = element.getAttributeByName(new QName("from"));
- if (from != null) {
- ProcessNode fromNode = pd.getProcessNode(from.getValue());
- if (fromNode == null) {
- throw new ProcessDefinitionParserException("Transition's 'from'-attribute refers to a non-existing event or task '" + from.getValue() + '.');
- }
- if (fromNode instanceof EndEvent) {
- throw new ProcessDefinitionParserException("Transition cannot start from end event.");
- }
- transition.setFrom(fromNode);
- fromNode.getOutgoingTransitions().add(transition);
- }
- Attribute to = element.getAttributeByName(new QName("to"));
- if (to != null) {
- ProcessNode toNode = pd.getProcessNode(to.getValue());
- if (toNode == null) {
- throw new ProcessDefinitionParserException("Transition's 'to'-attribute refers to a non-existing event or task '" + to.getValue() + '.');
- }
- transition.setTo(toNode);
- toNode.getIncomingTransitions().add(transition);
- }
- if (transition.getConditionExpression() == null && Objects.equals(transition.getFrom(), transition.getTo())) {
- throw new ProcessDefinitionParserException("Transition's 'from' equals its 'to'. Since no 'conditionExpression' has been set this will cause a loop.");
- }
- }
- log.debug("Process definition '{}' successfully parsed.", pd.getId());
- return pd;
-
- } catch (ProcessDefinitionParserException e) {
- throw e;
- } catch (XMLStreamException|IOException e) {
- throw new ProcessDefinitionParserException("Unable to read process definition from inputstream.", e);
- } catch (SAXException e) {
- throw new ProcessDefinitionParserException("Schema validation of process description failed.", e);
- } catch (Exception e) {
- throw new ProcessDefinitionParserException("Internal error creating process definition from inputstream.", e);
- } finally {
- if (reader != null) {
- try {
- reader.close();
- } catch (XMLStreamException e) {
- // error freeing resources
- }
- }
- }
- }
+
+ private static final String NS =
+ "http://reference.e-government.gv.at/namespace/moa/process/definition/v1";
+
+ private static Logger log = LoggerFactory.getLogger(ProcessDefinitionParser.class);
+
+ private static class LazyProcessDefinitionSchemaHolder {
+ private static final Schema PD_SCHEMA_INSTANCE;
+
+ static {
+ try (InputStream in =
+ ProcessDefinitionParser.class.getResourceAsStream("/process/ProcessDefinition.xsd")) {
+ log.trace("Compiling process definition schema.");
+ final SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
+ // schema is thread-safe
+ PD_SCHEMA_INSTANCE = factory.newSchema(new StreamSource(in));
+ } catch (final Exception e) {
+ throw new RuntimeException("Unable to compile process definition schema.", e);
+ }
+ }
+ }
+
+ /**
+ * Parses an XML representation of a process definition. The representation is being validated in
+ * order to suffice the related XML schema.
+ *
+ * @param processDefinitionInputStream The process definition.
+ * @return A new process definition.
+ * @throws ProcessDefinitionParserException Thrown in case of error parsing the process
+ * definition.
+ */
+ public ProcessDefinition parse(final InputStream processDefinitionInputStream)
+ throws ProcessDefinitionParserException {
+ XMLEventReader reader = null;
+ final ProcessDefinition pd = new ProcessDefinition();
+ log.debug("Parsing and validating process definition.");
+ try {
+
+ // Standard implementation of XMLInputFactory seems not to be thread-safe
+ final XMLInputFactory inputFactory = XMLInputFactory.newInstance();
+ reader = inputFactory.createXMLEventReader(processDefinitionInputStream);
+
+ final List<StartElement> transitionElements = new ArrayList<>();
+ final List<StartEvent> startEvents = new ArrayList<>();
+
+ reader = new EventReaderDelegate(reader) {
+
+ @Override
+ public XMLEvent nextEvent() throws XMLStreamException {
+ final XMLEvent event = super.nextEvent();
+
+ switch (event.getEventType()) {
+ case XMLStreamConstants.START_ELEMENT:
+ final StartElement element = event.asStartElement();
+ final QName qname = element.getName();
+
+ if (NS.equals(qname.getNamespaceURI())) {
+ log.trace("Found process description element '{}'.", qname.getLocalPart());
+ final Attribute id = element.getAttributeByName(new QName("id"));
+
+ switch (qname.getLocalPart()) {
+ case "ProcessDefinition":
+ if (id != null) {
+ pd.setId(id.getValue());
+ }
+ break;
+ case "StartEvent":
+ final StartEvent startEvent = new StartEvent();
+ if (id != null) {
+ startEvent.setId(id.getValue());
+ }
+ startEvents.add(startEvent);
+ break;
+ case "EndEvent":
+ final EndEvent endEvent = new EndEvent();
+ if (id != null) {
+ endEvent.setId(id.getValue());
+ pd.getEndEvents().put(id.getValue(), endEvent);
+ }
+ break;
+ case "Transition":
+ transitionElements.add(element);
+ break;
+ case "Task":
+ final TaskInfo taskInfo = new TaskInfo();
+ if (id != null) {
+ taskInfo.setId(id.getValue());
+ pd.getTaskInfos().put(id.getValue(), taskInfo);
+ }
+ final Attribute async = element.getAttributeByName(new QName("async"));
+ if (async != null) {
+ taskInfo.setAsync(Boolean.valueOf(async.getValue()));
+ }
+ final Attribute implementingClass =
+ element.getAttributeByName(new QName("class"));
+ if (implementingClass != null) {
+ taskInfo.setTaskImplementingClass(implementingClass.getValue());
+ }
+ break;
+ default:
+ log.warn("Ignore unknown event: {}", qname);
+ break;
+ }
+
+ }
+
+ break;
+ default:
+ log.warn("Ignore unknown event: {}", event);
+ break;
+ }
+
+ return event;
+ }
+
+ };
+
+ // validator is not thread-safe
+ final Validator validator =
+ LazyProcessDefinitionSchemaHolder.PD_SCHEMA_INSTANCE.newValidator();
+ validator.validate(new StAXSource(reader));
+ log.trace("Process definition successfully schema validated.");
+
+ // perform some basic checks
+ log.trace("Building model and performing some plausibility checks.");
+ if (startEvents.size() != 1) {
+ throw new ProcessDefinitionParserException(
+ "A ProcessDefinition must contain exactly one single StartEvent.");
+ }
+ pd.setStartEvent(startEvents.get(0));
+
+ // link transitions
+ final Iterator<StartElement> transitions = transitionElements.iterator();
+ while (transitions.hasNext()) {
+ final StartElement element = transitions.next();
+ final Transition transition = new Transition();
+ final Attribute id = element.getAttributeByName(new QName("id"));
+ if (id != null) {
+ transition.setId(id.getValue());
+ }
+ final Attribute conditionExpression =
+ element.getAttributeByName(new QName("conditionExpression"));
+ if (conditionExpression != null) {
+ transition.setConditionExpression(conditionExpression.getValue());
+ }
+ final Attribute from = element.getAttributeByName(new QName("from"));
+ if (from != null) {
+ final ProcessNode fromNode = pd.getProcessNode(from.getValue());
+ if (fromNode == null) {
+ throw new ProcessDefinitionParserException(
+ "Transition's 'from'-attribute refers to a non-existing event or task '"
+ + from.getValue() + '.');
+ }
+ if (fromNode instanceof EndEvent) {
+ throw new ProcessDefinitionParserException("Transition cannot start from end event.");
+ }
+ transition.setFrom(fromNode);
+ fromNode.getOutgoingTransitions().add(transition);
+ }
+ final Attribute to = element.getAttributeByName(new QName("to"));
+ if (to != null) {
+ final ProcessNode toNode = pd.getProcessNode(to.getValue());
+ if (toNode == null) {
+ throw new ProcessDefinitionParserException(
+ "Transition's 'to'-attribute refers to a non-existing event or task '"
+ + to.getValue() + '.');
+ }
+ transition.setTo(toNode);
+ toNode.getIncomingTransitions().add(transition);
+ }
+ if (transition.getConditionExpression() == null
+ && Objects.equals(transition.getFrom(), transition.getTo())) {
+ throw new ProcessDefinitionParserException(
+ "Transition's 'from' equals its 'to'. Since no 'conditionExpression' "
+ + "has been set this will cause a loop.");
+ }
+ }
+ log.debug("Process definition '{}' successfully parsed.", pd.getId());
+ return pd;
+
+ } catch (final ProcessDefinitionParserException e) {
+ throw e;
+ } catch (XMLStreamException | IOException e) {
+ throw new ProcessDefinitionParserException(
+ "Unable to read process definition from inputstream.", e);
+ } catch (final SAXException e) {
+ throw new ProcessDefinitionParserException("Schema validation of process description failed.",
+ e);
+ } catch (final Exception e) {
+ throw new ProcessDefinitionParserException(
+ "Internal error creating process definition from inputstream.", e);
+ } finally {
+ if (reader != null) {
+ try {
+ reader.close();
+ } catch (final XMLStreamException e) {
+ e.printStackTrace();
+
+ }
+ }
+ }
+ }
}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ProcessDefinitionParserException.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ProcessDefinitionParserException.java
index 292b3881..472d6469 100644
--- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ProcessDefinitionParserException.java
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ProcessDefinitionParserException.java
@@ -1,61 +1,52 @@
-/*******************************************************************************
- * Copyright 2017 Graz University of Technology
- * EAAF-Core Components has been developed in a cooperation between EGIZ,
- * A-SIT Plus, A-SIT, and Graz University of Technology.
+/*
+ * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a
+ * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology.
*
- * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European
+ * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in
+ * compliance with the Licence. You may obtain a copy of the Licence at:
* https://joinup.ec.europa.eu/news/understanding-eupl-v12
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+*/
+
package at.gv.egiz.eaaf.core.impl.idp.process;
/**
* Exception thrown in case of error parsing a process definition.
- *
+ *
* @author tknall
- *
+ *
*/
public class ProcessDefinitionParserException extends Exception {
- private static final long serialVersionUID = 1L;
+ private static final long serialVersionUID = 1L;
- /**
- * Creates a new parser exception providing a {@code message} describing the reason and the {@code cause}.
- *
- * @param message
- * The message.
- * @param cause
- * The cause.
- */
- public ProcessDefinitionParserException(String message, Throwable cause) {
- super(message, cause);
- }
+ /**
+ * Creates a new parser exception providing a {@code message} describing the reason and the
+ * {@code cause}.
+ *
+ * @param message The message.
+ * @param cause The cause.
+ */
+ public ProcessDefinitionParserException(final String message, final Throwable cause) {
+ super(message, cause);
+ }
- /**
- * Creates a new parser exception providing a {@code message} describing the reason.
- *
- * @param message
- * The message.
- */
- public ProcessDefinitionParserException(String message) {
- super(message);
- }
+ /**
+ * Creates a new parser exception providing a {@code message} describing the reason.
+ *
+ * @param message The message.
+ */
+ public ProcessDefinitionParserException(final String message) {
+ super(message);
+ }
}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ProcessEngineImpl.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ProcessEngineImpl.java
index 53f50e1f..0c4946af 100644
--- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ProcessEngineImpl.java
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ProcessEngineImpl.java
@@ -1,55 +1,39 @@
-/*******************************************************************************
- * Copyright 2017 Graz University of Technology
- * EAAF-Core Components has been developed in a cooperation between EGIZ,
- * A-SIT Plus, A-SIT, and Graz University of Technology.
+/*
+ * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a
+ * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology.
*
- * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European
+ * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in
+ * compliance with the Licence. You may obtain a copy of the Licence at:
* https://joinup.ec.europa.eu/news/understanding-eupl-v12
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+*/
+
package at.gv.egiz.eaaf.core.impl.idp.process;
import java.io.InputStream;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
+import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
-
-import org.apache.commons.collections4.IterableUtils;
-import org.apache.commons.collections4.Predicate;
-import org.apache.commons.lang3.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.slf4j.MDC;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.ApplicationContext;
-
import at.gv.egiz.eaaf.core.api.IRequest;
import at.gv.egiz.eaaf.core.api.data.EAAFConstants;
import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext;
import at.gv.egiz.eaaf.core.api.idp.process.ExpressionEvaluationContext;
import at.gv.egiz.eaaf.core.api.idp.process.ExpressionEvaluator;
import at.gv.egiz.eaaf.core.api.idp.process.ProcessEngine;
-import at.gv.egiz.eaaf.core.api.idp.process.ProcessInstanceStoreDAO;
+import at.gv.egiz.eaaf.core.api.idp.process.ProcessInstanceStoreDao;
import at.gv.egiz.eaaf.core.api.idp.process.Task;
-import at.gv.egiz.eaaf.core.exceptions.EAAFException;
+import at.gv.egiz.eaaf.core.exceptions.EaafException;
import at.gv.egiz.eaaf.core.exceptions.ProcessExecutionException;
import at.gv.egiz.eaaf.core.impl.idp.process.dao.ProcessInstanceStore;
import at.gv.egiz.eaaf.core.impl.idp.process.model.EndEvent;
@@ -58,439 +42,491 @@ import at.gv.egiz.eaaf.core.impl.idp.process.model.ProcessNode;
import at.gv.egiz.eaaf.core.impl.idp.process.model.StartEvent;
import at.gv.egiz.eaaf.core.impl.idp.process.model.TaskInfo;
import at.gv.egiz.eaaf.core.impl.idp.process.model.Transition;
+import org.apache.commons.collections4.IterableUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.slf4j.MDC;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
/**
- * Process engine implementation allowing starting and continuing processes as well as providing means for cleanup actions.
+ * Process engine implementation allowing starting and continuing processes as well as providing
+ * means for cleanup actions.
*/
public class ProcessEngineImpl implements ProcessEngine {
-
- private final Logger log = LoggerFactory.getLogger(getClass());
-
- @Autowired ProcessInstanceStoreDAO piStoreDao;
- @Autowired ApplicationContext context;
-
- private final ProcessDefinitionParser pdp = new ProcessDefinitionParser();
-
- private final Map<String, ProcessDefinition> processDefinitions = new ConcurrentHashMap<String, ProcessDefinition>();
-
- private final static String MDC_CTX_PI_NAME = "processInstanceId";
- private final static String MDC_CTX_TASK_NAME = "taskId";
-
- private ExpressionEvaluator transitionConditionExpressionEvaluator;
-
- @Override
- public void registerProcessDefinition(ProcessDefinition processDefinition) {
- log.info("Registering process definition '{}'.", processDefinition.getId());
- processDefinitions.put(processDefinition.getId(), processDefinition);
- }
-
- @Override
- public String registerProcessDefinition(InputStream processDefinitionInputStream) throws ProcessDefinitionParserException{
- final ProcessDefinition pd = pdp.parse(processDefinitionInputStream);
-
- postValidationOfProcessDefintion(pd);
-
- registerProcessDefinition(pd);
- return pd.getId();
- }
-
- /**
- * Sets the process definitions.
- *
- * @param processDefinitions
- * The process definitions.
- * @throws IllegalArgumentException
- * In case the process definitions contain definitions with the same identifier.
- */
- public void setProcessDefinitions(Iterable<ProcessDefinition> processDefinitions) {
- this.processDefinitions.clear();
- for (final ProcessDefinition pd : processDefinitions) {
- if (this.processDefinitions.containsKey(pd.getId())) {
- throw new IllegalArgumentException("Duplicate process definition identifier '" + pd.getId() + "'.");
- }
- registerProcessDefinition(pd);
- }
- }
-
- /**
- * Sets an expression evaluator that should be used to process transition condition expressions.
- * @param transitionConditionExpressionEvaluator The expression evaluator.
- */
- public void setTransitionConditionExpressionEvaluator(
- ExpressionEvaluator transitionConditionExpressionEvaluator) {
- this.transitionConditionExpressionEvaluator = transitionConditionExpressionEvaluator;
- }
-
-
- @Override
- public String createProcessInstance(String processDefinitionId, ExecutionContext executionContext) throws ProcessExecutionException {
- // look for respective process definition
- final ProcessDefinition pd = processDefinitions.get(processDefinitionId);
- if (pd == null) {
- throw new ProcessExecutionException("Unable to find process definition for process '" + processDefinitionId + "'.");
- }
- // create and keep process instance
- final ProcessInstance pi = new ProcessInstance(pd, executionContext);
- log.info("Creating process instance from process definition '{}': {}", processDefinitionId, pi.getId());
-
- try {
- saveOrUpdateProcessInstance(pi);
-
- } catch (final EAAFException e) {
- throw new ProcessExecutionException("Unable to persist process instance.", e);
- }
-
- return pi.getId();
- }
-
- @Override
- public String createProcessInstance(String processDefinitionId) throws ProcessExecutionException {
- return createProcessInstance(processDefinitionId, null);
- }
-
- @Override
- public void start(IRequest pendingReq) throws ProcessExecutionException {
- try {
- if (StringUtils.isEmpty(pendingReq.getProcessInstanceId())) {
- log.error("Pending-request with id:" + pendingReq.getPendingRequestId()
- + " includes NO 'ProcessInstanceId'");
- throw new ProcessExecutionException("Pending-request with id:" + pendingReq.getPendingRequestId()
- + " includes NO 'ProcessInstanceId'");
- }
-
- final ProcessInstance pi = loadProcessInstance(pendingReq.getProcessInstanceId());
-
- if (pi == null ) {
- throw new ProcessExecutionException("Process instance '" + pendingReq.getProcessInstanceId() + "' does not exist.");
-
- }
-
- MDC.put(MDC_CTX_PI_NAME, pi.getId());
-
- if (!ProcessInstanceState.NOT_STARTED.equals(pi.getState())) {
- throw new ProcessExecutionException("Process instance '" + pi.getId() + "' has already been started (current state is " + pi.getState() + ").");
- }
- log.info("Starting process instance '{}'.", pi.getId());
- // execute process
- pi.setState(ProcessInstanceState.STARTED);
- execute(pi, pendingReq);
-
- //store ProcessInstance if it is not already ended
- if (!ProcessInstanceState.ENDED.equals(pi.getState()))
- saveOrUpdateProcessInstance(pi);
-
- } catch (final EAAFException e) {
- throw new ProcessExecutionException("Unable to load/save process instance.", e);
-
- } finally {
- MDC.remove(MDC_CTX_PI_NAME);
- }
- }
-
- @Override
- public void signal(IRequest pendingReq) throws ProcessExecutionException {
-
- try {
- if (StringUtils.isEmpty(pendingReq.getProcessInstanceId())) {
- log.error("Pending-request with id:" + pendingReq.getPendingRequestId()
- + " includes NO 'ProcessInstanceId'");
- throw new ProcessExecutionException("Pending-request with id:" + pendingReq.getPendingRequestId()
- + " includes NO 'ProcessInstanceId'");
- }
-
- final ProcessInstance pi = loadProcessInstance(pendingReq.getProcessInstanceId());
-
- if (pi == null ) {
- throw new ProcessExecutionException("Process instance '" + pendingReq.getProcessInstanceId() + "' does not exist.");
-
- }
-
- MDC.put(MDC_CTX_PI_NAME, pi.getId());
-
- if (!ProcessInstanceState.SUSPENDED.equals(pi.getState())) {
- throw new ProcessExecutionException("Process instance '" + pi.getId() + "' has not been suspended (current state is " + pi.getState() + ").");
- }
-
- log.debug("Waking up process instance '{}'.", pi.getId());
- pi.setState(ProcessInstanceState.STARTED);
-
- //put pending-request ID on execution-context because it could be changed
- pi.getExecutionContext().put(EAAFConstants.PARAM_HTTP_TARGET_PENDINGREQUESTID, pendingReq.getPendingRequestId());
-
- execute(pi, pendingReq);
-
- //store ProcessInstance if it is not already ended
- if (!ProcessInstanceState.ENDED.equals(pi.getState()))
- saveOrUpdateProcessInstance(pi);
-
- } catch (final EAAFException e) {
- throw new ProcessExecutionException("Unable to load/save process instance.", e);
-
- } finally {
- MDC.remove(MDC_CTX_PI_NAME);
- }
- }
-
-
- /**
- * Instantiates a task implementation given by a {@link TaskInfo}.
- * @param ti The task info.
- * @return A Task implementation or {@code null} if the task info does not reference any task implementing classes.
- * @throws ProcessExecutionException Thrown in case of error (when the referenced class does not implement {@link Task} for instance).
- */
- private Task createTaskInstance(TaskInfo ti) throws ProcessExecutionException {
- final String clazz = StringUtils.trimToNull(ti.getTaskImplementingClass());
- Task task = null;
-
- if (clazz != null) {
- log.debug("Instantiating task implementing class '{}'.", clazz);
- Object instanceClass = null;
- try {
- instanceClass = context.getBean(clazz);
-
- } catch (final Exception e) {
- throw new ProcessExecutionException("Unable to get class '" + clazz + "' associated with task '" + ti.getId() + "' .", e);
-
- }
- if (instanceClass == null || !(instanceClass instanceof Task)) {
- throw new ProcessExecutionException("Class '" + clazz + "' associated with task '" + ti.getId() + "' is not assignable to " + Task.class.getName() + ".");
-
- }
- try {
- task = (Task) instanceClass;
-
- } catch (final Exception e) {
- throw new ProcessExecutionException("Unable to instantiate class '" + clazz + "' associated with task '" + ti.getId() + "' .", e);
- }
- }
-
- return task;
- }
-
- /**
- * Starts/executes a given process instance.
- * @param pi The process instance.
- * @param pendingReq
- * @throws ProcessExecutionException Thrown in case of error.
- */
- private void execute(final ProcessInstance pi, IRequest pendingReq) throws ProcessExecutionException {
- if (ProcessInstanceState.ENDED.equals(pi.getState())) {
- throw new ProcessExecutionException("Process for instance '" + pi.getId() + "' has already been ended.");
- }
- final ProcessDefinition pd = pi.getProcessDefinition();
- final ProcessNode processNode = pd.getProcessNode(pi.getNextId());
- log.debug("Processing node '{}'.", processNode.getId());
-
- // distinguish process node types StartEvent, TaskInfo and EndEvent
-
- if (processNode instanceof TaskInfo) {
- // TaskInfo types need to be executed
- final TaskInfo ti = (TaskInfo) processNode;
- MDC.put(MDC_CTX_TASK_NAME, ti.getId());
- try {
- log.debug("Processing task '{}'.", ti.getId());
- final Task task = createTaskInstance(ti);
- if (task != null) {
- try {
- log.debug("Executing task implementation for task '{}'.", ti.getId());
- log.trace("Execution context before task execution: {}", pi.getExecutionContext().keySet());
- pendingReq = task.execute(pendingReq, pi.getExecutionContext());
- log.debug("Returned from execution of task '{}'.", ti.getId());
- log.trace("Execution context after task execution: {}", pi.getExecutionContext().keySet());
-
- } catch (final Throwable t) {
- throw new ProcessExecutionException("Error executing task '" + ti.getId() + "'.", t);
-
- }
-
- //check if process was cancelled dynamically by task
- if (pi.getExecutionContext().isProcessCancelled()) {
- log.debug("Processing task '{}' was cancelled by Task: '{}'.", pi.getId(), ti.getId());
- processFinishEvent(pi);
- return;
-
- }
-
- } else {
- log.debug("No task implementing class set.");
-
- }
- } finally {
- MDC.remove(MDC_CTX_TASK_NAME);
-
- }
-
- } else if (processNode instanceof EndEvent) {
- processFinishEvent(pi);
- return;
-
- }
-
- final ExpressionEvaluationContext expressionContext = new ExpressionEvaluationContextImpl(pi);
-
- // traverse pointer
- final Transition t = IterableUtils.find(processNode.getOutgoingTransitions(), new Predicate<Transition>() {
- @Override
- public boolean evaluate(Transition transition) {
- if (transitionConditionExpressionEvaluator != null && transition.getConditionExpression() != null) {
- log.trace("Evaluating transition expression '{}'.", transition.getConditionExpression());
- return transitionConditionExpressionEvaluator.evaluate(expressionContext, transition.getConditionExpression());
- }
- return true;
- }
- });
- if (t == null) {
- throw new ProcessExecutionException("No valid transition starting from process node '" + processNode.getId()+ "'.");
- }
- log.trace("Found suitable transition: {}", t);
- // update pointer
- log.trace("Shifting process token from '{}' to '{}'.", pi.getNextId(), t.getTo().getId());
- pi.setNextId(t.getTo().getId());
-
- // inspect current task
- if (t.getTo() instanceof TaskInfo && (((TaskInfo) t.getTo()).isAsync())) {
- // immediately return in case of asynchonous task
- log.debug("Suspending process instance '{}' for asynchronous task '{}'.", pi.getId(), t.getTo().getId());
- pi.setState(ProcessInstanceState.SUSPENDED);
- return;
- }
-
- // continue execution in case of StartEvent or Task
- if (processNode instanceof StartEvent || processNode instanceof TaskInfo) {
- execute(pi, pendingReq);
- }
- }
-
- @Override
- public ProcessInstance getProcessInstance(String processInstanceId) {
-
- ProcessInstance processInstance;
- try {
- processInstance = loadProcessInstance(processInstanceId);
-
- } catch (final EAAFException e) {
- throw new RuntimeException("The process instance '" + processInstanceId + "' could not be retrieved.", e);
- }
-
- if (processInstance == null) {
- throw new IllegalArgumentException("The process instance '" + processInstanceId + "' does not/no longer exist.");
- }
-
- return processInstance;
- }
-
- /**
- * Persists a {@link ProcessInstance} to the database.
- * @param processInstance The object to persist.
- * @throws MOADatabaseException Thrown if an error occurs while accessing the database.
- */
- private void saveOrUpdateProcessInstance(ProcessInstance processInstance) throws EAAFException {
- final ProcessInstanceStore store = new ProcessInstanceStore();
-
- final ExecutionContext ctx = processInstance.getExecutionContext();
-
- final Map<String, Serializable> ctxData = new HashMap<String, Serializable>();
- for (final String key : ctx.keySet()) {
- ctxData.put(key, ctx.get(key));
- }
- store.setExecutionContextData(ctxData);
-
- store.setNextTaskId(processInstance.getNextId());
- store.setProcessDefinitionId(processInstance.getProcessDefinition().getId());
-
- store.setProcessInstanceId(processInstance.getId());
- store.setProcessState(processInstance.getState());
-
- piStoreDao.saveOrUpdate(store);
- }
-
- /**
- * Load a {@link ProcessInstance} with a certain id from the database.
- * @param processInstanceId The process instance id
- * @return The process instance corresponding to the id or {@code null} if no such object is found.
- * @throws MOADatabaseException Thrown if an error occurs while accessing the database.
- */
- private ProcessInstance loadProcessInstance(String processInstanceId) throws EAAFException {
-
- final ProcessInstanceStore piStore = piStoreDao.load(processInstanceId);
-
- if (piStore == null) {
- return null;
- }
-
- final ExecutionContext executionContext = new ExecutionContextImpl(piStore.getProcessInstanceId());
-
- final Map<String, Serializable> executionContextData = piStore.getExecutionContextData();
- for (final String key : executionContextData.keySet()) {
- executionContext.put(key, executionContextData.get(key));
- }
-
- final ProcessInstance pi = new ProcessInstance(processDefinitions.get(piStore.getProcessDefinitionId()), executionContext);
- pi.setNextId(piStore.getNextTaskId());
- pi.setState(piStore.getProcessState());
-
- return pi;
- }
-
- /* (non-Javadoc)
- * @see at.gv.egovernment.moa.id.process.ProcessEngine#deleteProcessInstance(java.lang.String)
- */
- @Override
- public void deleteProcessInstance(String processInstanceId) throws ProcessExecutionException {
- if (StringUtils.isEmpty(processInstanceId)) {
- throw new ProcessExecutionException("Unable to remove process instance: ProcessInstanceId is empty");
-
- }
-
- try {
- piStoreDao.remove(processInstanceId);
-
- } catch (final EAAFException e) {
- throw new ProcessExecutionException("Unable to remove process instance.", e);
-
- }
-
- }
-
- /**
- * Finish a process-flow and remove any process-flow related information
- *
- * @param pi
- * @throws ProcessExecutionException
- */
- private void processFinishEvent(ProcessInstance pi) throws ProcessExecutionException {
- log.info("Finishing process instance '{}'.", pi.getId());
-
- try {
- piStoreDao.remove(pi.getId());
-
- } catch (final EAAFException e) {
- throw new ProcessExecutionException("Unable to remove process instance.", e);
-
- }
- pi.setState(ProcessInstanceState.ENDED);
- log.debug("Final process context: {}", pi.getExecutionContext().keySet());
-
- }
-
- /**
- * Perform some post-validation operations on process definition
- *
- * Like: check if all tasks that are defined are available on context
- *
- * @param pd
- * @throws ProcessDefinitionParserException
- */
- private void postValidationOfProcessDefintion(ProcessDefinition pd) throws ProcessDefinitionParserException{
- try {
- for(final TaskInfo task : pd.getTaskInfos().values()) {
- createTaskInstance(task);
- }
-
- } catch (final ProcessExecutionException e) {
- log.error("Post-validation of process definition: {} find an error: {}", pd.getId(), e.getMessage());
- throw new ProcessDefinitionParserException("Post-validation find an error in process definition:" + pd.getId(), e);
-
- }
- }
+
+ private final Logger log = LoggerFactory.getLogger(getClass());
+
+ @Autowired
+ ProcessInstanceStoreDao piStoreDao;
+ @Autowired
+ ApplicationContext context;
+
+ private final ProcessDefinitionParser pdp = new ProcessDefinitionParser();
+
+ private final Map<String, ProcessDefinition> processDefinitions = new ConcurrentHashMap<>();
+
+ private static final String MDC_CTX_PI_NAME = "processInstanceId";
+ private static final String MDC_CTX_TASK_NAME = "taskId";
+
+ private ExpressionEvaluator transitionConditionExpressionEvaluator;
+
+ @Override
+ public void registerProcessDefinition(final ProcessDefinition processDefinition) {
+ log.info("Registering process definition '{}'.", processDefinition.getId());
+ processDefinitions.put(processDefinition.getId(), processDefinition);
+ }
+
+ @Override
+ public String registerProcessDefinition(final InputStream processDefinitionInputStream)
+ throws ProcessDefinitionParserException {
+ final ProcessDefinition pd = pdp.parse(processDefinitionInputStream);
+
+ postValidationOfProcessDefintion(pd);
+
+ registerProcessDefinition(pd);
+ return pd.getId();
+ }
+
+ /**
+ * Sets the process definitions.
+ *
+ * @param processDefinitions The process definitions.
+ * @throws IllegalArgumentException In case the process definitions contain definitions with the
+ * same identifier.
+ */
+ public void setProcessDefinitions(final Iterable<ProcessDefinition> processDefinitions) {
+ this.processDefinitions.clear();
+ for (final ProcessDefinition pd : processDefinitions) {
+ if (this.processDefinitions.containsKey(pd.getId())) {
+ throw new IllegalArgumentException(
+ "Duplicate process definition identifier '" + pd.getId() + "'.");
+ }
+ registerProcessDefinition(pd);
+ }
+ }
+
+ /**
+ * Sets an expression evaluator that should be used to process transition condition expressions.
+ *
+ * @param transitionConditionExpressionEvaluator The expression evaluator.
+ */
+ public void setTransitionConditionExpressionEvaluator(
+ final ExpressionEvaluator transitionConditionExpressionEvaluator) {
+ this.transitionConditionExpressionEvaluator = transitionConditionExpressionEvaluator;
+ }
+
+
+ @Override
+ public String createProcessInstance(final String processDefinitionId,
+ final ExecutionContext executionContext) throws ProcessExecutionException {
+ // look for respective process definition
+ final ProcessDefinition pd = processDefinitions.get(processDefinitionId);
+ if (pd == null) {
+ throw new ProcessExecutionException(
+ "Unable to find process definition for process '" + processDefinitionId + "'.");
+ }
+ // create and keep process instance
+ final ProcessInstance pi = new ProcessInstance(pd, executionContext);
+ log.info("Creating process instance from process definition '{}': {}", processDefinitionId,
+ pi.getId());
+
+ try {
+ saveOrUpdateProcessInstance(pi);
+
+ } catch (final EaafException e) {
+ throw new ProcessExecutionException("Unable to persist process instance.", e);
+ }
+
+ return pi.getId();
+ }
+
+ @Override
+ public String createProcessInstance(final String processDefinitionId)
+ throws ProcessExecutionException {
+ return createProcessInstance(processDefinitionId, null);
+ }
+
+ @Override
+ public void start(final IRequest pendingReq) throws ProcessExecutionException {
+ try {
+ if (StringUtils.isEmpty(pendingReq.getProcessInstanceId())) {
+ log.error("Pending-request with id:" + pendingReq.getPendingRequestId()
+ + " includes NO 'ProcessInstanceId'");
+ throw new ProcessExecutionException("Pending-request with id:"
+ + pendingReq.getPendingRequestId() + " includes NO 'ProcessInstanceId'");
+ }
+
+ final ProcessInstance pi = loadProcessInstance(pendingReq.getProcessInstanceId());
+
+ if (pi == null) {
+ throw new ProcessExecutionException(
+ "Process instance '" + pendingReq.getProcessInstanceId() + "' does not exist.");
+
+ }
+
+ MDC.put(MDC_CTX_PI_NAME, pi.getId());
+
+ if (!ProcessInstanceState.NOT_STARTED.equals(pi.getState())) {
+ throw new ProcessExecutionException("Process instance '" + pi.getId()
+ + "' has already been started (current state is " + pi.getState() + ").");
+ }
+ log.info("Starting process instance '{}'.", pi.getId());
+ // execute process
+ pi.setState(ProcessInstanceState.STARTED);
+ execute(pi, pendingReq);
+
+ // store ProcessInstance if it is not already ended
+ if (!ProcessInstanceState.ENDED.equals(pi.getState())) {
+ saveOrUpdateProcessInstance(pi);
+ }
+
+ } catch (final EaafException e) {
+ throw new ProcessExecutionException("Unable to load/save process instance.", e);
+
+ } finally {
+ MDC.remove(MDC_CTX_PI_NAME);
+ }
+ }
+
+ @Override
+ public void signal(final IRequest pendingReq) throws ProcessExecutionException {
+
+ try {
+ if (StringUtils.isEmpty(pendingReq.getProcessInstanceId())) {
+ log.error("Pending-request with id:" + pendingReq.getPendingRequestId()
+ + " includes NO 'ProcessInstanceId'");
+ throw new ProcessExecutionException("Pending-request with id:"
+ + pendingReq.getPendingRequestId() + " includes NO 'ProcessInstanceId'");
+ }
+
+ final ProcessInstance pi = loadProcessInstance(pendingReq.getProcessInstanceId());
+
+ if (pi == null) {
+ throw new ProcessExecutionException(
+ "Process instance '" + pendingReq.getProcessInstanceId() + "' does not exist.");
+
+ }
+
+ MDC.put(MDC_CTX_PI_NAME, pi.getId());
+
+ if (!ProcessInstanceState.SUSPENDED.equals(pi.getState())) {
+ throw new ProcessExecutionException("Process instance '" + pi.getId()
+ + "' has not been suspended (current state is " + pi.getState() + ").");
+ }
+
+ log.debug("Waking up process instance '{}'.", pi.getId());
+ pi.setState(ProcessInstanceState.STARTED);
+
+ // put pending-request ID on execution-context because it could be changed
+ pi.getExecutionContext().put(EAAFConstants.PARAM_HTTP_TARGET_PENDINGREQUESTID,
+ pendingReq.getPendingRequestId());
+
+ execute(pi, pendingReq);
+
+ // store ProcessInstance if it is not already ended
+ if (!ProcessInstanceState.ENDED.equals(pi.getState())) {
+ saveOrUpdateProcessInstance(pi);
+ }
+
+ } catch (final EaafException e) {
+ throw new ProcessExecutionException("Unable to load/save process instance.", e);
+
+ } finally {
+ MDC.remove(MDC_CTX_PI_NAME);
+ }
+ }
+
+
+ /**
+ * Instantiates a task implementation given by a {@link TaskInfo}.
+ *
+ * @param ti The task info.
+ * @return A Task implementation or {@code null} if the task info does not reference any task
+ * implementing classes.
+ * @throws ProcessExecutionException Thrown in case of error (when the referenced class does not
+ * implement {@link Task} for instance).
+ */
+ private Task createTaskInstance(final TaskInfo ti) throws ProcessExecutionException {
+ final String clazz = StringUtils.trimToNull(ti.getTaskImplementingClass());
+ Task task = null;
+
+ if (clazz != null) {
+ log.debug("Instantiating task implementing class '{}'.", clazz);
+ Object instanceClass = null;
+ try {
+ instanceClass = context.getBean(clazz);
+
+ } catch (final Exception e) {
+ throw new ProcessExecutionException(
+ "Unable to get class '" + clazz + "' associated with task '" + ti.getId() + "' .", e);
+
+ }
+ if (instanceClass == null || !(instanceClass instanceof Task)) {
+ throw new ProcessExecutionException("Class '" + clazz + "' associated with task '"
+ + ti.getId() + "' is not assignable to " + Task.class.getName() + ".");
+
+ }
+ try {
+ task = (Task) instanceClass;
+
+ } catch (final Exception e) {
+ throw new ProcessExecutionException("Unable to instantiate class '" + clazz
+ + "' associated with task '" + ti.getId() + "' .", e);
+ }
+ }
+
+ return task;
+ }
+
+ /**
+ * Starts/executes a given process instance.
+ *
+ * @param pi The process instance.
+ * @param pendingReq current pending request
+ * @throws ProcessExecutionException Thrown in case of error.
+ */
+ private void execute(final ProcessInstance pi, IRequest pendingReq)
+ throws ProcessExecutionException {
+ if (ProcessInstanceState.ENDED.equals(pi.getState())) {
+ throw new ProcessExecutionException(
+ "Process for instance '" + pi.getId() + "' has already been ended.");
+ }
+ final ProcessDefinition pd = pi.getProcessDefinition();
+ final ProcessNode processNode = pd.getProcessNode(pi.getNextId());
+ log.debug("Processing node '{}'.", processNode.getId());
+
+ // distinguish process node types StartEvent, TaskInfo and EndEvent
+
+ if (processNode instanceof TaskInfo) {
+ // TaskInfo types need to be executed
+ final TaskInfo ti = (TaskInfo) processNode;
+ MDC.put(MDC_CTX_TASK_NAME, ti.getId());
+ try {
+ log.debug("Processing task '{}'.", ti.getId());
+ final Task task = createTaskInstance(ti);
+ if (task != null) {
+ try {
+ log.debug("Executing task implementation for task '{}'.", ti.getId());
+ log.trace("Execution context before task execution: {}",
+ pi.getExecutionContext().keySet());
+ pendingReq = task.execute(pendingReq, pi.getExecutionContext());
+ log.debug("Returned from execution of task '{}'.", ti.getId());
+ log.trace("Execution context after task execution: {}",
+ pi.getExecutionContext().keySet());
+
+ } catch (final Throwable t) {
+ throw new ProcessExecutionException("Error executing task '" + ti.getId() + "'.", t);
+
+ }
+
+ // check if process was cancelled dynamically by task
+ if (pi.getExecutionContext().isProcessCancelled()) {
+ log.debug("Processing task '{}' was cancelled by Task: '{}'.", pi.getId(), ti.getId());
+ processFinishEvent(pi);
+ return;
+
+ }
+
+ } else {
+ log.debug("No task implementing class set.");
+
+ }
+ } finally {
+ MDC.remove(MDC_CTX_TASK_NAME);
+
+ }
+
+ } else if (processNode instanceof EndEvent) {
+ processFinishEvent(pi);
+ return;
+
+ }
+
+ final ExpressionEvaluationContext expressionContext = new ExpressionEvaluationContextImpl(pi);
+
+ // traverse pointer
+ final Transition t = IterableUtils.find(processNode.getOutgoingTransitions(), transition -> {
+ if (transitionConditionExpressionEvaluator != null
+ && transition.getConditionExpression() != null) {
+ log.trace("Evaluating transition expression '{}'.", transition.getConditionExpression());
+ return transitionConditionExpressionEvaluator.evaluate(expressionContext,
+ transition.getConditionExpression());
+ }
+ return true;
+ });
+ if (t == null) {
+ throw new ProcessExecutionException(
+ "No valid transition starting from process node '" + processNode.getId() + "'.");
+ }
+ log.trace("Found suitable transition: {}", t);
+ // update pointer
+ log.trace("Shifting process token from '{}' to '{}'.", pi.getNextId(), t.getTo().getId());
+ pi.setNextId(t.getTo().getId());
+
+ // inspect current task
+ if (t.getTo() instanceof TaskInfo && (((TaskInfo) t.getTo()).isAsync())) {
+ // immediately return in case of asynchonous task
+ log.debug("Suspending process instance '{}' for asynchronous task '{}'.", pi.getId(),
+ t.getTo().getId());
+ pi.setState(ProcessInstanceState.SUSPENDED);
+ return;
+ }
+
+ // continue execution in case of StartEvent or Task
+ if (processNode instanceof StartEvent || processNode instanceof TaskInfo) {
+ execute(pi, pendingReq);
+ }
+ }
+
+ @Override
+ public ProcessInstance getProcessInstance(final String processInstanceId) {
+
+ ProcessInstance processInstance;
+ try {
+ processInstance = loadProcessInstance(processInstanceId);
+
+ } catch (final EaafException e) {
+ throw new RuntimeException(
+ "The process instance '" + processInstanceId + "' could not be retrieved.", e);
+ }
+
+ if (processInstance == null) {
+ throw new IllegalArgumentException(
+ "The process instance '" + processInstanceId + "' does not/no longer exist.");
+ }
+
+ return processInstance;
+ }
+
+ /**
+ * Persists a {@link ProcessInstance} to the database.
+ *
+ * @param processInstance The object to persist.
+ * @throws MOADatabaseException Thrown if an error occurs while accessing the database.
+ */
+ private void saveOrUpdateProcessInstance(final ProcessInstance processInstance)
+ throws EaafException {
+ final ProcessInstanceStore store = new ProcessInstanceStore();
+
+ final ExecutionContext ctx = processInstance.getExecutionContext();
+
+ final Map<String, Serializable> ctxData = new HashMap<>();
+ for (final String key : ctx.keySet()) {
+ ctxData.put(key, ctx.get(key));
+ }
+ store.setExecutionContextData(ctxData);
+
+ store.setNextTaskId(processInstance.getNextId());
+ store.setProcessDefinitionId(processInstance.getProcessDefinition().getId());
+
+ store.setProcessInstanceId(processInstance.getId());
+ store.setProcessState(processInstance.getState());
+
+ piStoreDao.saveOrUpdate(store);
+ }
+
+ /**
+ * Load a {@link ProcessInstance} with a certain id from the database.
+ *
+ * @param processInstanceId The process instance id
+ * @return The process instance corresponding to the id or {@code null} if no such object is
+ * found.
+ * @throws MOADatabaseException Thrown if an error occurs while accessing the database.
+ */
+ private ProcessInstance loadProcessInstance(final String processInstanceId) throws EaafException {
+
+ final ProcessInstanceStore piStore = piStoreDao.load(processInstanceId);
+
+ if (piStore == null) {
+ return null;
+ }
+
+ final ExecutionContext executionContext =
+ new ExecutionContextImpl(piStore.getProcessInstanceId());
+
+ final Map<String, Serializable> executionContextData = piStore.getExecutionContextData();
+ for (final Entry<String, Serializable> el : executionContextData.entrySet()) {
+ executionContext.put(el.getKey(), el.getValue());
+ }
+
+ final ProcessInstance pi = new ProcessInstance(
+ processDefinitions.get(piStore.getProcessDefinitionId()), executionContext);
+ pi.setNextId(piStore.getNextTaskId());
+ pi.setState(piStore.getProcessState());
+
+ return pi;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egovernment.moa.id.process.ProcessEngine#deleteProcessInstance(java.lang.String)
+ */
+ @Override
+ public void deleteProcessInstance(final String processInstanceId)
+ throws ProcessExecutionException {
+ if (StringUtils.isEmpty(processInstanceId)) {
+ throw new ProcessExecutionException(
+ "Unable to remove process instance: ProcessInstanceId is empty");
+
+ }
+
+ try {
+ piStoreDao.remove(processInstanceId);
+
+ } catch (final EaafException e) {
+ throw new ProcessExecutionException("Unable to remove process instance.", e);
+
+ }
+
+ }
+
+ /**
+ * Finish a process-flow and remove any process-flow related information.
+ *
+ * @param pi current process instance
+ * @throws ProcessExecutionException In case of an process error
+ */
+ private void processFinishEvent(final ProcessInstance pi) throws ProcessExecutionException {
+ log.info("Finishing process instance '{}'.", pi.getId());
+
+ try {
+ piStoreDao.remove(pi.getId());
+
+ } catch (final EaafException e) {
+ throw new ProcessExecutionException("Unable to remove process instance.", e);
+
+ }
+ pi.setState(ProcessInstanceState.ENDED);
+ log.debug("Final process context: {}", pi.getExecutionContext().keySet());
+
+ }
+
+ /**
+ * Perform some post-validation operations on process definition.
+ *
+ * <p>
+ * Like: check if all tasks that are defined are available on context
+ * </p>
+ *
+ * @param pd current process definition
+ * @throws ProcessDefinitionParserException In case of a parser error
+ */
+ private void postValidationOfProcessDefintion(final ProcessDefinition pd)
+ throws ProcessDefinitionParserException {
+ try {
+ for (final TaskInfo task : pd.getTaskInfos().values()) {
+ createTaskInstance(task);
+ }
+
+ } catch (final ProcessExecutionException e) {
+ log.error("Post-validation of process definition: {} find an error: {}", pd.getId(),
+ e.getMessage());
+ throw new ProcessDefinitionParserException(
+ "Post-validation find an error in process definition:" + pd.getId(), e);
+
+ }
+ }
}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ProcessInstance.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ProcessInstance.java
index 6db1dc7d..69683529 100644
--- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ProcessInstance.java
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ProcessInstance.java
@@ -1,190 +1,185 @@
-/*******************************************************************************
- * Copyright 2017 Graz University of Technology
- * EAAF-Core Components has been developed in a cooperation between EGIZ,
- * A-SIT Plus, A-SIT, and Graz University of Technology.
+/*
+ * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a
+ * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology.
*
- * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European
+ * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in
+ * compliance with the Licence. You may obtain a copy of the Licence at:
* https://joinup.ec.europa.eu/news/understanding-eupl-v12
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+*/
+
package at.gv.egiz.eaaf.core.impl.idp.process;
import java.io.Serializable;
import java.util.Date;
-
+import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext;
+import at.gv.egiz.eaaf.core.impl.idp.process.model.ProcessDefinition;
+import at.gv.egiz.eaaf.core.impl.idp.process.support.SecureRandomHolder;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.time.DurationFormatUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext;
-import at.gv.egiz.eaaf.core.impl.idp.process.model.ProcessDefinition;
-import at.gv.egiz.eaaf.core.impl.idp.process.support.SecureRandomHolder;
-
/**
- * Represents a process being executed. The process instance provides information about the process and its state.
- *
+ * Represents a process being executed. The process instance provides information about the process
+ * and its state.
+ *
* @author tknall
- *
+ *
*/
public class ProcessInstance implements Serializable {
- private static final long serialVersionUID = 1L;
- private static final int RND_ID_LENGTH = 22;
-
- private final ProcessDefinition processDefinition;
- private String nextId;
- private Date lru;
- private final ExecutionContext executionContext;
- private ProcessInstanceState state = ProcessInstanceState.NOT_STARTED;
-
- private final Logger log = LoggerFactory.getLogger(getClass());
-
- /**
- * Creates a new process instance, based on a given process definition and a
- * given execution context. If the given execution context is {@code null} a new execution context will be created.<p/>
- * The process instance id of the execution context will be newly generated if it is {@code null} in the execution context.
- *
- * @param processDefinition
- * The process definition.
- * @param executionContext
- * The execution context (may be {@code null}). If {@code null} a new execution context will be created internally.
- */
- ProcessInstance(ProcessDefinition processDefinition, ExecutionContext executionContext) {
- this.processDefinition = processDefinition;
- nextId = processDefinition.getStartEvent().getId();
- if (executionContext == null) {
- executionContext = new ExecutionContextImpl();
- }
- if (executionContext.getProcessInstanceId() == null) {
- final String pdIdLocalPart = RandomStringUtils.random(RND_ID_LENGTH, 0, 0, true, true, null,
- SecureRandomHolder.getInstance());
- executionContext.setProcessInstanceId(this.processDefinition.getId() + "-" + pdIdLocalPart);
- } else {
- log.debug("Using process instance id from execution context.");
- }
- log.debug("Creating process instance with id '{}'.", executionContext.getProcessInstanceId());
- this.executionContext = executionContext;
- touch();
- }
-
- /**
- * Returns the underlying process definition.
- *
- * @return The underlying process definition.
- */
- ProcessDefinition getProcessDefinition() {
- touch();
- return processDefinition;
- }
-
- /**
- * Returns the id of the process node to be executed next.
- *
- * @return The process node pointer indicating the process node to be executed next.
- */
- public String getNextId() {
- touch();
- return nextId;
- }
-
- /**
- * Sets the internal pointer to the process node to be executed next.
- *
- * @param nextId
- * The process node id to be executed next.
- */
- void setNextId(String nextId) {
- touch();
- this.nextId = nextId;
- }
-
- /**
- * Returns the current state of the process instance.
- *
- * @return The current state.
- */
- public ProcessInstanceState getState() {
- touch();
- return state;
- }
-
- /**
- * Sets the current state of the process instance.
- *
- * @param state
- * The current state.
- */
- void setState(ProcessInstanceState state) {
- touch();
- this.state = state;
- }
-
- public String getId() {
- touch();
- return executionContext.getProcessInstanceId();
- }
-
- /**
- * Updates the last recently used date of the process instance.
- */
- private void touch() {
- lru = new Date();
- }
-
- /**
- * Returns the date the process instance has been accessed last.
- *
- * @return The last recently used date.
- */
- Date getLru() {
- return lru;
- }
-
- /**
- * Returns the associated execution context.
- * @return The execution context (never {@code null}).
- */
- public ExecutionContext getExecutionContext() {
- touch();
- return executionContext;
- }
-
- @Override
- public String toString() {
- final StringBuilder builder = new StringBuilder();
- builder.append("ProcessInstance [");
- builder.append("id=").append(executionContext.getProcessInstanceId());
- builder.append(", idle since=").append(
- DurationFormatUtils.formatDurationWords(new Date().getTime() - this.lru.getTime(), true, true));
- if (processDefinition != null) {
- builder.append(", processDefinition.id=");
- builder.append(processDefinition.getId());
- }
- if (nextId != null) {
- builder.append(", nextId=");
- builder.append(nextId);
- }
- builder.append(", executionContext=").append(executionContext);
- builder.append("]");
- return builder.toString();
- }
+ private static final long serialVersionUID = 1L;
+ private static final int RND_ID_LENGTH = 22;
+
+ private final ProcessDefinition processDefinition;
+ private String nextId;
+ private Date lru;
+ private final ExecutionContext executionContext;
+ private ProcessInstanceState state = ProcessInstanceState.NOT_STARTED;
+
+
+
+ /**
+ * Creates a new process instance, based on a given process definition and a given execution
+ * context. If the given execution context is {@code null} a new execution context will be
+ * created.
+ * <p/>
+ * The process instance id of the execution context will be newly generated if it is {@code null}
+ * in the execution context.
+ *
+ * @param processDefinition The process definition.
+ * @param executionContext The execution context (may be {@code null}). If {@code null} a new
+ * execution context will be created internally.
+ */
+ ProcessInstance(final ProcessDefinition processDefinition, ExecutionContext executionContext) {
+ final Logger log = LoggerFactory.getLogger(getClass());
+
+ this.processDefinition = processDefinition;
+ nextId = processDefinition.getStartEvent().getId();
+ if (executionContext == null) {
+ executionContext = new ExecutionContextImpl();
+ }
+ if (executionContext.getProcessInstanceId() == null) {
+ final String pdIdLocalPart = RandomStringUtils.random(RND_ID_LENGTH, 0, 0, true, true, null,
+ SecureRandomHolder.getInstance());
+ executionContext.setProcessInstanceId(this.processDefinition.getId() + "-" + pdIdLocalPart);
+ } else {
+ log.debug("Using process instance id from execution context.");
+ }
+ log.debug("Creating process instance with id '{}'.", executionContext.getProcessInstanceId());
+ this.executionContext = executionContext;
+ touch();
+ }
+
+ /**
+ * Returns the underlying process definition.
+ *
+ * @return The underlying process definition.
+ */
+ ProcessDefinition getProcessDefinition() {
+ touch();
+ return processDefinition;
+ }
+
+ /**
+ * Returns the id of the process node to be executed next.
+ *
+ * @return The process node pointer indicating the process node to be executed next.
+ */
+ public String getNextId() {
+ touch();
+ return nextId;
+ }
+
+ /**
+ * Sets the internal pointer to the process node to be executed next.
+ *
+ * @param nextId The process node id to be executed next.
+ */
+ void setNextId(final String nextId) {
+ touch();
+ this.nextId = nextId;
+ }
+
+ /**
+ * Returns the current state of the process instance.
+ *
+ * @return The current state.
+ */
+ public ProcessInstanceState getState() {
+ touch();
+ return state;
+ }
+
+ /**
+ * Sets the current state of the process instance.
+ *
+ * @param state The current state.
+ */
+ void setState(final ProcessInstanceState state) {
+ touch();
+ this.state = state;
+ }
+
+ public String getId() {
+ touch();
+ return executionContext.getProcessInstanceId();
+ }
+
+ /**
+ * Updates the last recently used date of the process instance.
+ */
+ private void touch() {
+ lru = new Date();
+ }
+
+ /**
+ * Returns the date the process instance has been accessed last.
+ *
+ * @return The last recently used date.
+ */
+ Date getLru() {
+ return lru;
+ }
+
+ /**
+ * Returns the associated execution context.
+ *
+ * @return The execution context (never {@code null}).
+ */
+ public ExecutionContext getExecutionContext() {
+ touch();
+ return executionContext;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder builder = new StringBuilder();
+ builder.append("ProcessInstance [");
+ builder.append("id=").append(executionContext.getProcessInstanceId());
+ builder.append(", idle since=").append(DurationFormatUtils
+ .formatDurationWords(new Date().getTime() - this.lru.getTime(), true, true));
+ if (processDefinition != null) {
+ builder.append(", processDefinition.id=");
+ builder.append(processDefinition.getId());
+ }
+ if (nextId != null) {
+ builder.append(", nextId=");
+ builder.append(nextId);
+ }
+ builder.append(", executionContext=").append(executionContext);
+ builder.append("]");
+ return builder.toString();
+ }
}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ProcessInstanceState.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ProcessInstanceState.java
index 1abf5b86..e6bfa480 100644
--- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ProcessInstanceState.java
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/ProcessInstanceState.java
@@ -1,56 +1,51 @@
-/*******************************************************************************
- * Copyright 2017 Graz University of Technology
- * EAAF-Core Components has been developed in a cooperation between EGIZ,
- * A-SIT Plus, A-SIT, and Graz University of Technology.
+/*
+ * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a
+ * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology.
*
- * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European
+ * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in
+ * compliance with the Licence. You may obtain a copy of the Licence at:
* https://joinup.ec.europa.eu/news/understanding-eupl-v12
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+*/
+
package at.gv.egiz.eaaf.core.impl.idp.process;
/**
* Represents a certain process instance state.
+ *
* @author tknall
*
*/
public enum ProcessInstanceState {
-
- /**
- * Indicates that the process with this process instance has not yet been started.
- */
- NOT_STARTED,
-
- /**
- * Indicates that the process is currently running.
- */
- STARTED,
-
- /**
- * Indicates that the process has been suspended until being waken up by someonce calling {@code signal}.
- */
- SUSPENDED,
-
- /**
- * Indicates that the process has been completed.
- */
- ENDED
+
+ /**
+ * Indicates that the process with this process instance has not yet been started.
+ */
+ NOT_STARTED,
+
+ /**
+ * Indicates that the process is currently running.
+ */
+ STARTED,
+
+ /**
+ * Indicates that the process has been suspended until being waken up by someonce calling
+ * {@code signal}.
+ */
+ SUSPENDED,
+
+ /**
+ * Indicates that the process has been completed.
+ */
+ ENDED
}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/dao/ProcessInstanceStore.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/dao/ProcessInstanceStore.java
index 0fee29e5..f1abaef3 100644
--- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/dao/ProcessInstanceStore.java
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/dao/ProcessInstanceStore.java
@@ -1,99 +1,91 @@
-/*******************************************************************************
- * Copyright 2017 Graz University of Technology
- * EAAF-Core Components has been developed in a cooperation between EGIZ,
- * A-SIT Plus, A-SIT, and Graz University of Technology.
+/*
+ * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a
+ * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology.
*
- * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European
+ * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in
+ * compliance with the Licence. You may obtain a copy of the Licence at:
* https://joinup.ec.europa.eu/news/understanding-eupl-v12
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+*/
+
package at.gv.egiz.eaaf.core.impl.idp.process.dao;
import java.io.Serializable;
import java.util.Map;
-
import at.gv.egiz.eaaf.core.impl.idp.process.ProcessInstanceState;
-public class ProcessInstanceStore implements Serializable{
+public class ProcessInstanceStore implements Serializable {
+
+ private static final long serialVersionUID = -6147519767313903808L;
+
+ /**
+ * A process instance identifier qualifies as natural primary key by satisfying these requirements.
+ * ("unique, constant, required"):
+ * <ul>
+ * <li>unique value</li>
+ * <li>never changes (immutable)</li>
+ * <li>never {@code null}</li>
+ * </ul>
+ */
- private static final long serialVersionUID = -6147519767313903808L;
+ private String processInstanceId;
- /**
- * A process instance identifier qualifies as natural primary key by satisfying these requirements
- * ("unique, constant, required"):
- * <ul>
- * <li>unique value</li>
- * <li>never changes (immutable)</li>
- * <li>never {@code null}</li>
- * </ul>
- */
+ private String processDefinitionId;
- private String processInstanceId;
+ private String nextTaskId;
- private String processDefinitionId;
+ private ProcessInstanceState processState;
- private String nextTaskId;
+ private Map<String, Serializable> executionContextData;
- private ProcessInstanceState processState;
-
- private Map<String, Serializable> executionContextData;
-
- public String getProcessInstanceId() {
- return processInstanceId;
- }
+ public String getProcessInstanceId() {
+ return processInstanceId;
+ }
- public String getProcessDefinitionId() {
- return processDefinitionId;
- }
+ public String getProcessDefinitionId() {
+ return processDefinitionId;
+ }
- public String getNextTaskId() {
- return nextTaskId;
- }
+ public String getNextTaskId() {
+ return nextTaskId;
+ }
- public ProcessInstanceState getProcessState() {
- return processState;
- }
+ public ProcessInstanceState getProcessState() {
+ return processState;
+ }
- @SuppressWarnings("unchecked")
- public Map<String, Serializable> getExecutionContextData() {
- return executionContextData;
- }
+ @SuppressWarnings("unchecked")
+ public Map<String, Serializable> getExecutionContextData() {
+ return executionContextData;
+ }
- public void setProcessInstanceId(String processInstanceId) {
- this.processInstanceId = processInstanceId;
- }
+ public void setProcessInstanceId(final String processInstanceId) {
+ this.processInstanceId = processInstanceId;
+ }
- public void setProcessDefinitionId(String processDefinitionId) {
- this.processDefinitionId = processDefinitionId;
- }
+ public void setProcessDefinitionId(final String processDefinitionId) {
+ this.processDefinitionId = processDefinitionId;
+ }
- public void setNextTaskId(String nextTaskId) {
- this.nextTaskId = nextTaskId;
- }
+ public void setNextTaskId(final String nextTaskId) {
+ this.nextTaskId = nextTaskId;
+ }
- public void setProcessState(ProcessInstanceState processState) {
- this.processState = processState;
- }
+ public void setProcessState(final ProcessInstanceState processState) {
+ this.processState = processState;
+ }
- public void setExecutionContextData(Map<String, Serializable> executionContextData) {
- this.executionContextData = executionContextData;
- }
+ public void setExecutionContextData(final Map<String, Serializable> executionContextData) {
+ this.executionContextData = executionContextData;
+ }
}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/dao/ProcessInstanceStoreDAOImpl.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/dao/ProcessInstanceStoreDAOImpl.java
deleted file mode 100644
index 681c9707..00000000
--- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/dao/ProcessInstanceStoreDAOImpl.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*******************************************************************************
- * Copyright 2017 Graz University of Technology
- * EAAF-Core Components has been developed in a cooperation between EGIZ,
- * A-SIT Plus, A-SIT, and Graz University of Technology.
- *
- * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- * https://joinup.ec.europa.eu/news/understanding-eupl-v12
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-package at.gv.egiz.eaaf.core.impl.idp.process.dao;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-
-import at.gv.egiz.eaaf.core.api.idp.process.ProcessInstanceStoreDAO;
-import at.gv.egiz.eaaf.core.api.storage.ITransactionStorage;
-import at.gv.egiz.eaaf.core.exceptions.EAAFException;
-
-/**
- * Database backed implementation of the {@link ProcessInstanceStoreDAO}
- * interface.
- */
-@Service("ProcessInstanceStoreage")
-public class ProcessInstanceStoreDAOImpl implements ProcessInstanceStoreDAO {
-
- private Logger log = LoggerFactory.getLogger(getClass());
-
- @Autowired ITransactionStorage transactionStorage;
-
- @Override
- public void saveOrUpdate(ProcessInstanceStore pIStore) throws EAAFException {
- try {
- transactionStorage.put(pIStore.getProcessInstanceId(), pIStore, -1);
- log.debug("Store process instance with='{}' in the database.", pIStore.getProcessInstanceId());
-
- } catch (EAAFException e) {
- log.warn("ProcessInstanceStore could not be persisted to the database.");
- throw e;
- }
- }
-
- @Override
- public ProcessInstanceStore load(String processInstanceId) throws EAAFException {
- log.debug("Retrieve the ProcessInstanceStore for id='{}' from the database.", processInstanceId);
- ProcessInstanceStore result = null;
- try {
- result = transactionStorage.get(processInstanceId, ProcessInstanceStore.class);
-
- } catch (Exception e) {
- log.error("There are multiple persisted processes with the same process instance id '{}'",
- processInstanceId);
-
- throw e;
- }
-
- if (result != null) {
- log.debug("Found process instance store for instance '{}'.", processInstanceId);
-
- } else {
- log.debug("Unable to find process instance store for instance '{}'.", processInstanceId);
-
- }
-
- return result;
- }
-
- @Override
- public void remove(String processInstanceId) throws EAAFException {
-
- log.debug("Delete the ProcessInstanceStore for id='{}' from the database.", processInstanceId);
-
- if (transactionStorage.containsKey(processInstanceId))
- transactionStorage.remove(processInstanceId);
- else
- log.trace("ProcessInstanceStore for id='{}' was not found and could therefore not be deleted.", processInstanceId);
- }
-
-}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/dao/ProcessInstanceStoreDaoImpl.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/dao/ProcessInstanceStoreDaoImpl.java
new file mode 100644
index 00000000..06c8cc1a
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/dao/ProcessInstanceStoreDaoImpl.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a
+ * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European
+ * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in
+ * compliance with the Licence. You may obtain a copy of the Licence at:
+ * https://joinup.ec.europa.eu/news/understanding-eupl-v12
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+*/
+
+package at.gv.egiz.eaaf.core.impl.idp.process.dao;
+
+import at.gv.egiz.eaaf.core.api.idp.process.ProcessInstanceStoreDao;
+import at.gv.egiz.eaaf.core.api.storage.ITransactionStorage;
+import at.gv.egiz.eaaf.core.exceptions.EaafException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+/**
+ * Database backed implementation of the {@link ProcessInstanceStoreDao} interface.
+ */
+@Service("ProcessInstanceStoreage")
+public class ProcessInstanceStoreDaoImpl implements ProcessInstanceStoreDao {
+
+ private final Logger log = LoggerFactory.getLogger(getClass());
+
+ @Autowired
+ ITransactionStorage transactionStorage;
+
+ @Override
+ public void saveOrUpdate(final ProcessInstanceStore piStore) throws EaafException {
+ try {
+ transactionStorage.put(piStore.getProcessInstanceId(), piStore, -1);
+ log.debug("Store process instance with='{}' in the database.",
+ piStore.getProcessInstanceId());
+
+ } catch (final EaafException e) {
+ log.warn("ProcessInstanceStore could not be persisted to the database.");
+ throw e;
+ }
+ }
+
+ @Override
+ public ProcessInstanceStore load(final String processInstanceId) throws EaafException {
+ log.debug("Retrieve the ProcessInstanceStore for id='{}' from the database.",
+ processInstanceId);
+ ProcessInstanceStore result = null;
+ try {
+ result = transactionStorage.get(processInstanceId, ProcessInstanceStore.class);
+
+ } catch (final Exception e) {
+ log.error("There are multiple persisted processes with the same process instance id '{}'",
+ processInstanceId);
+
+ throw e;
+ }
+
+ if (result != null) {
+ log.debug("Found process instance store for instance '{}'.", processInstanceId);
+
+ } else {
+ log.debug("Unable to find process instance store for instance '{}'.", processInstanceId);
+
+ }
+
+ return result;
+ }
+
+ @Override
+ public void remove(final String processInstanceId) throws EaafException {
+
+ log.debug("Delete the ProcessInstanceStore for id='{}' from the database.", processInstanceId);
+
+ if (transactionStorage.containsKey(processInstanceId)) {
+ transactionStorage.remove(processInstanceId);
+ } else {
+ log.trace(
+ "ProcessInstanceStore for id='{}' was not found and could therefore not be deleted.",
+ processInstanceId);
+ }
+ }
+
+}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/model/EndEvent.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/model/EndEvent.java
index 8657d0dc..48919ded 100644
--- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/model/EndEvent.java
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/model/EndEvent.java
@@ -1,68 +1,60 @@
-/*******************************************************************************
- * Copyright 2017 Graz University of Technology
- * EAAF-Core Components has been developed in a cooperation between EGIZ,
- * A-SIT Plus, A-SIT, and Graz University of Technology.
+/*
+ * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a
+ * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology.
*
- * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European
+ * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in
+ * compliance with the Licence. You may obtain a copy of the Licence at:
* https://joinup.ec.europa.eu/news/understanding-eupl-v12
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+*/
+
package at.gv.egiz.eaaf.core.impl.idp.process.model;
import java.io.Serializable;
-
import org.apache.commons.collections4.CollectionUtils;
/**
* Represents an end event. Process execution terminates when an end event is reached.
- *
+ *
* @author tknall
*/
public class EndEvent extends ProcessNode implements Serializable {
- private static final long serialVersionUID = 1L;
+ private static final long serialVersionUID = 1L;
- @Override
- public String toString() {
- StringBuilder builder = new StringBuilder();
- builder.append("EndEvent [");
- if (getId() != null) {
- builder.append("id=");
- builder.append(getId());
- }
- if (CollectionUtils.isNotEmpty(getIncomingTransitions())) {
- if (builder.length() > 0) {
- builder.append(", ");
- }
- builder.append("incomingTransitions=");
- builder.append(getIncomingTransitions());
- }
- if (CollectionUtils.isNotEmpty(getOutgoingTransitions())) {
- if (builder.length() > 0) {
- builder.append(", ");
- }
- builder.append("outgoingTransitions=");
- builder.append(getOutgoingTransitions());
- }
- builder.append("]");
- return builder.toString();
- }
+ @Override
+ public String toString() {
+ final StringBuilder builder = new StringBuilder();
+ builder.append("EndEvent [");
+ if (getId() != null) {
+ builder.append("id=");
+ builder.append(getId());
+ }
+ if (CollectionUtils.isNotEmpty(getIncomingTransitions())) {
+ if (builder.length() > 0) {
+ builder.append(", ");
+ }
+ builder.append("incomingTransitions=");
+ builder.append(getIncomingTransitions());
+ }
+ if (CollectionUtils.isNotEmpty(getOutgoingTransitions())) {
+ if (builder.length() > 0) {
+ builder.append(", ");
+ }
+ builder.append("outgoingTransitions=");
+ builder.append(getOutgoingTransitions());
+ }
+ builder.append("]");
+ return builder.toString();
+ }
}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/model/ProcessDefinition.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/model/ProcessDefinition.java
index b7caef7a..3ab68266 100644
--- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/model/ProcessDefinition.java
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/model/ProcessDefinition.java
@@ -1,184 +1,177 @@
-/*******************************************************************************
- * Copyright 2017 Graz University of Technology
- * EAAF-Core Components has been developed in a cooperation between EGIZ,
- * A-SIT Plus, A-SIT, and Graz University of Technology.
+/*
+ * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a
+ * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology.
*
- * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European
+ * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in
+ * compliance with the Licence. You may obtain a copy of the Licence at:
* https://joinup.ec.europa.eu/news/understanding-eupl-v12
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+*/
+
package at.gv.egiz.eaaf.core.impl.idp.process.model;
+import java.io.Serializable;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;
-
import at.gv.egiz.eaaf.core.impl.idp.process.ProcessDefinitionParser;
/**
- * Represents a single process definition containing
+ * Represents a single process definition containing.
* <ul>
* <li>a {@link StartEvent},</li>
* <li>one or more {@linkplain TaskInfo Tasks},</li>
* <li>one or more {@linkplain EndEvent EndEvents} and</li>
* <li>some {@linkplain Transition Transitions} linking StartEvents, Tasks and EndEvents.
* </ul>
- *
+ *
* @author tknall
- *
+ *
*/
-public class ProcessDefinition {
-
- private String id;
- private StartEvent startEvent;
- private Map<String, TaskInfo> taskInfos = new LinkedHashMap<>();
- private Map<String, EndEvent> endEvents = new LinkedHashMap<>();
-
- /**
- * Returns the unique identifier of the process definition.
- *
- * @return The unique identifier (never {@code null} if process definition comes from
- * {@link ProcessDefinitionParser}).
- */
- public String getId() {
- return id;
- }
-
- /**
- * Sets the unique identifier of the process definition.
- *
- * @param id
- * The unique identifier.
- */
- public void setId(String id) {
- this.id = id;
- }
-
- /**
- * Returns the start event of the process definition.
- *
- * @return The start event (never {@code null} if process definition comes from {@link ProcessDefinitionParser}).
- */
- public StartEvent getStartEvent() {
- return startEvent;
- }
-
- /**
- * Sets the start event of the process definition.
- *
- * @param startEvent
- * The start event.
- */
- public void setStartEvent(StartEvent startEvent) {
- this.startEvent = startEvent;
- }
-
- /**
- * Returns a map containing the tasks of the process definition.
- *
- * @return The tasks (map is never {@code null} if process definition comes from {@link ProcessDefinitionParser}).
- */
- public Map<String, TaskInfo> getTaskInfos() {
- return taskInfos;
- }
-
- /**
- * Sets the map containing the tasks.
- *
- * @param taskInfos
- * The map containing the tasks.
- */
- public void setTaskInfos(Map<String, TaskInfo> taskInfos) {
- this.taskInfos = taskInfos;
- }
-
- /**
- * Returns a map containing the end events of the process description.
- *
- * @return The map containing the end events (map is never {@code null} if process definition comes from
- * {@link ProcessDefinitionParser}).
- */
- public Map<String, EndEvent> getEndEvents() {
- return endEvents;
- }
-
- /**
- * Sets a map containing the end events of the process description.
- *
- * @param endEvents
- * The map containing the end events.
- */
- public void setEndEvents(Map<String, EndEvent> endEvents) {
- this.endEvents = endEvents;
- }
-
- /**
- * Returns the process node associated with the given {@code id}.
- *
- * @param id
- * The identifier of the process node.
- * @return The process node (may be {code null} when no process node with the given {@code id} exists).
- */
- public ProcessNode getProcessNode(String id) {
- Objects.requireNonNull(id, "Identifier must not be null.");
- if (startEvent != null && id.equals(startEvent.getId())) {
- return startEvent;
- }
- TaskInfo task = taskInfos.get(id);
- if (task != null) {
- return task;
- }
- return endEvents.get(id);
- }
-
- @Override
- public String toString() {
- StringBuilder builder = new StringBuilder();
- if (id != null) {
- builder.append("id=");
- builder.append(id);
- }
- if (startEvent != null) {
- if (builder.length() > 0) {
- builder.append(", ");
- }
- builder.append("startEvent=");
- builder.append(startEvent);
- }
- if (taskInfos != null && !taskInfos.isEmpty()) {
- if (builder.length() > 0) {
- builder.append(", ");
- }
- builder.append("tasksInfos=");
- builder.append(taskInfos.values());
- }
- if (endEvents != null && !endEvents.isEmpty()) {
- if (builder.length() > 0) {
- builder.append(", ");
- }
- builder.append("endEvents=");
- builder.append(endEvents.values());
- }
- builder.insert(0, "ProcessDefinition [");
- builder.append("]");
- return builder.toString();
- }
+public class ProcessDefinition implements Serializable {
+
+ private static final long serialVersionUID = 7896697967510445442L;
+
+ private String id;
+ private StartEvent startEvent;
+ private Map<String, TaskInfo> taskInfos = new LinkedHashMap<>();
+ private Map<String, EndEvent> endEvents = new LinkedHashMap<>();
+
+ /**
+ * Returns the unique identifier of the process definition.
+ *
+ * @return The unique identifier (never {@code null} if process definition comes from
+ * {@link ProcessDefinitionParser}).
+ */
+ public String getId() {
+ return id;
+ }
+
+ /**
+ * Sets the unique identifier of the process definition.
+ *
+ * @param id The unique identifier.
+ */
+ public void setId(final String id) {
+ this.id = id;
+ }
+
+ /**
+ * Returns the start event of the process definition.
+ *
+ * @return The start event (never {@code null} if process definition comes from
+ * {@link ProcessDefinitionParser}).
+ */
+ public StartEvent getStartEvent() {
+ return startEvent;
+ }
+
+ /**
+ * Sets the start event of the process definition.
+ *
+ * @param startEvent The start event.
+ */
+ public void setStartEvent(final StartEvent startEvent) {
+ this.startEvent = startEvent;
+ }
+
+ /**
+ * Returns a map containing the tasks of the process definition.
+ *
+ * @return The tasks (map is never {@code null} if process definition comes from
+ * {@link ProcessDefinitionParser}).
+ */
+ public Map<String, TaskInfo> getTaskInfos() {
+ return taskInfos;
+ }
+
+ /**
+ * Sets the map containing the tasks.
+ *
+ * @param taskInfos The map containing the tasks.
+ */
+ public void setTaskInfos(final Map<String, TaskInfo> taskInfos) {
+ this.taskInfos = taskInfos;
+ }
+
+ /**
+ * Returns a map containing the end events of the process description.
+ *
+ * @return The map containing the end events (map is never {@code null} if process definition
+ * comes from {@link ProcessDefinitionParser}).
+ */
+ public Map<String, EndEvent> getEndEvents() {
+ return endEvents;
+ }
+
+ /**
+ * Sets a map containing the end events of the process description.
+ *
+ * @param endEvents The map containing the end events.
+ */
+ public void setEndEvents(final Map<String, EndEvent> endEvents) {
+ this.endEvents = endEvents;
+ }
+
+ /**
+ * Returns the process node associated with the given {@code id}.
+ *
+ * @param id The identifier of the process node.
+ * @return The process node (may be {code null} when no process node with the given {@code id}
+ * exists).
+ */
+ public ProcessNode getProcessNode(final String id) {
+ Objects.requireNonNull(id, "Identifier must not be null.");
+ if (startEvent != null && id.equals(startEvent.getId())) {
+ return startEvent;
+ }
+ final TaskInfo task = taskInfos.get(id);
+ if (task != null) {
+ return task;
+ }
+ return endEvents.get(id);
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder builder = new StringBuilder();
+ if (id != null) {
+ builder.append("id=");
+ builder.append(id);
+ }
+ if (startEvent != null) {
+ if (builder.length() > 0) {
+ builder.append(", ");
+ }
+ builder.append("startEvent=");
+ builder.append(startEvent);
+ }
+ if (taskInfos != null && !taskInfos.isEmpty()) {
+ if (builder.length() > 0) {
+ builder.append(", ");
+ }
+ builder.append("tasksInfos=");
+ builder.append(taskInfos.values());
+ }
+ if (endEvents != null && !endEvents.isEmpty()) {
+ if (builder.length() > 0) {
+ builder.append(", ");
+ }
+ builder.append("endEvents=");
+ builder.append(endEvents.values());
+ }
+ builder.insert(0, "ProcessDefinition [");
+ builder.append("]");
+ return builder.toString();
+ }
}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/model/ProcessNode.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/model/ProcessNode.java
index 7964fa47..92858edf 100644
--- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/model/ProcessNode.java
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/model/ProcessNode.java
@@ -1,95 +1,95 @@
-/*******************************************************************************
- * Copyright 2017 Graz University of Technology
- * EAAF-Core Components has been developed in a cooperation between EGIZ,
- * A-SIT Plus, A-SIT, and Graz University of Technology.
+/*
+ * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a
+ * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology.
*
- * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European
+ * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in
+ * compliance with the Licence. You may obtain a copy of the Licence at:
* https://joinup.ec.europa.eu/news/understanding-eupl-v12
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+*/
+
package at.gv.egiz.eaaf.core.impl.idp.process.model;
import java.util.ArrayList;
import java.util.List;
-
import at.gv.egiz.eaaf.core.impl.idp.process.ProcessDefinitionParser;
/**
* Represents a {@link StartEvent}, an {@link EndEvent} or a {@linkplain TaskInfo Task}.
+ *
* @author tknall
*
*/
public abstract class ProcessNode {
- private String id;
- private List<Transition> outgoingTransitions = new ArrayList<>();
- private List<Transition> incomingTransitions = new ArrayList<>();
+ private String id;
+ private List<Transition> outgoingTransitions = new ArrayList<>();
+ private List<Transition> incomingTransitions = new ArrayList<>();
+
+ /**
+ * Returns the unique identifier of the process node.
+ *
+ * @return The unique identifier (never {@code null} if process node comes from a process
+ * definition from {@link ProcessDefinitionParser}).
+ */
+ public String getId() {
+ return id;
+ }
- /**
- * Returns the unique identifier of the process node.
- *
- * @return The unique identifier (never {@code null} if process node comes from a process definition from
- * {@link ProcessDefinitionParser}).
- */
- public String getId() {
- return id;
- }
+ /**
+ * Sets the unique identifier of the process node.
+ *
+ * @param id The unique identifier.
+ */
+ public void setId(final String id) {
+ this.id = id;
+ }
- /**
- * Sets the unique identifier of the process node.
- * @param id The unique identifier.
- */
- public void setId(String id) {
- this.id = id;
- }
+ /**
+ * Returns a list of transitions pointing from this process node to another one.
+ *
+ * @return A list of transitions (never {@code null} if process node comes from a process
+ * definition from {@link ProcessDefinitionParser}).
+ */
+ public List<Transition> getOutgoingTransitions() {
+ return outgoingTransitions;
+ }
- /**
- * Returns a list of transitions pointing from this process node to another one.
- * @return A list of transitions (never {@code null} if process node comes from a process definition from {@link ProcessDefinitionParser}).
- */
- public List<Transition> getOutgoingTransitions() {
- return outgoingTransitions;
- }
+ /**
+ * Sets the list of transitions pointing from this process node to another one.
+ *
+ * @param outgoingTransitions The list of transitions originating from this process node.
+ */
+ public void setOutgoingTransitions(final List<Transition> outgoingTransitions) {
+ this.outgoingTransitions = outgoingTransitions;
+ }
- /**
- * Sets the list of transitions pointing from this process node to another one.
- * @param outgoingTransitions The list of transitions originating from this process node.
- */
- public void setOutgoingTransitions(List<Transition> outgoingTransitions) {
- this.outgoingTransitions = outgoingTransitions;
- }
+ /**
+ * Returns a list of transitions pointing from another process node to this one.
+ *
+ * @return A list of transitions (never {@code null} if process node comes from a process
+ * definition from {@link ProcessDefinitionParser}).
+ */
+ public List<Transition> getIncomingTransitions() {
+ return incomingTransitions;
+ }
- /**
- * Returns a list of transitions pointing from another process node to this one.
- * @return A list of transitions (never {@code null} if process node comes from a process definition from {@link ProcessDefinitionParser}).
- */
- public List<Transition> getIncomingTransitions() {
- return incomingTransitions;
- }
+ /**
+ * Sets the list of transitions pointing from another process node to this one.
+ *
+ * @param incomingTransitions A list of transitions pointing to this process node.
+ */
+ public void setIncomingTransitions(final List<Transition> incomingTransitions) {
+ this.incomingTransitions = incomingTransitions;
+ }
- /**
- * Sets the list of transitions pointing from another process node to this one.
- * @param incomingTransitions A list of transitions pointing to this process node.
- */
- public void setIncomingTransitions(List<Transition> incomingTransitions) {
- this.incomingTransitions = incomingTransitions;
- }
-
}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/model/StartEvent.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/model/StartEvent.java
index 8e358b69..698312c7 100644
--- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/model/StartEvent.java
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/model/StartEvent.java
@@ -1,71 +1,63 @@
-/*******************************************************************************
- * Copyright 2017 Graz University of Technology
- * EAAF-Core Components has been developed in a cooperation between EGIZ,
- * A-SIT Plus, A-SIT, and Graz University of Technology.
+/*
+ * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a
+ * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology.
*
- * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European
+ * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in
+ * compliance with the Licence. You may obtain a copy of the Licence at:
* https://joinup.ec.europa.eu/news/understanding-eupl-v12
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+*/
+
package at.gv.egiz.eaaf.core.impl.idp.process.model;
import java.io.Serializable;
-
import org.apache.commons.collections4.CollectionUtils;
/**
- * Represents a start event. Each process description contains a single start event. Process execution starts with a
- * start event.
- *
+ * Represents a start event. Each process description contains a single start event. Process
+ * execution starts with a start event.
+ *
* @author tknall
- *
+ *
*/
public class StartEvent extends ProcessNode implements Serializable {
- private static final long serialVersionUID = 1L;
+ private static final long serialVersionUID = 1L;
- @Override
- public String toString() {
- StringBuilder builder = new StringBuilder();
- builder.append("StartEvent [");
- if (getId() != null) {
- builder.append("id=");
- builder.append(getId());
- }
- if (CollectionUtils.isNotEmpty(getIncomingTransitions())) {
- if (builder.length() > 0) {
- builder.append(", ");
- }
- builder.append("incomingTransitions=");
- builder.append(getIncomingTransitions());
- }
- if (CollectionUtils.isNotEmpty(getOutgoingTransitions())) {
- if (builder.length() > 0) {
- builder.append(", ");
- }
- builder.append("outgoingTransitions=");
+ @Override
+ public String toString() {
+ final StringBuilder builder = new StringBuilder();
+ builder.append("StartEvent [");
+ if (getId() != null) {
+ builder.append("id=");
+ builder.append(getId());
+ }
+ if (CollectionUtils.isNotEmpty(getIncomingTransitions())) {
+ if (builder.length() > 0) {
+ builder.append(", ");
+ }
+ builder.append("incomingTransitions=");
+ builder.append(getIncomingTransitions());
+ }
+ if (CollectionUtils.isNotEmpty(getOutgoingTransitions())) {
+ if (builder.length() > 0) {
+ builder.append(", ");
+ }
+ builder.append("outgoingTransitions=");
- builder.append(getOutgoingTransitions());
- }
- builder.append("]");
- return builder.toString();
- }
+ builder.append(getOutgoingTransitions());
+ }
+ builder.append("]");
+ return builder.toString();
+ }
}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/model/TaskInfo.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/model/TaskInfo.java
index b98045c5..9e384b4c 100644
--- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/model/TaskInfo.java
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/model/TaskInfo.java
@@ -1,120 +1,117 @@
-/*******************************************************************************
- * Copyright 2017 Graz University of Technology
- * EAAF-Core Components has been developed in a cooperation between EGIZ,
- * A-SIT Plus, A-SIT, and Graz University of Technology.
+/*
+ * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a
+ * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology.
*
- * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European
+ * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in
+ * compliance with the Licence. You may obtain a copy of the Licence at:
* https://joinup.ec.europa.eu/news/understanding-eupl-v12
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+
package at.gv.egiz.eaaf.core.impl.idp.process.model;
import java.io.Serializable;
-
-import org.apache.commons.collections4.CollectionUtils;
-
import at.gv.egiz.eaaf.core.api.idp.process.Task;
+import org.apache.commons.collections4.CollectionUtils;
/**
* Represents information about a single task to be performed upon process execution.
+ *
* @author tknall
*
*/
public class TaskInfo extends ProcessNode implements Serializable {
- private static final long serialVersionUID = 1L;
- private static final boolean DEFAULT_ASYNC = false;
-
- private String taskImplementingClass;
- private boolean async = DEFAULT_ASYNC;
-
- /**
- * Determines if the task is marked asynchronous ({@code true}) or synchronous ({@code false}).
- * @return A flag indicating if the task should be executed asynchronously or synchronously. (Default: {@code false})
- */
- public boolean isAsync() {
- return async;
- }
+ private static final long serialVersionUID = 1L;
+ private static final boolean DEFAULT_ASYNC = false;
+
+ private String taskImplementingClass;
+ private boolean async = DEFAULT_ASYNC;
+
+ /**
+ * Determines if the task is marked asynchronous ({@code true}) or synchronous ({@code false}).
+ *
+ * @return A flag indicating if the task should be executed asynchronously or synchronously.
+ * (Default: {@code false})
+ */
+ public boolean isAsync() {
+ return async;
+ }
- /**
- * Marks a task to executed asynchronously ({@code true}) or synchronously ({@code false}).
- * @param async The flag.
- */
- public void setAsync(boolean async) {
- this.async = async;
- }
+ /**
+ * Marks a task to executed asynchronously ({@code true}) or synchronously ({@code false}).
+ *
+ * @param async The flag.
+ */
+ public void setAsync(final boolean async) {
+ this.async = async;
+ }
- /**
- * Returns the class that implements the actual task (must implement {@link Task}).
- * @return The task implementing class.
- */
- public String getTaskImplementingClass() {
- return taskImplementingClass;
- }
+ /**
+ * Returns the class that implements the actual task (must implement {@link Task}).
+ *
+ * @return The task implementing class.
+ */
+ public String getTaskImplementingClass() {
+ return taskImplementingClass;
+ }
- /**
- * Sets the class that implements the actual task (must implement {@link Task}).
- * @param taskImplementingClass The task implementing class.
- */
- public void setTaskImplementingClass(String taskImplementingClass) {
- this.taskImplementingClass = taskImplementingClass;
- }
+ /**
+ * Sets the class that implements the actual task (must implement {@link Task}).
+ *
+ * @param taskImplementingClass The task implementing class.
+ */
+ public void setTaskImplementingClass(final String taskImplementingClass) {
+ this.taskImplementingClass = taskImplementingClass;
+ }
- @Override
- public String toString() {
- StringBuilder builder = new StringBuilder();
- if (getId() != null) {
- builder.append("id=");
- builder.append(getId());
- }
- if (async != DEFAULT_ASYNC) {
- if (builder.length() > 0) {
- builder.append(", ");
- }
- builder.append("async=");
- builder.append(async);
- }
- if (taskImplementingClass != null) {
- if (builder.length() > 0) {
- builder.append(", ");
- }
- builder.append("taskImplementingClass=");
- builder.append(taskImplementingClass);
- }
- if (CollectionUtils.isNotEmpty(getIncomingTransitions())) {
- if (builder.length() > 0) {
- builder.append(", ");
- }
- builder.append("incomingTransitions=");
- builder.append(getIncomingTransitions());
- }
- if (CollectionUtils.isNotEmpty(getOutgoingTransitions())) {
- if (builder.length() > 0) {
- builder.append(", ");
- }
- builder.append("outgoingTransitions=");
- builder.append(getOutgoingTransitions());
- }
- builder.insert(0, "TaskInfo [");
- builder.append("]");
- return builder.toString();
- }
+ @Override
+ public String toString() {
+ final StringBuilder builder = new StringBuilder();
+ if (getId() != null) {
+ builder.append("id=");
+ builder.append(getId());
+ }
+ if (async != DEFAULT_ASYNC) {
+ if (builder.length() > 0) {
+ builder.append(", ");
+ }
+ builder.append("async=");
+ builder.append(async);
+ }
+ if (taskImplementingClass != null) {
+ if (builder.length() > 0) {
+ builder.append(", ");
+ }
+ builder.append("taskImplementingClass=");
+ builder.append(taskImplementingClass);
+ }
+ if (CollectionUtils.isNotEmpty(getIncomingTransitions())) {
+ if (builder.length() > 0) {
+ builder.append(", ");
+ }
+ builder.append("incomingTransitions=");
+ builder.append(getIncomingTransitions());
+ }
+ if (CollectionUtils.isNotEmpty(getOutgoingTransitions())) {
+ if (builder.length() > 0) {
+ builder.append(", ");
+ }
+ builder.append("outgoingTransitions=");
+ builder.append(getOutgoingTransitions());
+ }
+ builder.insert(0, "TaskInfo [");
+ builder.append("]");
+ return builder.toString();
+ }
}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/model/Transition.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/model/Transition.java
index 542ea7a8..4c7b70f0 100644
--- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/model/Transition.java
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/model/Transition.java
@@ -1,162 +1,150 @@
-/*******************************************************************************
- * Copyright 2017 Graz University of Technology
- * EAAF-Core Components has been developed in a cooperation between EGIZ,
- * A-SIT Plus, A-SIT, and Graz University of Technology.
+/*
+ * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a
+ * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology.
*
- * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European
+ * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in
+ * compliance with the Licence. You may obtain a copy of the Licence at:
* https://joinup.ec.europa.eu/news/understanding-eupl-v12
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+*/
+
package at.gv.egiz.eaaf.core.impl.idp.process.model;
import java.io.Serializable;
-
import at.gv.egiz.eaaf.core.impl.idp.process.ProcessDefinitionParser;
/**
* Represents a single transition from a {@link StartEvent} or {@linkplain TaskInfo Task} to another
* {@linkplain TaskInfo Task} or {@link EndEvent}.
- *
+ *
* @author tknall
- *
+ *
*/
public class Transition implements Serializable {
- private static final long serialVersionUID = 1L;
+ private static final long serialVersionUID = 1L;
- private String id;
- private String conditionExpression;
- private ProcessNode from;
- private ProcessNode to;
+ private String id;
+ private String conditionExpression;
+ private ProcessNode from;
+ private ProcessNode to;
- /**
- * Returns the process node (effectively a {@link StartEvent} or {@linkplain TaskInfo Task}) the transition is
- * pointing from.
- *
- * @return The transition's source process node (never {@code null} if transition comes from a process definition
- * from {@link ProcessDefinitionParser}).
- */
- public ProcessNode getFrom() {
- return from;
- }
+ /**
+ * Returns the process node (effectively a {@link StartEvent} or {@linkplain TaskInfo Task}) the
+ * transition is pointing from.
+ *
+ * @return The transition's source process node (never {@code null} if transition comes from a
+ * process definition from {@link ProcessDefinitionParser}).
+ */
+ public ProcessNode getFrom() {
+ return from;
+ }
- /**
- * Sets the process node the transition is pointing from.
- *
- * @param from
- * The transition's source process node.
- */
- public void setFrom(ProcessNode from) {
- this.from = from;
- }
+ /**
+ * Sets the process node the transition is pointing from.
+ *
+ * @param from The transition's source process node.
+ */
+ public void setFrom(final ProcessNode from) {
+ this.from = from;
+ }
- /**
- * Returns the process node (effectively a {@linkplain TaskInfo Task} or {@link EndEvent}) the transition is
- * pointing to.
- *
- * @return The transition's destination process node (never {@code null} if transition comes from a process
- * definition from {@link ProcessDefinitionParser}).
- */
- public ProcessNode getTo() {
- return to;
- }
+ /**
+ * Returns the process node (effectively a {@linkplain TaskInfo Task} or {@link EndEvent}) the
+ * transition is pointing to.
+ *
+ * @return The transition's destination process node (never {@code null} if transition comes from
+ * a process definition from {@link ProcessDefinitionParser}).
+ */
+ public ProcessNode getTo() {
+ return to;
+ }
- /**
- * Sets the process node the transition is pointing to.
- *
- * @param to
- * The transition's destination process node.
- */
- public void setTo(ProcessNode to) {
- this.to = to;
- }
+ /**
+ * Sets the process node the transition is pointing to.
+ *
+ * @param to The transition's destination process node.
+ */
+ public void setTo(final ProcessNode to) {
+ this.to = to;
+ }
- /**
- * Returns the unique identifier of the transition.
- *
- * @return The unique identifier (may be {@code null}).
- */
- public String getId() {
- return id;
- }
+ /**
+ * Returns the unique identifier of the transition.
+ *
+ * @return The unique identifier (may be {@code null}).
+ */
+ public String getId() {
+ return id;
+ }
- /**
- * Sets the unique identifier of the transition.
- *
- * @param id
- * The unique identifier.
- */
- public void setId(String id) {
- this.id = id;
- }
+ /**
+ * Sets the unique identifier of the transition.
+ *
+ * @param id The unique identifier.
+ */
+ public void setId(final String id) {
+ this.id = id;
+ }
- /**
- * Returns the condition expression for this transition.
- *
- * @return The condition expression (may be {@code null}).
- */
- public String getConditionExpression() {
- return conditionExpression;
- }
+ /**
+ * Returns the condition expression for this transition.
+ *
+ * @return The condition expression (may be {@code null}).
+ */
+ public String getConditionExpression() {
+ return conditionExpression;
+ }
- /**
- * Sets the condition expression for this transition.
- *
- * @param conditionExpression
- * The condition expression.
- */
- public void setConditionExpression(String conditionExpression) {
- this.conditionExpression = conditionExpression;
- }
+ /**
+ * Sets the condition expression for this transition.
+ *
+ * @param conditionExpression The condition expression.
+ */
+ public void setConditionExpression(final String conditionExpression) {
+ this.conditionExpression = conditionExpression;
+ }
- @Override
- public String toString() {
- StringBuilder builder = new StringBuilder();
- if (id != null) {
- builder.append("id=");
- builder.append(id);
- }
- if (from != null) {
- if (builder.length() > 0) {
- builder.append(", ");
- }
- builder.append("from.id=");
- builder.append(from.getId());
- }
- if (to != null) {
- if (builder.length() > 0) {
- builder.append(", ");
- }
- builder.append("to.id=");
- builder.append(to.getId());
- }
- if (conditionExpression != null) {
- if (builder.length() > 0) {
- builder.append(", ");
- }
- builder.append("conditionExpression=");
- builder.append(conditionExpression);
- }
- builder.insert(0, "Transition [");
- builder.append("]");
- return builder.toString();
- }
+ @Override
+ public String toString() {
+ final StringBuilder builder = new StringBuilder();
+ if (id != null) {
+ builder.append("id=");
+ builder.append(id);
+ }
+ if (from != null) {
+ if (builder.length() > 0) {
+ builder.append(", ");
+ }
+ builder.append("from.id=");
+ builder.append(from.getId());
+ }
+ if (to != null) {
+ if (builder.length() > 0) {
+ builder.append(", ");
+ }
+ builder.append("to.id=");
+ builder.append(to.getId());
+ }
+ if (conditionExpression != null) {
+ if (builder.length() > 0) {
+ builder.append(", ");
+ }
+ builder.append("conditionExpression=");
+ builder.append(conditionExpression);
+ }
+ builder.insert(0, "Transition [");
+ builder.append("]");
+ return builder.toString();
+ }
}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/spring/SpringExpressionEvaluator.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/spring/SpringExpressionEvaluator.java
index a91963e8..fc01463e 100644
--- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/spring/SpringExpressionEvaluator.java
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/spring/SpringExpressionEvaluator.java
@@ -1,35 +1,29 @@
-/*******************************************************************************
- * Copyright 2017 Graz University of Technology
- * EAAF-Core Components has been developed in a cooperation between EGIZ,
- * A-SIT Plus, A-SIT, and Graz University of Technology.
+/*
+ * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a
+ * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology.
*
- * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European
+ * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in
+ * compliance with the Licence. You may obtain a copy of the Licence at:
* https://joinup.ec.europa.eu/news/understanding-eupl-v12
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+*/
+
package at.gv.egiz.eaaf.core.impl.idp.process.spring;
import java.util.Objects;
-
import javax.annotation.PostConstruct;
-
+import at.gv.egiz.eaaf.core.api.idp.process.ExpressionEvaluationContext;
+import at.gv.egiz.eaaf.core.api.idp.process.ExpressionEvaluator;
+import at.gv.egiz.eaaf.core.impl.idp.process.model.Transition;
import org.apache.commons.lang3.BooleanUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -41,47 +35,44 @@ import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
-import at.gv.egiz.eaaf.core.api.idp.process.ExpressionEvaluationContext;
-import at.gv.egiz.eaaf.core.api.idp.process.ExpressionEvaluator;
-import at.gv.egiz.eaaf.core.impl.idp.process.model.Transition;
-
/**
- * Expression evaluator for processing {@link Transition} conditions allowing to reference Spring beans from the
- * application context.
- *
+ * Expression evaluator for processing {@link Transition} conditions allowing to reference Spring
+ * beans from the application context.
+ *
* @author tknall
- *
+ *
*/
public class SpringExpressionEvaluator implements ExpressionEvaluator {
- private Logger log = LoggerFactory.getLogger(getClass());
- private ExpressionParser parser = new SpelExpressionParser();
- private StandardEvaluationContext evaluationContext = new StandardEvaluationContext();
+ private final Logger log = LoggerFactory.getLogger(getClass());
+ private final ExpressionParser parser = new SpelExpressionParser();
+ private final StandardEvaluationContext evaluationContext = new StandardEvaluationContext();
- @Autowired(required = false)
- private ApplicationContext ctx;
+ @Autowired(required = false)
+ private ApplicationContext ctx;
- @PostConstruct
- private void init() {
- if (ctx != null) {
- evaluationContext.setBeanResolver(new BeanFactoryResolver(ctx));
- }
- }
+ @PostConstruct
+ private void init() {
+ if (ctx != null) {
+ evaluationContext.setBeanResolver(new BeanFactoryResolver(ctx));
+ }
+ }
- @Override
- public boolean evaluate(ExpressionEvaluationContext expressionContext, String expression) {
- Objects.requireNonNull(expression, "Expression must not be null.");
- log.trace("Evaluating '{}'.", expression);
+ @Override
+ public boolean evaluate(final ExpressionEvaluationContext expressionContext,
+ final String expression) {
+ Objects.requireNonNull(expression, "Expression must not be null.");
+ log.trace("Evaluating '{}'.", expression);
- Expression expr = parser.parseExpression(expression);
- Boolean result = expr.getValue(evaluationContext, expressionContext, Boolean.class);
- if (result == null) {
- log.warn("Evaluation of '{}' results in null-value.", expression);
- } else {
- log.debug("Expression '{}' -> {}", expression, result);
- }
+ final Expression expr = parser.parseExpression(expression);
+ final Boolean result = expr.getValue(evaluationContext, expressionContext, Boolean.class);
+ if (result == null) {
+ log.warn("Evaluation of '{}' results in null-value.", expression);
+ } else {
+ log.debug("Expression '{}' -> {}", expression, result);
+ }
- return BooleanUtils.isTrue(result);
- }
+ return BooleanUtils.isTrue(result);
+ }
}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/springweb/AbstractAuthSourceServlet.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/springweb/AbstractAuthSourceServlet.java
index 4b007c4c..cc899641 100644
--- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/springweb/AbstractAuthSourceServlet.java
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/springweb/AbstractAuthSourceServlet.java
@@ -1,34 +1,29 @@
-/*******************************************************************************
- * Copyright 2017 Graz University of Technology
- * EAAF-Core Components has been developed in a cooperation between EGIZ,
- * A-SIT Plus, A-SIT, and Graz University of Technology.
+/*
+ * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a
+ * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology.
*
- * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European
+ * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in
+ * compliance with the Licence. You may obtain a copy of the Licence at:
* https://joinup.ec.europa.eu/news/understanding-eupl-v12
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+*/
+
package at.gv.egiz.eaaf.core.impl.idp.process.springweb;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
-
+import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext;
+import at.gv.egiz.eaaf.core.api.idp.process.ProcessEngine;
+import at.gv.egiz.eaaf.core.impl.idp.process.ProcessInstance;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
@@ -36,107 +31,95 @@ import org.springframework.beans.factory.NoUniqueBeanDefinitionException;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
-import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext;
-import at.gv.egiz.eaaf.core.api.idp.process.ProcessEngine;
-import at.gv.egiz.eaaf.core.impl.idp.process.ProcessInstance;
-
/**
- * Abstract HttpServlet that provides means for retrieving the process engine (Spring Web required) as well as
- * retrieving the underlying process instance and execution context evaluating a certain request parameter.
- *
+ * Abstract HttpServlet that provides means for retrieving the process engine (Spring Web required)
+ * as well as retrieving the underlying process instance and execution context evaluating a certain
+ * request parameter.
+ *
* @author tknall
- *
+ *
*/
public abstract class AbstractAuthSourceServlet extends HttpServlet {
- private static final long serialVersionUID = 1L;
+ private static final long serialVersionUID = 1L;
+
+ private ProcessEngine processEngine;
- private ProcessEngine processEngine;
-
- /**
- * Returns the name of the request parameter representing the respective instance id.
- * <p/>Default is {@code processInstanceId}.
- * @return The request parameter name.
- */
- public String getProcessInstanceIdParameterName() {
- return "processInstanceId";
- }
+ /**
+ * Returns the name of the request parameter representing the respective instance id.
+ * <p/>
+ * Default is {@code processInstanceId}.
+ *
+ * @return The request parameter name.
+ */
+ public String getProcessInstanceIdParameterName() {
+ return "processInstanceId";
+ }
- /**
- * Returns the underlying process engine instance.
- *
- * @return The process engine (never {@code null}).
- * @throws NoSuchBeanDefinitionException
- * if no {@link ProcessEngine} bean was found.
- * @throws NoUniqueBeanDefinitionException
- * if more than one {@link ProcessEngine} bean was found.
- * @throws BeansException
- * if a problem getting the {@link ProcessEngine} bean occurred.
- * @throws IllegalStateException
- * if the Spring WebApplicationContext was not found, which means that the servlet is used outside a
- * Spring web environment.
- */
- public synchronized ProcessEngine getProcessEngine() {
- if (processEngine == null) {
- WebApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
- if (ctx == null) {
- throw new IllegalStateException(
- "Unable to find Spring WebApplicationContext. Servlet needs to be executed within a Spring web environment.");
- }
- processEngine = ctx.getBean(ProcessEngine.class);
- }
- return processEngine;
- }
+ /**
+ * Returns the underlying process engine instance.
+ *
+ * @return The process engine (never {@code null}).
+ * @throws NoSuchBeanDefinitionException if no {@link ProcessEngine} bean was found.
+ * @throws NoUniqueBeanDefinitionException if more than one {@link ProcessEngine} bean was found.
+ * @throws BeansException if a problem getting the {@link ProcessEngine} bean occurred.
+ * @throws IllegalStateException if the Spring WebApplicationContext was not found, which means
+ * that the servlet is used outside a Spring web environment.
+ */
+ public synchronized ProcessEngine getProcessEngine() {
+ if (processEngine == null) {
+ final WebApplicationContext ctx =
+ WebApplicationContextUtils.getWebApplicationContext(getServletContext());
+ if (ctx == null) {
+ throw new IllegalStateException(
+ "Unable to find Spring WebApplicationContext. "
+ + "Servlet needs to be executed within a Spring web environment.");
+ }
+ processEngine = ctx.getBean(ProcessEngine.class);
+ }
+ return processEngine;
+ }
- /**
- * Retrieves the process instance referenced by the request parameter {@link #getProcessInstanceIdParameterName()}.
- *
- * @param request
- * The HttpServletRequest.
- * @return The process instance (never {@code null}).
- * @throws NoSuchBeanDefinitionException
- * if no {@link ProcessEngine} bean was found.
- * @throws NoUniqueBeanDefinitionException
- * if more than one {@link ProcessEngine} bean was found.
- * @throws BeansException
- * if a problem getting the {@link ProcessEngine} bean occurred.
- * @throws IllegalStateException
- * if the Spring WebApplicationContext was not found, which means that the servlet is used outside a
- * Spring web environment.
- * @throws IllegalArgumentException
- * in case the process instance id referenced by the request parameter
- * {@link #getProcessInstanceIdParameterName()} does not exist.
- */
- public ProcessInstance getProcessInstance(HttpServletRequest request) {
- String processInstanceId = StringUtils.trimToNull(request.getParameter(getProcessInstanceIdParameterName()));
- if (processInstanceId == null) {
- throw new IllegalArgumentException("Missing request parameter '" + getProcessInstanceIdParameterName() + "'.");
- }
- return getProcessEngine().getProcessInstance(processInstanceId);
- }
+ /**
+ * Retrieves the process instance referenced by the request parameter
+ * {@link #getProcessInstanceIdParameterName()}.
+ *
+ * @param request The HttpServletRequest.
+ * @return The process instance (never {@code null}).
+ * @throws NoSuchBeanDefinitionException if no {@link ProcessEngine} bean was found.
+ * @throws NoUniqueBeanDefinitionException if more than one {@link ProcessEngine} bean was found.
+ * @throws BeansException if a problem getting the {@link ProcessEngine} bean occurred.
+ * @throws IllegalStateException if the Spring WebApplicationContext was not found, which means
+ * that the servlet is used outside a Spring web environment.
+ * @throws IllegalArgumentException in case the process instance id referenced by the request
+ * parameter {@link #getProcessInstanceIdParameterName()} does not exist.
+ */
+ public ProcessInstance getProcessInstance(final HttpServletRequest request) {
+ final String processInstanceId =
+ StringUtils.trimToNull(request.getParameter(getProcessInstanceIdParameterName()));
+ if (processInstanceId == null) {
+ throw new IllegalArgumentException(
+ "Missing request parameter '" + getProcessInstanceIdParameterName() + "'.");
+ }
+ return getProcessEngine().getProcessInstance(processInstanceId);
+ }
- /**
- * Retrieves the execution context for the respective process instance referenced by the request parameter
- * {@link #getProcessInstanceIdParameterName()}.
- *
- * @param request
- * The HttpServletRequest.
- * @return The execution context (never {@code null}).
- * @throws NoSuchBeanDefinitionException
- * if no {@link ProcessEngine} bean was found.
- * @throws NoUniqueBeanDefinitionException
- * if more than one {@link ProcessEngine} bean was found.
- * @throws BeansException
- * if a problem getting the {@link ProcessEngine} bean occurred.
- * @throws IllegalStateException
- * if the Spring WebApplicationContext was not found, which means that the servlet is used outside a
- * Spring web environment.
- * @throws IllegalArgumentException
- * in case the process instance id referenced by the request parameter
- * {@link #getProcessInstanceIdParameterName()} does not exist.
- */
- public ExecutionContext getExecutionContext(HttpServletRequest request) {
- return getProcessInstance(request).getExecutionContext();
- }
+ /**
+ * Retrieves the execution context for the respective process instance referenced by the request
+ * parameter {@link #getProcessInstanceIdParameterName()}.
+ *
+ * @param request The HttpServletRequest.
+ * @return The execution context (never {@code null}).
+ * @throws NoSuchBeanDefinitionException if no {@link ProcessEngine} bean was found.
+ * @throws NoUniqueBeanDefinitionException if more than one {@link ProcessEngine} bean was found.
+ * @throws BeansException if a problem getting the {@link ProcessEngine} bean occurred.
+ * @throws IllegalStateException if the Spring WebApplicationContext was not found, which means
+ * that the servlet is used outside a Spring web environment.
+ * @throws IllegalArgumentException in case the process instance id referenced by the request
+ * parameter {@link #getProcessInstanceIdParameterName()} does not exist.
+ */
+ public ExecutionContext getExecutionContext(final HttpServletRequest request) {
+ return getProcessInstance(request).getExecutionContext();
+ }
}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/springweb/AbstractTask.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/springweb/AbstractTask.java
index b7a20d71..02db6686 100644
--- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/springweb/AbstractTask.java
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/springweb/AbstractTask.java
@@ -1,50 +1,42 @@
-/*******************************************************************************
- * Copyright 2017 Graz University of Technology
- * EAAF-Core Components has been developed in a cooperation between EGIZ,
- * A-SIT Plus, A-SIT, and Graz University of Technology.
+/*
+ * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a
+ * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology.
*
- * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European
+ * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in
+ * compliance with the Licence. You may obtain a copy of the Licence at:
* https://joinup.ec.europa.eu/news/understanding-eupl-v12
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+*/
+
package at.gv.egiz.eaaf.core.impl.idp.process.springweb;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-
-import org.springframework.web.context.request.RequestAttributes;
-import org.springframework.web.context.request.RequestContextHolder;
-import org.springframework.web.context.request.ServletRequestAttributes;
-import org.springframework.web.filter.RequestContextFilter;
-
import at.gv.egiz.eaaf.core.api.IRequest;
import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext;
import at.gv.egiz.eaaf.core.api.idp.process.Task;
import at.gv.egiz.eaaf.core.exceptions.TaskExecutionException;
+import org.springframework.web.context.request.RequestAttributes;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+import org.springframework.web.filter.RequestContextFilter;
/**
- * Abstract task implementation providing {@link HttpServletRequest} and {@link HttpServletResponse}.
+ * Abstract task implementation providing {@link HttpServletRequest} and
+ * {@link HttpServletResponse}.
* <p/>
- * Note that this abstract task requires the Spring (web) framework including a {@link RequestContextFilter} to be set
- * within {@code web.xml}.
- *
+ * Note that this abstract task requires the Spring (web) framework including a
+ * {@link RequestContextFilter} to be set within {@code web.xml}.
+ *
* <pre>
* ...
* &lt;filter&gt;
@@ -57,69 +49,72 @@ import at.gv.egiz.eaaf.core.exceptions.TaskExecutionException;
* &lt;/filter-mapping&gt;
* ...
* </pre>
- *
+ *
* @author tknall
* @author tlenz
- *
+ *
*/
public abstract class AbstractTask implements Task {
- /**
- * Executes the task providing the underlying {@link ExecutionContext} {@code executionContext} as well as the
- * respective {@link HttpServletRequest} and {@link HttpServletResponse}.
- *
- * @param executionContext
- * The execution context (never {@code null}).
- * @param request
- * The HttpServletRequest (never {@code null}).
- * @param response
- * The HttpServletResponse (never {@code null}).
- * @throws IllegalStateException
- * Thrown in case the task is nur being run within the required environment. Refer to javadoc for
- * further information.
- * @throws Exception
- * Thrown in case of error executing the task.
- */
- public abstract void execute(ExecutionContext executionContext, HttpServletRequest request,
- HttpServletResponse response) throws TaskExecutionException;
+ @Override
+ public IRequest execute(final IRequest pendingReq, final ExecutionContext executionContext)
+ throws TaskExecutionException {
+ final RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
+ if (requestAttributes != null && requestAttributes instanceof ServletRequestAttributes) {
+ final HttpServletRequest request =
+ ((ServletRequestAttributes) requestAttributes).getRequest();
+ final HttpServletResponse response =
+ ((ServletRequestAttributes) requestAttributes).getResponse();
+ if (request == null || response == null) {
+ throw new IllegalStateException(
+ "Spring's RequestContextHolder did not provide HttpServletResponse. "
+ + "Did you forget to set the required "
+ + "org.springframework.web.filter.RequestContextFilter in your web.xml.");
+ }
+ return internalExecute(pendingReq, executionContext, request, response);
+ } else {
+ throw new IllegalStateException("Task needs to be executed within a Spring web environment.");
+ }
+ }
+
+ /**
+ * Executes the task providing the underlying {@link ExecutionContext} {@code executionContext} as
+ * well as the respective {@link HttpServletRequest} and {@link HttpServletResponse}.
+ *
+ * @param executionContext The execution context (never {@code null}).
+ * @param request The HttpServletRequest (never {@code null}).
+ * @param response The HttpServletResponse (never {@code null}).
+ * @throws IllegalStateException Thrown in case the task is nur being run within the required
+ * environment. Refer to javadoc for further information.
+ * @throws Exception Thrown in case of error executing the task.
+ */
+ public abstract void execute(ExecutionContext executionContext, HttpServletRequest request,
+ HttpServletResponse response) throws TaskExecutionException;
+
+ /**
+ * Executes the task providing the underlying {@link ExecutionContext} {@code executionContext}
+ * and the {@link IRequest} {@code pendingReq }as well as the respective
+ * {@link HttpServletRequest} and {@link HttpServletResponse}.
+ *
+ * <p>
+ * This method sets the pending-request object of the task implementation and starts the
+ * {@code execute} method of the task
+ * </p>
+ *
+ * @param pendingReq The pending-request object (never {@code null}).
+ * @param executionContext The execution context (never {@code null}).
+ * @param request The HttpServletRequest (never {@code null}).
+ * @param response The HttpServletResponse (never {@code null}).
+ * @return The pending-request object, because Process-management works recursive
+ *
+ * @throws IllegalStateException Thrown in case the task is being run within the required
+ * environment. Refer to javadoc for further information.
+ * @throws Exception Thrown in case of error executing the task.
+ */
+ protected abstract IRequest internalExecute(IRequest pendingReq,
+ ExecutionContext executionContext, HttpServletRequest request, HttpServletResponse response)
+ throws TaskExecutionException;
+
- /**
- * Executes the task providing the underlying {@link ExecutionContext} {@code executionContext}
- * and the {@link IRequest} {@code pendingReq }as well as the
- * respective {@link HttpServletRequest} and {@link HttpServletResponse}.
- *
- * This method sets the pending-request object of the task implementation and starts the
- * {@code execute} method of the task
- *
- * @param pendingReq The pending-request object (never {@code null}).
- * @param executionContext The execution context (never {@code null}).
- * @param request The HttpServletRequest (never {@code null}).
- * @param response The HttpServletResponse (never {@code null}).
- * @return The pending-request object, because Process-management works recursive
- *
- * @throws IllegalStateException
- * Thrown in case the task is being run within the required environment. Refer to javadoc for
- * further information.
- * @throws Exception
- * Thrown in case of error executing the task.
- */
- protected abstract IRequest internalExecute(IRequest pendingReq, ExecutionContext executionContext, HttpServletRequest request,
- HttpServletResponse response) throws TaskExecutionException;
-
- @Override
- public IRequest execute(IRequest pendingReq, ExecutionContext executionContext) throws TaskExecutionException {
- RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
- if (requestAttributes != null && requestAttributes instanceof ServletRequestAttributes) {
- HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
- HttpServletResponse response = ((ServletRequestAttributes) requestAttributes).getResponse();
- if (request == null || response == null) {
- throw new IllegalStateException(
- "Spring's RequestContextHolder did not provide HttpServletResponse. Did you forget to set the required org.springframework.web.filter.RequestContextFilter in your web.xml.");
- }
- return internalExecute(pendingReq, executionContext, request, response);
- } else {
- throw new IllegalStateException("Task needs to be executed within a Spring web environment.");
- }
- }
}
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/springweb/SpringWebExpressionEvaluator.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/springweb/SpringWebExpressionEvaluator.java
index 5ebc1b58..c723a728 100644
--- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/springweb/SpringWebExpressionEvaluator.java
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/process/springweb/SpringWebExpressionEvaluator.java
@@ -1,43 +1,33 @@
-/*******************************************************************************
- * Copyright 2017 Graz University of Technology
- * EAAF-Core Components has been developed in a cooperation between EGIZ,
- * A-SIT Plus, A-SIT, and Graz University of Technology.
+/*
+ * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a
+ * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology.
*
- * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European
+ * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in
+ * compliance with the Licence. You may obtain a copy of the Licence at:
* https://joinup.ec.europa.eu/news/understanding-eupl-v12
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
-/*******************************************************************************
- *******************************************************************************/
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+*/
+
package at.gv.egiz.eaaf.core.impl.idp.process.springweb;
import java.io.Serializable;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
import java.util.Map;
-import java.util.Map.Entry;
import java.util.Objects;
-
import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
-
-import org.apache.commons.lang3.ArrayUtils;
+import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext;
+import at.gv.egiz.eaaf.core.api.idp.process.ExpressionEvaluationContext;
+import at.gv.egiz.eaaf.core.api.idp.process.ExpressionEvaluator;
+import at.gv.egiz.eaaf.core.impl.idp.process.model.Transition;
import org.apache.commons.lang3.BooleanUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -49,121 +39,89 @@ import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
-import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext;
-import at.gv.egiz.eaaf.core.api.idp.process.ExpressionEvaluationContext;
-import at.gv.egiz.eaaf.core.api.idp.process.ExpressionEvaluator;
-import at.gv.egiz.eaaf.core.impl.idp.process.model.Transition;
-
/**
- * Expression evaluator for processing {@link Transition} conditions allowing to
+ * Expression evaluator for processing {@link Transition} conditions allowing to.
* <ul>
* <li>reference Spring beans from the application context using {@code @myBeanName...},</li>
* <li>{@link ExecutionContext} properties using {@code ctx['property']},</li>
- * <li>Multi valued {@link HttpServletRequest} parameters using {@code requestParameters['foo']} (keep in mind that this
- * expression returns an array of String values) and</li>
- * <li>Single valued {@link HttpServletRequest} parameters using {@code requestParameter['foo']}</li>
+ * <li>Multi valued {@link HttpServletRequest} parameters using {@code requestParameters['foo']}
+ * (keep in mind that this expression returns an array of String values) and</li>
+ * <li>Single valued {@link HttpServletRequest} parameters using
+ * {@code requestParameter['foo']}</li>
* </ul>
- *
+ *
* @author tknall
- *
+ *
*/
public class SpringWebExpressionEvaluator implements ExpressionEvaluator {
- private Logger log = LoggerFactory.getLogger(getClass());
- private ExpressionParser parser = new SpelExpressionParser();
- private StandardEvaluationContext evaluationContext = new StandardEvaluationContext();
-
- @Autowired(required = false)
- private ApplicationContext ctx;
-
- @Autowired(required = false)
- private HttpServletRequest request;
-
- @PostConstruct
- private void init() {
- if (ctx != null) {
- evaluationContext.setBeanResolver(new BeanFactoryResolver(ctx));
- }
- }
-
- /**
- * Evaluation context that provides access to {@link HttpServletRequest} parameters using
- * {@code requestParameter['foo']} for single value parameters or {@code requestParameters['foo']} for multi value
- * parameters. Basic calls to {@code ctx} will be delegated.
- *
- * @author tknall
- *
- */
- private class SpringWebExpressionEvaluationContext implements ExpressionEvaluationContext {
-
- private static final long serialVersionUID = 1L;
-
- /**
- * Creates a new expression evaluation context, providing access to HttpServletRequest parameter(s).
- *
- * @param delegate
- * The original {@link ExpressionEvaluationContext} to be delegated to for {@code ctx['foo']}
- * expressions.
- */
- public SpringWebExpressionEvaluationContext(ExpressionEvaluationContext delegate) {
- this.delegate = delegate;
- }
-
- private ExpressionEvaluationContext delegate;
-
- @Override
- public Map<String, Serializable> getCtx() {
- return delegate.getCtx();
- }
-
- @SuppressWarnings("unused")
- public Map<String, String> getRequestParameter() {
- if (request != null) {
- Map<String, String> singleValueMap = new HashMap<String, String>();
- Iterator<Entry<String, String[]>> it = request.getParameterMap().entrySet().iterator();
- while (it.hasNext()) {
- Entry<String, String[]> entry = it.next();
- if (ArrayUtils.isNotEmpty(entry.getValue())) {
- singleValueMap.put(entry.getKey(), entry.getValue()[0]);
- }
- }
- return singleValueMap;
- } else {
- return Collections.<String, String> emptyMap();
- }
- }
-
- @SuppressWarnings("unused")
- public Map<String, String[]> getRequestParameters() {
- if (request != null) {
- return request.getParameterMap();
- } else {
- return Collections.<String, String[]> emptyMap();
- }
- }
-
- }
-
- @Override
- public boolean evaluate(ExpressionEvaluationContext expressionContext, String expression) {
- Objects.requireNonNull(expression, "Expression must not be null.");
- log.trace("Evaluating '{}'.", expression);
-
- Expression expr = parser.parseExpression(expression);
- Boolean result = null;
- try {
- result = expr.getValue(evaluationContext, new SpringWebExpressionEvaluationContext(expressionContext),
- Boolean.class);
- if (result == null) {
- log.debug("Evaluation of '{}' results in null-value.", expression);
- } else {
- log.debug("Expression '{}' -> {}", expression, result);
- }
- } catch (Exception e) {
- log.warn("Expression '{}' could not be processed.", expression, e);
- }
-
- return BooleanUtils.isTrue(result);
- }
+ private final Logger log = LoggerFactory.getLogger(getClass());
+ private final ExpressionParser parser = new SpelExpressionParser();
+ private final StandardEvaluationContext evaluationContext = new StandardEvaluationContext();
+
+ @Autowired(required = false)
+ private ApplicationContext ctx;
+
+ @PostConstruct
+ private void init() {
+ if (ctx != null) {
+ evaluationContext.setBeanResolver(new BeanFactoryResolver(ctx));
+ }
+ }
+
+ /**
+ * Evaluation context that provides access to {@link HttpServletRequest} parameters using
+ * {@code requestParameter['foo']} for single value parameters or {@code requestParameters['foo']}
+ * for multi value parameters. Basic calls to {@code ctx} will be delegated.
+ *
+ * @author tknall
+ *
+ */
+ private static class SpringWebExpressionEvaluationContext implements ExpressionEvaluationContext {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Creates a new expression evaluation context, providing access to HttpServletRequest
+ * parameter(s).
+ *
+ * @param delegate The original {@link ExpressionEvaluationContext} to be delegated to for
+ * {@code ctx['foo']} expressions.
+ */
+ public SpringWebExpressionEvaluationContext(final ExpressionEvaluationContext delegate) {
+ this.delegate = delegate;
+ }
+
+ private final ExpressionEvaluationContext delegate;
+
+ @Override
+ public Map<String, Serializable> getCtx() {
+ return delegate.getCtx();
+ }
+
+ }
+
+ @Override
+ public boolean evaluate(final ExpressionEvaluationContext expressionContext,
+ final String expression) {
+ Objects.requireNonNull(expression, "Expression must not be null.");
+ log.trace("Evaluating '{}'.", expression);
+
+ final Expression expr = parser.parseExpression(expression);
+ Boolean result = null;
+ try {
+ result = expr.getValue(evaluationContext,
+ new SpringWebExpressionEvaluationContext(expressionContext), Boolean.class);
+ if (result == null) {
+ log.debug("Evaluation of '{}' results in null-value.", expression);
+ } else {
+ log.debug("Expression '{}' -> {}", expression, result);
+ }
+ } catch (final Exception e) {
+ log.warn("Expression '{}' could not be processed.", expression, e);
+ }
+
+ return BooleanUtils.isTrue(result);
+ }
}