Search in sources :

Example 1 with RuleSet

use of org.kie.workbench.common.stunner.core.rule.RuleSet in project kie-wb-common by kiegroup.

the class GraphValidatorImplTest method testValidateEmptyViewConnectorNodes.

@Test
@SuppressWarnings("unchecked")
public void testValidateEmptyViewConnectorNodes() {
    final RuleSet ruleSet = graphTestHandler.ruleSet;
    final Graph<DefinitionSet, Node> graph = graphTestHandler.graph;
    final TestingGraphInstanceBuilder.TestGraph1 testGraph1 = TestingGraphInstanceBuilder.newGraph1(graphTestHandler);
    // Update the edge2 and remove the connection's target node.
    // From this point, a validation error is expected.
    graphTestHandler.removeTargetConnection(testGraph1.edge2);
    tested.validate(graph, ruleSet, ruleViolations -> {
        assertEquals(1, ruleViolations.size());
        final RuleViolation violation = ruleViolations.iterator().next();
        assertNotNull(violation);
        assertTrue(violation instanceof EmptyConnectionViolation);
        EmptyConnectionViolation v = (EmptyConnectionViolation) violation;
        final Optional<Object[]> arguments = v.getArguments();
        assertTrue(arguments.isPresent());
        assertEquals(testGraph1.edge2.getUUID(), arguments.get()[0]);
        assertEquals(testGraph1.intermNode.getUUID(), arguments.get()[1]);
        assertNull(arguments.get()[2]);
    });
}
Also used : RuleSet(org.kie.workbench.common.stunner.core.rule.RuleSet) EmptyConnectionViolation(org.kie.workbench.common.stunner.core.rule.violations.EmptyConnectionViolation) TestingGraphInstanceBuilder(org.kie.workbench.common.stunner.core.TestingGraphInstanceBuilder) Node(org.kie.workbench.common.stunner.core.graph.Node) DefinitionSet(org.kie.workbench.common.stunner.core.graph.content.definition.DefinitionSet) RuleViolation(org.kie.workbench.common.stunner.core.rule.RuleViolation) Test(org.junit.Test)

Example 2 with RuleSet

use of org.kie.workbench.common.stunner.core.rule.RuleSet in project kie-wb-common by kiegroup.

the class GraphValidatorImplTest method testValidateGraph2.

@Test
@SuppressWarnings("unchecked")
public void testValidateGraph2() {
    final RuleManager ruleManager = graphTestHandler.ruleManager;
    final RuleSet ruleSet = graphTestHandler.ruleSet;
    final Graph<DefinitionSet, Node> graph = graphTestHandler.graph;
    final TestingGraphInstanceBuilder.TestGraph2 testGraph2 = TestingGraphInstanceBuilder.newGraph2(graphTestHandler);
    tested.validate(getGraph(), graphTestHandler.ruleSet, this::assertNoError);
    final int evalCount = testGraph2.evaluationsCount + 11;
    final ArgumentCaptor<RuleEvaluationContext> contextCaptor = ArgumentCaptor.forClass(RuleEvaluationContext.class);
    verify(ruleManager, times(evalCount)).evaluate(eq(ruleSet), contextCaptor.capture());
    final List<RuleEvaluationContext> contexts = contextCaptor.getAllValues();
    assertEquals(evalCount, contexts.size());
    int cindex = testGraph2.evaluationsCount;
    verifyCardinality((ElementCardinalityContext) contexts.get(cindex++), graph);
    verifyContainment((NodeContainmentContext) contexts.get(cindex++), graph, testGraph2.parentNode);
    verifyContainment((NodeContainmentContext) contexts.get(cindex++), testGraph2.parentNode, testGraph2.startNode);
    verifyConnection((GraphConnectionContext) contexts.get(cindex++), testGraph2.edge1, testGraph2.startNode, testGraph2.intermNode);
    verifyConnectorCardinality((ConnectorCardinalityContext) contexts.get(cindex++), graph, testGraph2.intermNode, testGraph2.edge1, EdgeCardinalityContext.Direction.INCOMING, Optional.empty());
    verifyConnectorCardinality((ConnectorCardinalityContext) contexts.get(cindex++), graph, testGraph2.startNode, testGraph2.edge1, EdgeCardinalityContext.Direction.OUTGOING, Optional.empty());
    verifyContainment((NodeContainmentContext) contexts.get(cindex++), testGraph2.parentNode, testGraph2.intermNode);
    verifyConnection((GraphConnectionContext) contexts.get(cindex++), testGraph2.edge2, testGraph2.intermNode, testGraph2.endNode);
    verifyConnectorCardinality((ConnectorCardinalityContext) contexts.get(cindex++), graph, testGraph2.endNode, testGraph2.edge2, EdgeCardinalityContext.Direction.INCOMING, Optional.empty());
    verifyConnectorCardinality((ConnectorCardinalityContext) contexts.get(cindex++), graph, testGraph2.intermNode, testGraph2.edge2, EdgeCardinalityContext.Direction.OUTGOING, Optional.empty());
    verifyContainment((NodeContainmentContext) contexts.get(cindex++), testGraph2.parentNode, testGraph2.endNode);
}
Also used : RuleSet(org.kie.workbench.common.stunner.core.rule.RuleSet) TestingGraphInstanceBuilder(org.kie.workbench.common.stunner.core.TestingGraphInstanceBuilder) Node(org.kie.workbench.common.stunner.core.graph.Node) RuleManager(org.kie.workbench.common.stunner.core.rule.RuleManager) RuleEvaluationContext(org.kie.workbench.common.stunner.core.rule.RuleEvaluationContext) DefinitionSet(org.kie.workbench.common.stunner.core.graph.content.definition.DefinitionSet) Test(org.junit.Test)

