/* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.kie.workbench.common.stunner.bpmn.backend.marshall.json.builder; import org.kie.workbench.common.stunner.bpmn.definition.BPMNDefinition; import org.kie.workbench.common.stunner.core.api.FactoryManager; import org.kie.workbench.common.stunner.core.command.CommandResult; import org.kie.workbench.common.stunner.core.graph.Edge; import org.kie.workbench.common.stunner.core.graph.Node; import org.kie.workbench.common.stunner.core.graph.command.impl.AddNodeCommand; import org.kie.workbench.common.stunner.core.graph.command.impl.SetConnectionTargetNodeCommand; import org.kie.workbench.common.stunner.core.graph.content.view.View; import org.kie.workbench.common.stunner.core.graph.processing.index.MutableIndex; import org.kie.workbench.common.stunner.core.rule.RuleViolation; // TODO: Improve error handling. public abstract class AbstractEdgeBuilder<W, T extends Edge<View<W>, Node>> extends AbstractObjectBuilder<W, T> implements EdgeObjectBuilder<W, T> { protected final Class<?> definitionClass; public AbstractEdgeBuilder(final Class<?> definitionClass) { this.definitionClass = definitionClass; } @Override public Class<?> getDefinitionClass() { return definitionClass; } @Override @SuppressWarnings("unchecked") protected T doBuild(final BuilderContext context) { FactoryManager factoryManager = context.getFactoryManager(); String definitionId = context.getOryxManager().getMappingsManager().getDefinitionId(definitionClass); T result = (T) factoryManager.newElement(this.nodeId, definitionId); setProperties(context, (BPMNDefinition) result.getContent().getDefinition()); addEdgeIntoIndex(context, result); afterEdgeBuild(context, result); return result; } @SuppressWarnings("unchecked") protected void afterEdgeBuild(final BuilderContext context, final T edge) { // Outgoing connections. if (outgoingResourceIds != null && !outgoingResourceIds.isEmpty()) { for (String outgoingNodeId : outgoingResourceIds) { GraphObjectBuilder<?, ?> outgoingNodeBuilder = getBuilder(context, outgoingNodeId); if (outgoingNodeBuilder == null) { throw new RuntimeException("No edge for " + outgoingNodeId); } Node node = (Node) outgoingNodeBuilder.build(context); // Command - Add the node into the graph store. AddNodeCommand addNodeCommand = context.getCommandFactory().addNode(node); // Command - Set the edge connection's target node. int magnetIdx = ((AbstractNodeBuilder) outgoingNodeBuilder).getTargetConnectionMagnetIndex(context, node, edge); SetConnectionTargetNodeCommand setTargetNodeCommand = context.getCommandFactory().setTargetNode(node, edge, magnetIdx); CommandResult<RuleViolation> results1 = context.execute(addNodeCommand); if (hasErrors(results1)) { throw new RuntimeException("Error building BPMN graph. Command 'addNodeCommand' execution failed."); } CommandResult<RuleViolation> results2 = context.execute(setTargetNodeCommand); if (hasErrors(results2)) { throw new RuntimeException("Error building BPMN graph. Command 'SetConnectionTargetNodeCommand' execution failed."); } } } } @SuppressWarnings("unchecked") protected void addEdgeIntoIndex(final BuilderContext context, final T edge) { MutableIndex<Node, Edge> index = (MutableIndex<Node, Edge>) context.getIndex(); index.addEdge(edge); } @Override public String toString() { return new StringBuilder(super.toString()).append(" [defClass=").append(definitionClass.getName()).append("] ").toString(); } }