public static <T extends ProcessNode<T, M>, M extends ProcessModelBase<T, M>> M deserialize( final DeserializationFactory<T, M> factory, final M processModel, final XmlReader in) throws XmlException { XmlReaderUtil.skipPreamble(in); final QName elementName = ELEMENTNAME; assert XmlReaderUtil.isElement(in, elementName) : "Expected " + elementName + " but found " + in.getLocalName(); for (int i = in.getAttributeCount() - 1; i >= 0; --i) { processModel.deserializeAttribute( in.getAttributeNamespace(i), in.getAttributeLocalName(i), in.getAttributeValue(i)); } EventType event = null; loop: while (in.hasNext() && event != XmlStreaming.END_ELEMENT) { switch ((event = in.next())) { case START_ELEMENT: if (processModel.deserializeChild(factory, in)) { continue loop; } XmlReaderUtil.unhandledEvent(in); break; case TEXT: case CDSECT: if (false) { continue loop; } default: XmlReaderUtil.unhandledEvent(in); } } for (final T node : processModel.getModelNodes()) { for (final Identifiable pred : node.getPredecessors()) { final T predNode = processModel.getNode(pred); if (predNode != null) { predNode.addSuccessor(node); } } } return processModel; }
/** * Normalize the process model. By default this may do nothing. * * @return The model (this). */ public M normalize(SplitFactory<? extends T, M> splitFactory) { ensureIds(); // Make all nodes directly refer to other nodes. for (T childNode : mProcessNodes) { childNode.resolveRefs(); } for (T childNode : mProcessNodes) { // Create a copy as we are actually going to remove all successors, but need to keep the list ArrayList<Identifiable> successors = new ArrayList<>(childNode.getSuccessors()); if (successors.size() > 1 && !(childNode instanceof Split)) { for (Identifiable suc2 : successors) { // Remove the current node as predecessor. ProcessNode<?, ?> suc = (ProcessNode) suc2; suc.removePredecessor(childNode); childNode.removeSuccessor(suc); // remove the predecessor from the current node } // create a new join, this should Split<? extends T, M> newSplit = splitFactory.createSplit(asM(), successors); childNode.addSuccessor(newSplit); } } return this.asM(); }