Example 3 with RuleSet

use of org.kie.workbench.common.stunner.core.rule.RuleSet in project kie-wb-common by kiegroup.

the class GraphValidatorImpl method validate.

/**
 * Performs the validation for the <code>graph</code> instance.
 * @param graph The instance to validate.
 * @param aRuleSet An optional rule set instance to validate against it. If not present, the default
 * rule set for the the graph will be used.
 * @param graphValidatorConsumer An optional consumer for the graph instance when is being validated.
 * @param nodeValidatorConsumer An optional consumer each node instance when being validated.
 * @param edgeValidatorConsumer An optional consumer each edge instance when being validated.
 * @param resultConsumer The consumer for all the resulting validation violations produced during the
 * validator for the graph, and all of its nodes and edges. It's being called once the
 * validation has been completed.
 */
@SuppressWarnings("unchecked")
void validate(final Graph graph, final Optional<RuleSet> aRuleSet, final Optional<BiConsumer<Graph, Collection<RuleViolation>>> graphValidatorConsumer, final Optional<BiConsumer<Node, Collection<RuleViolation>>> nodeValidatorConsumer, final Optional<BiConsumer<Edge, Collection<RuleViolation>>> edgeValidatorConsumer, Consumer<Collection<RuleViolation>> resultConsumer) {
    final RuleSet ruleSet = aRuleSet.orElse(getRuleSet(graph));
    final ViolationsSet violations = new ViolationsSet();
    treeWalkTraverseProcessor.traverse(graph, new AbstractTreeTraverseCallback<org.kie.workbench.common.stunner.core.graph.Graph, Node, Edge>() {

        private final Stack<Node> currentParents = new Stack<Node>();

        @Override
        public void startGraphTraversal(final org.kie.workbench.common.stunner.core.graph.Graph graph) {
            super.startGraphTraversal(graph);
            currentParents.clear();
            // Evaluate the graph's cardinality rules.
            final Set<RuleViolation> graphCardinalityViolations = violations.addViolations(evaluateCardinality(ruleSet, graph));
            graphValidatorConsumer.ifPresent(g -> g.accept(graph, graphCardinalityViolations));
        }

        @Override
        public boolean startEdgeTraversal(final Edge edge) {
            super.startEdgeTraversal(edge);
            final Object content = edge.getContent();
            final ViolationsSet edgeViolations = new ViolationsSet();
            if (content instanceof Child) {
                this.currentParents.push(edge.getSourceNode());
            } else if (content instanceof View) {
                final Optional<Node<? extends View<?>, ? extends Edge>> sourceOpt = Optional.ofNullable(edge.getSourceNode());
                final Optional<Node<? extends View<?>, ? extends Edge>> targetOpt = Optional.ofNullable(edge.getTargetNode());
                // Check not empty connections.
                final Optional<RuleViolation> emptyConnectionViolation = evaluateNotEmptyConnections(graph, edge, sourceOpt, targetOpt);
                emptyConnectionViolation.ifPresent(edgeViolations::add);
                // Evaluate connection rules.
                edgeViolations.addViolations(evaluateConnection(ruleSet, graph, edge, sourceOpt, targetOpt));
                // Evaluate connector cardinality rules for this edge.
                if (null != edge.getTargetNode()) {
                    edgeViolations.addViolations(evaluateIncomingEdgeCardinality(ruleSet, graph, edge));
                }
                if (null != edge.getSourceNode()) {
                    edgeViolations.addViolations(evaluateOutgoingEdgeCardinality(ruleSet, graph, edge));
                }
            } else if (content instanceof Dock) {
                final Node parent = edge.getSourceNode();
                final Node docked = edge.getTargetNode();
                // Evaluate docking rules for the source & target nodes.
                edgeViolations.addViolations(evaluateDocking(ruleSet, graph, parent, docked));
            }
            edgeValidatorConsumer.ifPresent(c -> c.accept(edge, edgeViolations));
            violations.addAll(edgeViolations);
            return true;
        }

        @Override
        public void endEdgeTraversal(final Edge edge) {
            super.endEdgeTraversal(edge);
            if (edge.getContent() instanceof Child) {
                this.currentParents.pop();
            }
        }

        @Override
        public boolean startNodeTraversal(final Node node) {
            super.startNodeTraversal(node);
            final Collection<RuleViolation> nodeViolations = evaluateNode(node, currentParents.isEmpty() ? null : currentParents.peek());
            nodeValidatorConsumer.ifPresent(c -> c.accept(node, nodeViolations));
            return true;
        }

        @Override
        public void endGraphTraversal() {
            super.endGraphTraversal();
            // Finished - feed the consumer instance.
            resultConsumer.accept(violations);
        }

        private Collection<RuleViolation> evaluateNode(final Node node, final Node parent) {
            // Evaluate containment rules for this node.
            return violations.addViolations(evaluateContainment(ruleSet, graph, null != parent ? parent : graph, node));
        }
    });
}
Also used : Edge(org.kie.workbench.common.stunner.core.graph.Edge) Stack(java.util.Stack) View(org.kie.workbench.common.stunner.core.graph.content.view.View) Inject(javax.inject.Inject) EdgeCardinalityContext(org.kie.workbench.common.stunner.core.rule.context.EdgeCardinalityContext) TreeWalkTraverseProcessor(org.kie.workbench.common.stunner.core.graph.processing.traverse.tree.TreeWalkTraverseProcessor) RuleViolation(org.kie.workbench.common.stunner.core.rule.RuleViolation) BiConsumer(java.util.function.BiConsumer) Element(org.kie.workbench.common.stunner.core.graph.Element) AbstractTreeTraverseCallback(org.kie.workbench.common.stunner.core.graph.processing.traverse.tree.AbstractTreeTraverseCallback) DefinitionManager(org.kie.workbench.common.stunner.core.api.DefinitionManager) LinkedHashSet(java.util.LinkedHashSet) Collection(java.util.Collection) Set(java.util.Set) Child(org.kie.workbench.common.stunner.core.graph.content.relationship.Child) RuleSet(org.kie.workbench.common.stunner.core.rule.RuleSet) Logger(java.util.logging.Logger) DefinitionSet(org.kie.workbench.common.stunner.core.graph.content.definition.DefinitionSet) RuleContextBuilder(org.kie.workbench.common.stunner.core.rule.context.impl.RuleContextBuilder) Definition(org.kie.workbench.common.stunner.core.graph.content.definition.Definition) EmptyConnectionViolation(org.kie.workbench.common.stunner.core.rule.violations.EmptyConnectionViolation) Consumer(java.util.function.Consumer) Graph(org.kie.workbench.common.stunner.core.graph.Graph) RuleViolations(org.kie.workbench.common.stunner.core.rule.RuleViolations) Optional(java.util.Optional) Dock(org.kie.workbench.common.stunner.core.graph.content.relationship.Dock) ApplicationScoped(javax.enterprise.context.ApplicationScoped) RuleManager(org.kie.workbench.common.stunner.core.rule.RuleManager) Node(org.kie.workbench.common.stunner.core.graph.Node) GraphValidator(org.kie.workbench.common.stunner.core.validation.GraphValidator) LinkedHashSet(java.util.LinkedHashSet) Set(java.util.Set) RuleSet(org.kie.workbench.common.stunner.core.rule.RuleSet) DefinitionSet(org.kie.workbench.common.stunner.core.graph.content.definition.DefinitionSet) Node(org.kie.workbench.common.stunner.core.graph.Node) RuleViolation(org.kie.workbench.common.stunner.core.rule.RuleViolation) Child(org.kie.workbench.common.stunner.core.graph.content.relationship.Child) RuleSet(org.kie.workbench.common.stunner.core.rule.RuleSet) View(org.kie.workbench.common.stunner.core.graph.content.view.View) Stack(java.util.Stack) Graph(org.kie.workbench.common.stunner.core.graph.Graph) Graph(org.kie.workbench.common.stunner.core.graph.Graph) Dock(org.kie.workbench.common.stunner.core.graph.content.relationship.Dock) Collection(java.util.Collection) Edge(org.kie.workbench.common.stunner.core.graph.Edge)

