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]);
});
}
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);
}
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));
}
});
}
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);
}
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);
}
Aggregations