/* * 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.factory; import java.util.ArrayList; import java.util.List; import javax.enterprise.context.Dependent; import javax.inject.Inject; import org.kie.workbench.common.stunner.bpmn.definition.BPMNDiagram; import org.kie.workbench.common.stunner.bpmn.definition.BPMNDiagramImpl; import org.kie.workbench.common.stunner.bpmn.definition.StartNoneEvent; import org.kie.workbench.common.stunner.core.api.DefinitionManager; import org.kie.workbench.common.stunner.core.api.FactoryManager; import org.kie.workbench.common.stunner.core.command.Command; import org.kie.workbench.common.stunner.core.command.impl.CompositeCommandImpl; import org.kie.workbench.common.stunner.core.factory.graph.ElementFactory; import org.kie.workbench.common.stunner.core.factory.impl.AbstractGraphFactory; import org.kie.workbench.common.stunner.core.graph.Edge; import org.kie.workbench.common.stunner.core.graph.Graph; import org.kie.workbench.common.stunner.core.graph.Node; import org.kie.workbench.common.stunner.core.graph.command.EmptyRulesCommandExecutionContext; import org.kie.workbench.common.stunner.core.graph.command.GraphCommandExecutionContext; import org.kie.workbench.common.stunner.core.graph.command.GraphCommandManager; import org.kie.workbench.common.stunner.core.graph.command.impl.GraphCommandFactory; import org.kie.workbench.common.stunner.core.graph.content.definition.Definition; import org.kie.workbench.common.stunner.core.graph.content.definition.DefinitionSet; import org.kie.workbench.common.stunner.core.graph.processing.index.GraphIndexBuilder; import org.kie.workbench.common.stunner.core.graph.processing.index.Index; import org.kie.workbench.common.stunner.core.rule.RuleManager; import org.kie.workbench.common.stunner.core.util.UUID; /** * The custom factory for BPMN graphs. * It initializes the BPMN graph with a new Diagram node instance, which represents the main process. * This class uses the Commands API in order to avoid adding nodes/edges and setting bean values manually on the graph structure, * so this will avoid further errors, but in fact there should be not need to check runtime rules when executing * these commands. */ @Dependent public class BPMNGraphFactoryImpl extends AbstractGraphFactory implements BPMNGraphFactory { static final double START_X = 100d; static final double START_Y = 100d; private final DefinitionManager definitionManager; private final RuleManager ruleManager; private final GraphIndexBuilder<?> indexBuilder; private final GraphCommandManager graphCommandManager; private final GraphCommandFactory graphCommandFactory; private final FactoryManager factoryManager; private Class<? extends BPMNDiagram> diagramType; protected BPMNGraphFactoryImpl() { this(null, null, null, null, null, null); } @Inject public BPMNGraphFactoryImpl(final DefinitionManager definitionManager, final FactoryManager factoryManager, final RuleManager ruleManager, final GraphCommandManager graphCommandManager, final GraphCommandFactory graphCommandFactory, final GraphIndexBuilder<?> indexBuilder) { this.definitionManager = definitionManager; this.factoryManager = factoryManager; this.ruleManager = ruleManager; this.graphCommandManager = graphCommandManager; this.graphCommandFactory = graphCommandFactory; this.indexBuilder = indexBuilder; this.diagramType = BPMNDiagramImpl.class; } public void setDiagramType(final Class<? extends BPMNDiagram> diagramType) { this.diagramType = diagramType; } @Override public Class<? extends ElementFactory> getFactoryType() { return BPMNGraphFactory.class; } @Override @SuppressWarnings("unchecked") public Graph<DefinitionSet, Node> build(final String uuid, final String definitionSetId) { final Graph<DefinitionSet, Node> graph = super.build(uuid, definitionSetId); //Add default elements final List<Command> commands = buildInitialisationCommands(); final CompositeCommandImpl.CompositeCommandBuilder commandBuilder = new CompositeCommandImpl.CompositeCommandBuilder(); commands.forEach(commandBuilder::addCommand); graphCommandManager.execute(createGraphContext(graph), commandBuilder.build()); return graph; } @Override public boolean accepts(final String source) { return true; } @Override protected double getWidth() { return GRAPH_DEFAULT_WIDTH; } @Override protected double getHeight() { return GRAPH_DEFAULT_HEIGHT; } @SuppressWarnings("unchecked") // Add a BPMN diagram and a start event nodes by default. protected List<Command> buildInitialisationCommands() { final List<Command> commands = new ArrayList<>(); final Node<Definition<BPMNDiagram>, Edge> diagramNode = (Node<Definition<BPMNDiagram>, Edge>) factoryManager.newElement(UUID.uuid(), diagramType); final Node<Definition<StartNoneEvent>, Edge> startEventNode = (Node<Definition<StartNoneEvent>, Edge>) factoryManager.newElement(UUID.uuid(), StartNoneEvent.class); commands.add(graphCommandFactory.addNode(diagramNode)); commands.add(graphCommandFactory.addChildNode(diagramNode, startEventNode, START_X, START_Y)); return commands; } @SuppressWarnings("unchecked") protected GraphCommandExecutionContext createGraphContext(final Graph graph) { final Index<?, ?> index = indexBuilder.build(graph); return new EmptyRulesCommandExecutionContext(definitionManager, factoryManager, ruleManager, index); } @Override protected DefinitionManager getDefinitionManager() { return definitionManager; } }