Example 4 with RuleSet

use of org.kie.workbench.common.stunner.core.rule.RuleSet in project kie-wb-common by kiegroup.

the class GraphValidatorImplTest method testValidateGraph1.

@Test
@SuppressWarnings("unchecked")
public void testValidateGraph1() {
    final RuleManager ruleManager = graphTestHandler.ruleManager;
    final RuleSet ruleSet = graphTestHandler.ruleSet;
    final Graph<DefinitionSet, Node> graph = graphTestHandler.graph;
    final TestingGraphInstanceBuilder.TestGraph1 testGraph1 = TestingGraphInstanceBuilder.newGraph1(graphTestHandler);
    tested.validate(graph, ruleSet, this::assertNoError);
    final int evalCount = testGraph1.evaluationsCount + 10;
    final ArgumentCaptor<RuleEvaluationContext> contextCaptor = ArgumentCaptor.forClass(RuleEvaluationContext.class);
    verify(ruleManager, times(evalCount)).evaluate(eq(ruleSet), contextCaptor.capture());
    final List<RuleEvaluationContext> contexts = contextCaptor.getAllValues();
    assertEquals(evalCount, contexts.size());
    int cindex = testGraph1.evaluationsCount;
    verifyCardinality((ElementCardinalityContext) contexts.get(cindex++), graph);
    verifyContainment((NodeContainmentContext) contexts.get(cindex++), graph, testGraph1.startNode);
    verifyConnection((GraphConnectionContext) contexts.get(cindex++), testGraph1.edge1, testGraph1.startNode, testGraph1.intermNode);
    verifyConnectorCardinality((ConnectorCardinalityContext) contexts.get(cindex++), graph, testGraph1.intermNode, testGraph1.edge1, EdgeCardinalityContext.Direction.INCOMING, Optional.empty());
    verifyConnectorCardinality((ConnectorCardinalityContext) contexts.get(cindex++), graph, testGraph1.startNode, testGraph1.edge1, EdgeCardinalityContext.Direction.OUTGOING, Optional.empty());
    verifyContainment((NodeContainmentContext) contexts.get(cindex++), graph, testGraph1.intermNode);
    verifyConnection((GraphConnectionContext) contexts.get(cindex++), testGraph1.edge2, testGraph1.intermNode, testGraph1.endNode);
    verifyConnectorCardinality((ConnectorCardinalityContext) contexts.get(cindex++), graph, testGraph1.endNode, testGraph1.edge2, EdgeCardinalityContext.Direction.INCOMING, Optional.empty());
    verifyConnectorCardinality((ConnectorCardinalityContext) contexts.get(cindex++), graph, testGraph1.intermNode, testGraph1.edge2, EdgeCardinalityContext.Direction.OUTGOING, Optional.empty());
    verifyContainment((NodeContainmentContext) contexts.get(cindex++), graph, testGraph1.endNode);
}
Also used : RuleSet(org.kie.workbench.common.stunner.core.rule.RuleSet) TestingGraphInstanceBuilder(org.kie.workbench.common.stunner.core.TestingGraphInstanceBuilder) Node(org.kie.workbench.common.stunner.core.graph.Node) RuleManager(org.kie.workbench.common.stunner.core.rule.RuleManager) RuleEvaluationContext(org.kie.workbench.common.stunner.core.rule.RuleEvaluationContext) DefinitionSet(org.kie.workbench.common.stunner.core.graph.content.definition.DefinitionSet) Test(org.junit.Test)

