aboutsummaryrefslogtreecommitdiff
path: root/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/process/ProcessDefinitionParser.java
diff options
context:
space:
mode:
Diffstat (limited to 'id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/process/ProcessDefinitionParser.java')
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/process/ProcessDefinitionParser.java224
1 files changed, 0 insertions, 224 deletions
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/process/ProcessDefinitionParser.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/process/ProcessDefinitionParser.java
deleted file mode 100644
index 162ee624a..000000000
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/process/ProcessDefinitionParser.java
+++ /dev/null
@@ -1,224 +0,0 @@
-package at.gv.egovernment.moa.id.process;
-
-import java.io.IOException;
-import java.io.InputStream;
-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;
-import javax.xml.stream.XMLInputFactory;
-import javax.xml.stream.XMLStreamConstants;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.stream.events.Attribute;
-import javax.xml.stream.events.StartElement;
-import javax.xml.stream.events.XMLEvent;
-import javax.xml.stream.util.EventReaderDelegate;
-import javax.xml.transform.stax.StAXSource;
-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.egovernment.moa.id.process.model.EndEvent;
-import at.gv.egovernment.moa.id.process.model.ProcessDefinition;
-import at.gv.egovernment.moa.id.process.model.ProcessNode;
-import at.gv.egovernment.moa.id.process.model.StartEvent;
-import at.gv.egovernment.moa.id.process.model.TaskInfo;
-import at.gv.egovernment.moa.id.process.model.Transition;
-
-/**
- * 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("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
- }
- }
- }
- }
-
-}