use of org.kie.workbench.common.stunner.core.diagram.Diagram in project kie-wb-common by kiegroup.
the class DMNMarshallerStandalone method unmarshall.
@Override
@SuppressWarnings("unchecked")
public Graph unmarshall(final Metadata metadata, final InputStream input) throws IOException {
final Map<String, HasComponentWidths> hasComponentWidthsMap = new HashMap<>();
final BiConsumer<String, HasComponentWidths> hasComponentWidthsConsumer = (uuid, hcw) -> {
if (Objects.nonNull(uuid)) {
hasComponentWidthsMap.put(uuid, hcw);
}
};
final org.kie.dmn.model.api.Definitions dmnXml = marshaller.unmarshal(new InputStreamReader(input));
final List<org.kie.dmn.model.api.DRGElement> diagramDrgElements = dmnXml.getDrgElement();
final Optional<org.kie.dmn.model.api.dmndi.DMNDiagram> dmnDDDiagram = findDMNDiagram(dmnXml);
// Get external DMN model information
final Map<Import, org.kie.dmn.model.api.Definitions> importDefinitions = dmnMarshallerImportsHelper.getImportDefinitions(metadata, dmnXml.getImport());
// Get external PMML model information
final Map<Import, PMMLDocumentMetadata> pmmlDocuments = dmnMarshallerImportsHelper.getPMMLDocuments(metadata, dmnXml.getImport());
// Map external DRGElements
final List<DMNShape> dmnShapes = dmnDDDiagram.map(this::getUniqueDMNShapes).orElse(emptyList());
final List<org.kie.dmn.model.api.DRGElement> importedDrgElements = getImportedDrgElementsByShape(dmnShapes, importDefinitions);
// Group DRGElements
final List<org.kie.dmn.model.api.DRGElement> drgElements = new ArrayList<>();
drgElements.addAll(diagramDrgElements);
drgElements.addAll(importedDrgElements);
// Remove DRGElements that doesn't have any local or imported shape.
removeDrgElementsWithoutShape(drgElements, dmnShapes);
final Map<String, Entry<org.kie.dmn.model.api.DRGElement, Node>> elems = drgElements.stream().collect(toMap(org.kie.dmn.model.api.DRGElement::getId, dmn -> new SimpleEntry<>(dmn, dmnToStunner(dmn, hasComponentWidthsConsumer, importedDrgElements))));
final Set<org.kie.dmn.model.api.DecisionService> dmnDecisionServices = new HashSet<>();
// Stunner rely on relative positioning for Edge connections, so need to cycle on DMNShape first.
for (Entry<org.kie.dmn.model.api.DRGElement, Node> kv : elems.values()) {
ddExtAugmentStunner(dmnDDDiagram, kv.getValue());
}
// Setup Node Relationships and Connections all based on absolute positioning
for (Entry<org.kie.dmn.model.api.DRGElement, Node> kv : elems.values()) {
final org.kie.dmn.model.api.DRGElement elem = kv.getKey();
final Node currentNode = kv.getValue();
// For imported nodes, we don't have its connections
if (isImportedDRGElement(importedDrgElements, elem)) {
continue;
}
// DMN spec table 2: Requirements connection rules
if (elem instanceof org.kie.dmn.model.api.Decision) {
final org.kie.dmn.model.api.Decision decision = (org.kie.dmn.model.api.Decision) elem;
for (org.kie.dmn.model.api.InformationRequirement ir : decision.getInformationRequirement()) {
connectEdgeToNodes(INFO_REQ_ID, ir, ir.getRequiredInput(), elems, dmnXml, currentNode);
connectEdgeToNodes(INFO_REQ_ID, ir, ir.getRequiredDecision(), elems, dmnXml, currentNode);
}
for (org.kie.dmn.model.api.KnowledgeRequirement kr : decision.getKnowledgeRequirement()) {
connectEdgeToNodes(KNOWLEDGE_REQ_ID, kr, kr.getRequiredKnowledge(), elems, dmnXml, currentNode);
}
for (org.kie.dmn.model.api.AuthorityRequirement ar : decision.getAuthorityRequirement()) {
connectEdgeToNodes(AUTH_REQ_ID, ar, ar.getRequiredAuthority(), elems, dmnXml, currentNode);
}
} else if (elem instanceof org.kie.dmn.model.api.BusinessKnowledgeModel) {
final org.kie.dmn.model.api.BusinessKnowledgeModel bkm = (org.kie.dmn.model.api.BusinessKnowledgeModel) elem;
for (org.kie.dmn.model.api.KnowledgeRequirement kr : bkm.getKnowledgeRequirement()) {
connectEdgeToNodes(KNOWLEDGE_REQ_ID, kr, kr.getRequiredKnowledge(), elems, dmnXml, currentNode);
}
for (org.kie.dmn.model.api.AuthorityRequirement ar : bkm.getAuthorityRequirement()) {
connectEdgeToNodes(AUTH_REQ_ID, ar, ar.getRequiredAuthority(), elems, dmnXml, currentNode);
}
} else if (elem instanceof org.kie.dmn.model.api.KnowledgeSource) {
final org.kie.dmn.model.api.KnowledgeSource ks = (org.kie.dmn.model.api.KnowledgeSource) elem;
for (org.kie.dmn.model.api.AuthorityRequirement ar : ks.getAuthorityRequirement()) {
connectEdgeToNodes(AUTH_REQ_ID, ar, ar.getRequiredInput(), elems, dmnXml, currentNode);
connectEdgeToNodes(AUTH_REQ_ID, ar, ar.getRequiredDecision(), elems, dmnXml, currentNode);
connectEdgeToNodes(AUTH_REQ_ID, ar, ar.getRequiredAuthority(), elems, dmnXml, currentNode);
}
} else if (elem instanceof org.kie.dmn.model.api.DecisionService) {
final org.kie.dmn.model.api.DecisionService ds = (org.kie.dmn.model.api.DecisionService) elem;
dmnDecisionServices.add(ds);
for (org.kie.dmn.model.api.DMNElementReference er : ds.getEncapsulatedDecision()) {
final String reqInputID = getId(er);
final Node requiredNode = getRequiredNode(elems, reqInputID);
if (Objects.nonNull(requiredNode)) {
connectDSChildEdge(currentNode, requiredNode);
}
}
for (org.kie.dmn.model.api.DMNElementReference er : ds.getOutputDecision()) {
final String reqInputID = getId(er);
final Node requiredNode = getRequiredNode(elems, reqInputID);
if (Objects.nonNull(requiredNode)) {
connectDSChildEdge(currentNode, requiredNode);
}
}
}
}
final Map<String, Node<View<TextAnnotation>, ?>> textAnnotations = dmnXml.getArtifact().stream().filter(org.kie.dmn.model.api.TextAnnotation.class::isInstance).map(org.kie.dmn.model.api.TextAnnotation.class::cast).collect(Collectors.toMap(org.kie.dmn.model.api.TextAnnotation::getId, dmn -> textAnnotationConverter.nodeFromDMN(dmn, hasComponentWidthsConsumer)));
textAnnotations.values().forEach(n -> ddExtAugmentStunner(dmnDDDiagram, n));
final List<org.kie.dmn.model.api.Association> associations = dmnXml.getArtifact().stream().filter(org.kie.dmn.model.api.Association.class::isInstance).map(org.kie.dmn.model.api.Association.class::cast).collect(Collectors.toList());
for (org.kie.dmn.model.api.Association a : associations) {
final String sourceId = getId(a.getSourceRef());
final Node sourceNode = Optional.ofNullable(elems.get(sourceId)).map(Entry::getValue).orElse(textAnnotations.get(sourceId));
final String targetId = getId(a.getTargetRef());
final Node targetNode = Optional.ofNullable(elems.get(targetId)).map(Entry::getValue).orElse(textAnnotations.get(targetId));
@SuppressWarnings("unchecked") final Edge<View<Association>, ?> myEdge = (Edge<View<Association>, ?>) factoryManager.newElement(idOfDMNorWBUUID(a), ASSOCIATION_ID).asEdge();
final Id id = new Id(a.getId());
final Description description = new Description(a.getDescription());
final Association definition = new Association(id, description);
myEdge.getContent().setDefinition(definition);
connectEdge(myEdge, sourceNode, targetNode);
setConnectionMagnets(myEdge, a.getId(), dmnXml);
}
// Ensure all locations are updated to relative for Stunner
for (Entry<org.kie.dmn.model.api.DRGElement, Node> kv : elems.values()) {
PointUtils.convertToRelativeBounds(kv.getValue());
}
final Graph graph = factoryManager.newDiagram("prova", BindableAdapterUtils.getDefinitionSetId(DMNDefinitionSet.class), metadata).getGraph();
elems.values().stream().map(Map.Entry::getValue).forEach(graph::addNode);
textAnnotations.values().forEach(graph::addNode);
final Node<?, ?> dmnDiagramRoot = findDMNDiagramRoot(graph);
final Definitions definitionsStunnerPojo = DefinitionsConverter.wbFromDMN(dmnXml, importDefinitions, pmmlDocuments);
loadImportedItemDefinitions(definitionsStunnerPojo, importDefinitions);
((View<DMNDiagram>) dmnDiagramRoot.getContent()).getDefinition().setDefinitions(definitionsStunnerPojo);
// Only connect Nodes to the Diagram that are not referenced by DecisionServices
final List<String> references = new ArrayList<>();
dmnDecisionServices.forEach(ds -> references.addAll(ds.getEncapsulatedDecision().stream().map(org.kie.dmn.model.api.DMNElementReference::getHref).collect(Collectors.toList())));
dmnDecisionServices.forEach(ds -> references.addAll(ds.getOutputDecision().stream().map(org.kie.dmn.model.api.DMNElementReference::getHref).collect(Collectors.toList())));
final Map<org.kie.dmn.model.api.DRGElement, Node> elemsToConnectToRoot = elems.values().stream().filter(elem -> !references.contains("#" + elem.getKey().getId())).collect(Collectors.toMap(Entry::getKey, Entry::getValue));
elemsToConnectToRoot.values().stream().forEach(node -> connectRootWithChild(dmnDiagramRoot, node));
textAnnotations.values().stream().forEach(node -> connectRootWithChild(dmnDiagramRoot, node));
// Copy ComponentWidths information
final Optional<ComponentsWidthsExtension> extension = findComponentsWidthsExtension(dmnDDDiagram);
extension.ifPresent(componentsWidthsExtension -> {
// can be imported from another diagram but the extension is not imported or present in this diagram.
if (componentsWidthsExtension.getComponentsWidths() != null) {
hasComponentWidthsMap.forEach((uuid, hasComponentWidths) -> componentsWidthsExtension.getComponentsWidths().stream().filter(componentWidths -> componentWidths.getDmnElementRef().getLocalPart().equals(uuid)).findFirst().ifPresent(componentWidths -> {
final List<Double> widths = hasComponentWidths.getComponentWidths();
widths.clear();
widths.addAll(componentWidths.getWidths());
}));
}
});
return graph;
}
use of org.kie.workbench.common.stunner.core.diagram.Diagram in project kie-wb-common by kiegroup.
the class DMNUnmarshaller method unmarshall.
private Promise<Graph> unmarshall(final Metadata metadata, final JSITDefinitions dmnDefinitions, final Map<JSITImport, JSITDefinitions> importDefinitions, final Map<JSITImport, PMMLDocumentMetadata> pmmlDocuments) {
final Map<String, HasComponentWidths> hasComponentWidthsMap = new HashMap<>();
final BiConsumer<String, HasComponentWidths> hasComponentWidthsConsumer = (uuid, hcw) -> {
if (Objects.nonNull(uuid)) {
hasComponentWidthsMap.put(uuid, hcw);
}
};
// Check before the DRG creation ('ensureDRGElementExists').
final boolean isDMNDIPresent = Optional.ofNullable(dmnDefinitions.getDMNDI()).isPresent();
ensureDRGElementExists(dmnDefinitions);
final Definitions wbDefinitions = DefinitionsConverter.wbFromDMN(dmnDefinitions, importDefinitions, pmmlDocuments);
final List<NodeEntry> nodeEntries = modelToStunnerConverter.makeNodes(dmnDefinitions, importDefinitions, isDMNDIPresent, hasComponentWidthsConsumer);
final List<JSITDecisionService> dmnDecisionServices = getDecisionServices(nodeEntries);
// Ensure all locations are updated to relative for Stunner
nodeEntries.forEach(e -> PointUtils.convertToRelativeBounds(e.getNode()));
final Map<String, Diagram> stunnerDiagramsById = new HashMap<>();
final Map<String, DMNDiagramElement> dmnDiagramsById = new HashMap<>();
for (final DMNDiagramElement dmnDiagramElement : wbDefinitions.getDiagramElements()) {
final String dmnDiagramId = dmnDiagramElement.getId().getValue();
final Diagram value = factoryManager.newDiagram(dmnDiagramId, BindableAdapterUtils.getDefinitionSetId(DMNDefinitionSet.class), metadata);
stunnerDiagramsById.put(dmnDiagramId, value);
dmnDiagramsById.put(dmnDiagramId, dmnDiagramElement);
}
final DMNDiagramsSessionState state = dmnDiagramsSession.setState(metadata, stunnerDiagramsById, dmnDiagramsById);
nodeEntries.forEach(nodeEntry -> {
final String diagramId = nodeEntry.getDiagramId();
final Graph graph = stunnerDiagramsById.get(diagramId).getGraph();
graph.addNode(nodeEntry.getNode());
});
final Graph drgGraph = state.getDRGDiagram().getGraph();
loadImportedItemDefinitions(wbDefinitions, importDefinitions);
for (final Diagram value : stunnerDiagramsById.values()) {
final Node<?, ?> dmnDiagramRoot = DMNGraphUtils.findDMNDiagramRoot(value.getGraph());
((View<DMNDiagram>) dmnDiagramRoot.getContent()).getDefinition().setDefinitions(wbDefinitions);
nodeEntries.forEach(nodeEntry -> {
if (Objects.equals(stunnerDiagramsById.get(nodeEntry.getDiagramId()), value)) {
connectRootWithChild(dmnDiagramRoot, nodeEntry.getNode());
}
});
}
// Only connect Nodes to the Diagram that are not referenced by DecisionServices
final List<String> references = new ArrayList<>();
final List<JSITDecisionService> lstDecisionServices = new ArrayList<>(dmnDecisionServices);
for (int iDS = 0; iDS < lstDecisionServices.size(); iDS++) {
final JSITDecisionService jsiDecisionService = Js.uncheckedCast(lstDecisionServices.get(iDS));
final List<JSITDMNElementReference> jsiEncapsulatedDecisions = jsiDecisionService.getEncapsulatedDecision();
if (Objects.nonNull(jsiEncapsulatedDecisions)) {
for (int i = 0; i < jsiEncapsulatedDecisions.size(); i++) {
final JSITDMNElementReference jsiEncapsulatedDecision = Js.uncheckedCast(jsiEncapsulatedDecisions.get(i));
references.add(jsiEncapsulatedDecision.getHref());
}
}
final List<JSITDMNElementReference> jsiOutputDecisions = jsiDecisionService.getOutputDecision();
if (Objects.nonNull(jsiOutputDecisions)) {
for (int i = 0; i < jsiOutputDecisions.size(); i++) {
final JSITDMNElementReference jsiOutputDecision = Js.uncheckedCast(jsiOutputDecisions.get(i));
references.add(jsiOutputDecision.getHref());
}
}
}
// Copy ComponentWidths information
final List<JSITComponentsWidthsExtension> extensions = findComponentsWidthsExtensions(dmnDefinitions.getDMNDI().getDMNDiagram());
extensions.forEach(componentsWidthsExtension -> {
// can be imported from another diagram but the extension is not imported or present in this diagram.
if (Objects.nonNull(componentsWidthsExtension.getComponentWidths())) {
hasComponentWidthsMap.entrySet().forEach(es -> {
final List<JSITComponentWidths> jsiComponentWidths = componentsWidthsExtension.getComponentWidths();
for (int i = 0; i < jsiComponentWidths.size(); i++) {
final JSITComponentWidths jsiWidths = Js.uncheckedCast(jsiComponentWidths.get(i));
if (Objects.equals(jsiWidths.getDmnElementRef(), es.getKey())) {
final List<Double> widths = es.getValue().getComponentWidths();
if (Objects.nonNull(jsiWidths.getWidth())) {
widths.clear();
for (int w = 0; w < jsiWidths.getWidth().size(); w++) {
final double width = jsiWidths.getWidth().get(w).doubleValue();
widths.add(width);
}
}
}
}
});
}
});
return promises.resolve(drgGraph);
}
use of org.kie.workbench.common.stunner.core.diagram.Diagram in project kie-wb-common by kiegroup.
the class DMNSetConnectionSourceNodeCommandTest method testGetEdgesGraph.
@Test
public void testGetEdgesGraph() {
final String diagramId = "diagram id";
final Diagram diagram = mock(Diagram.class);
final Graph graph = mock(Graph.class);
doReturn(Optional.of(diagramId)).when(command).getDiagramId();
when(diagram.getGraph()).thenReturn(graph);
when(graphsProvider.getDiagram(diagramId)).thenReturn(diagram);
final Graph actualGraph = command.getEdgesGraph();
assertEquals(graph, actualGraph);
}
use of org.kie.workbench.common.stunner.core.diagram.Diagram in project kie-wb-common by kiegroup.
the class SessionEventObserver method onSessionDiagramSavedEvent.
void onSessionDiagramSavedEvent(@Observes final SessionDiagramSavedEvent event) {
final Diagram currentDiagram = event.getSession().getCanvasHandler().getDiagram();
sessionDiagramSavedHandlers.stream().filter(handler -> handler.accepts(currentDiagram)).forEach(handler -> handler.onSessionDiagramSaved(event.getSession()));
}
use of org.kie.workbench.common.stunner.core.diagram.Diagram in project kie-wb-common by kiegroup.
the class SessionEventObserver method onSessionDiagramOpenedEvent.
void onSessionDiagramOpenedEvent(@Observes final SessionDiagramOpenedEvent event) {
final Diagram currentDiagram = event.getSession().getCanvasHandler().getDiagram();
sessionDiagramOpenedHandlers.stream().filter(handler -> handler.accepts(currentDiagram)).forEach(handler -> handler.onSessionDiagramOpened(event.getSession()));
}
Aggregations