Example 5 with RuleSet

use of org.kie.workbench.common.stunner.core.rule.RuleSet in project kie-wb-common by kiegroup.

the class AbstractElementBuilderControl method allows.

@Override
@SuppressWarnings("unchecked")
public boolean allows(final ElementBuildRequest<AbstractCanvasHandler> request) {
    final double x = request.getX();
    final double y = request.getY();
    final Object definition = request.getDefinition();
    final Node<View<?>, Edge> parent = getParent(x, y);
    final Set<String> labels = clientDefinitionManager.adapters().forDefinition().getLabels(definition);
    final RuleSet ruleSet = canvasHandler.getRuleSet();
    // Check containment rules.
    if (null != parent) {
        final Object parentDef = parent.getContent().getDefinition();
        final Set<String> parentLabels = clientDefinitionManager.adapters().forDefinition().getLabels(parentDef);
        final RuleViolations containmentViolations = ruleManager.evaluate(ruleSet, RuleContextBuilder.DomainContexts.containment(parentLabels, labels));
        if (!isValid(containmentViolations)) {
            return false;
        }
    }
    // Check cardinality rules.
    final Map<String, Integer> graphLabelCount = GraphUtils.getLabelsCount(canvasHandler.getDiagram().getGraph(), labels);
    final DefaultRuleViolations cardinalityViolations = new DefaultRuleViolations();
    labels.forEach(role -> {
        final Integer roleCount = Optional.ofNullable(graphLabelCount.get(role)).orElse(0);
        final RuleViolations violations = ruleManager.evaluate(ruleSet, RuleContextBuilder.DomainContexts.cardinality(Collections.singleton(role), roleCount, Optional.of(CardinalityContext.Operation.ADD)));
        cardinalityViolations.addViolations(violations);
    });
    labels.stream().forEach(role -> {
    });
    return isValid(cardinalityViolations);
}
Also used : RuleSet(org.kie.workbench.common.stunner.core.rule.RuleSet) DefaultRuleViolations(org.kie.workbench.common.stunner.core.rule.violations.DefaultRuleViolations) RuleViolations(org.kie.workbench.common.stunner.core.rule.RuleViolations) DefaultRuleViolations(org.kie.workbench.common.stunner.core.rule.violations.DefaultRuleViolations) View(org.kie.workbench.common.stunner.core.graph.content.view.View) Edge(org.kie.workbench.common.stunner.core.graph.Edge)

Aggregations

RuleSet (org.kie.workbench.common.stunner.core.rule.RuleSet)10 Node (org.kie.workbench.common.stunner.core.graph.Node)4 DefinitionSet (org.kie.workbench.common.stunner.core.graph.content.definition.DefinitionSet)4 RuleEvaluationContext (org.kie.workbench.common.stunner.core.rule.RuleEvaluationContext)4 RuleViolations (org.kie.workbench.common.stunner.core.rule.RuleViolations)4 LinkedHashSet (java.util.LinkedHashSet)3 Test (org.junit.Test)3 TestingGraphInstanceBuilder (org.kie.workbench.common.stunner.core.TestingGraphInstanceBuilder)3 RuleManager (org.kie.workbench.common.stunner.core.rule.RuleManager)3 Edge (org.kie.workbench.common.stunner.core.graph.Edge)2 View (org.kie.workbench.common.stunner.core.graph.content.view.View)2 RuleViolation (org.kie.workbench.common.stunner.core.rule.RuleViolation)2 EmptyConnectionViolation (org.kie.workbench.common.stunner.core.rule.violations.EmptyConnectionViolation)2 Collection (java.util.Collection)1 Optional (java.util.Optional)1 Set (java.util.Set)1 Stack (java.util.Stack)1 BiConsumer (java.util.function.BiConsumer)1 Consumer (java.util.function.Consumer)1 Logger (java.util.logging.Logger)1