Search in sources :

Example 1 with AbstractTreeTraverseCallback

use of org.kie.workbench.common.stunner.core.graph.processing.traverse.tree.AbstractTreeTraverseCallback in project kie-wb-common by kiegroup.

the class ConnectorParentsMatchContainmentHandler method evaluateSingleContainment.

@SuppressWarnings("unchecked")
private void evaluateSingleContainment(final DefaultRuleViolations result, final RuleExtension rule, final NodeContainmentContext context, final Node<? extends Definition<?>, ? extends Edge> candidate) {
    final GraphEvaluationState state = context.getState();
    final Graph<?, ? extends Node> graph = context.getState().getGraph();
    final String connectorId = rule.getId();
    // Walk throw the graph and evaluate connector source and target nodes parent match.
    treeWalkTraverseProcessor.traverse(graph, candidate, new AbstractTreeTraverseCallback<Graph, Node, Edge>() {

        @Override
        public boolean startNodeTraversal(final Node node) {
            // Process incoming edges into the node as well.
            final List<? extends Edge> inEdges = node.getInEdges();
            if (null != inEdges) {
                inEdges.stream().forEach(this::process);
            }
            return true;
        }

        @Override
        public boolean startEdgeTraversal(final Edge edge) {
            return process(edge);
        }

        private boolean process(final Edge edge) {
            final Optional<String> eId = getId(definitionManager, edge);
            if (eId.isPresent() && connectorId.equals(eId.get())) {
                final Node sourceNode = state.getConnectionState().getSource(edge);
                final Node targetNode = state.getConnectionState().getTarget(edge);
                final boolean valid = new ParentTypesMatcher(() -> definitionManager, e -> getParent(context, e), rule.getTypeArguments()).matcher().test(sourceNode, targetNode);
                if (!valid) {
                    addViolation(edge.getUUID(), rule, result);
                }
            }
            return true;
        }
    });
}
Also used : StatefulContainmentState.getParent(org.kie.workbench.common.stunner.core.rule.context.impl.StatefulGraphEvaluationState.StatefulContainmentState.getParent) Collection(java.util.Collection) Edge(org.kie.workbench.common.stunner.core.graph.Edge) DefaultRuleViolations(org.kie.workbench.common.stunner.core.rule.violations.DefaultRuleViolations) Definition(org.kie.workbench.common.stunner.core.graph.content.definition.Definition) GraphEvaluationState(org.kie.workbench.common.stunner.core.rule.context.GraphEvaluationState) GraphUtils(org.kie.workbench.common.stunner.core.graph.util.GraphUtils) Inject(javax.inject.Inject) NodeContainmentContext(org.kie.workbench.common.stunner.core.rule.context.NodeContainmentContext) List(java.util.List) Graph(org.kie.workbench.common.stunner.core.graph.Graph) TreeWalkTraverseProcessor(org.kie.workbench.common.stunner.core.graph.processing.traverse.tree.TreeWalkTraverseProcessor) Stream(java.util.stream.Stream) ParentTypesMatcher(org.kie.workbench.common.stunner.core.graph.util.ParentTypesMatcher) RuleViolations(org.kie.workbench.common.stunner.core.rule.RuleViolations) GraphEvaluationHandlerUtils(org.kie.workbench.common.stunner.core.rule.handler.impl.GraphEvaluationHandlerUtils) AbstractTreeTraverseCallback(org.kie.workbench.common.stunner.core.graph.processing.traverse.tree.AbstractTreeTraverseCallback) Optional(java.util.Optional) DefinitionManager(org.kie.workbench.common.stunner.core.api.DefinitionManager) ApplicationScoped(javax.enterprise.context.ApplicationScoped) RuleExtension(org.kie.workbench.common.stunner.core.rule.ext.RuleExtension) Node(org.kie.workbench.common.stunner.core.graph.Node) Graph(org.kie.workbench.common.stunner.core.graph.Graph) Optional(java.util.Optional) ParentTypesMatcher(org.kie.workbench.common.stunner.core.graph.util.ParentTypesMatcher) Node(org.kie.workbench.common.stunner.core.graph.Node) List(java.util.List) Edge(org.kie.workbench.common.stunner.core.graph.Edge) GraphEvaluationState(org.kie.workbench.common.stunner.core.rule.context.GraphEvaluationState)

Example 2 with AbstractTreeTraverseCallback

use of org.kie.workbench.common.stunner.core.graph.processing.traverse.tree.AbstractTreeTraverseCallback 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();
    final StatelessGraphContextBuilder contextBuilder = new StatelessGraphContextBuilder(graph);
    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(contextBuilder, ruleSet));
            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(edge, sourceOpt, targetOpt);
                emptyConnectionViolation.ifPresent(edgeViolations::add);
                // Evaluate connection rules.
                edgeViolations.addViolations(evaluateConnection(contextBuilder, ruleSet, edge, sourceOpt, targetOpt));
                // Evaluate connector cardinality rules for this edge.
                if (null != edge.getTargetNode()) {
                    edgeViolations.addViolations(evaluateIncomingEdgeCardinality(contextBuilder, ruleSet, edge));
                }
                if (null != edge.getSourceNode()) {
                    edgeViolations.addViolations(evaluateOutgoingEdgeCardinality(contextBuilder, ruleSet, 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(contextBuilder, ruleSet, 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, contextBuilder, 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) StatelessGraphContextBuilder(org.kie.workbench.common.stunner.core.rule.context.impl.RuleEvaluationContextBuilder.StatelessGraphContextBuilder) 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) DefinitionSet(org.kie.workbench.common.stunner.core.graph.content.definition.DefinitionSet) 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) StatelessGraphContextBuilder(org.kie.workbench.common.stunner.core.rule.context.impl.RuleEvaluationContextBuilder.StatelessGraphContextBuilder) 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 3 with AbstractTreeTraverseCallback

use of org.kie.workbench.common.stunner.core.graph.processing.traverse.tree.AbstractTreeTraverseCallback in project kie-wb-common by kiegroup.

the class GraphUtils method computeGraphHashCode.

@SuppressWarnings("all")
public static int computeGraphHashCode(GraphImpl graph) {
    final int[] result = { 0 };
    new TreeWalkTraverseProcessorImpl().traverse(graph, new AbstractTreeTraverseCallback<Graph, Node, Edge>() {

        @Override
        public boolean startEdgeTraversal(final Edge edge) {
            super.startEdgeTraversal(edge);
            final Object content = edge.getContent();
            result[0] = combineHashCodes(result[0], content.hashCode());
            if (edge.getContent() instanceof ViewConnector) {
                Optional<Connection> sourceConnection = ((ViewConnector) edge.getContent()).getSourceConnection();
                sourceConnection.ifPresent(c -> result[0] = combineHashCodes(result[0], c.hashCode()));
                Optional<Connection> targetConnection = ((ViewConnector) edge.getContent()).getTargetConnection();
                targetConnection.ifPresent(c -> result[0] = combineHashCodes(result[0], c.hashCode()));
            }
            return true;
        }

        @Override
        public boolean startNodeTraversal(final Node node) {
            super.startNodeTraversal(node);
            result[0] = combineHashCodes(result[0], node.hashCode());
            if (!(node.getContent() instanceof DefinitionSet) && node.getContent() instanceof Definition) {
                Object def = ((Definition) (node.getContent())).getDefinition();
                result[0] = combineHashCodes(result[0], def.hashCode());
            }
            if (node.getContent() instanceof HasBounds) {
                Bounds bounds = ((HasBounds) node.getContent()).getBounds();
                result[0] = combineHashCodes(result[0], bounds.hashCode());
            }
            return true;
        }
    });
    return result[0];
}
Also used : IntStream(java.util.stream.IntStream) Connection(org.kie.workbench.common.stunner.core.graph.content.view.Connection) Edge(org.kie.workbench.common.stunner.core.graph.Edge) PortablePreconditions.checkNotNull(org.kie.soup.commons.validation.PortablePreconditions.checkNotNull) HashMap(java.util.HashMap) HashUtil.combineHashCodes(org.kie.workbench.common.stunner.core.util.HashUtil.combineHashCodes) OptionalInt(java.util.OptionalInt) Function(java.util.function.Function) View(org.kie.workbench.common.stunner.core.graph.content.view.View) Map(java.util.Map) Bound(org.kie.workbench.common.stunner.core.graph.content.Bound) 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) StreamSupport(java.util.stream.StreamSupport) Diagram(org.kie.workbench.common.stunner.core.diagram.Diagram) Point2D(org.kie.workbench.common.stunner.core.graph.content.view.Point2D) Iterator(java.util.Iterator) Predicate(java.util.function.Predicate) Collection(java.util.Collection) TreeWalkTraverseProcessorImpl(org.kie.workbench.common.stunner.core.graph.processing.traverse.tree.TreeWalkTraverseProcessorImpl) Set(java.util.Set) Child(org.kie.workbench.common.stunner.core.graph.content.relationship.Child) DefinitionSet(org.kie.workbench.common.stunner.core.graph.content.definition.DefinitionSet) Collectors(java.util.stream.Collectors) Definition(org.kie.workbench.common.stunner.core.graph.content.definition.Definition) ViewConnector(org.kie.workbench.common.stunner.core.graph.content.view.ViewConnector) Objects(java.util.Objects) List(java.util.List) Graph(org.kie.workbench.common.stunner.core.graph.Graph) GraphImpl(org.kie.workbench.common.stunner.core.graph.impl.GraphImpl) Stream(java.util.stream.Stream) Optional(java.util.Optional) Dock(org.kie.workbench.common.stunner.core.graph.content.relationship.Dock) HasBounds(org.kie.workbench.common.stunner.core.graph.content.HasBounds) Collections(java.util.Collections) Bounds(org.kie.workbench.common.stunner.core.graph.content.Bounds) Node(org.kie.workbench.common.stunner.core.graph.Node) ViewConnector(org.kie.workbench.common.stunner.core.graph.content.view.ViewConnector) Optional(java.util.Optional) Node(org.kie.workbench.common.stunner.core.graph.Node) HasBounds(org.kie.workbench.common.stunner.core.graph.content.HasBounds) Bounds(org.kie.workbench.common.stunner.core.graph.content.Bounds) Definition(org.kie.workbench.common.stunner.core.graph.content.definition.Definition) TreeWalkTraverseProcessorImpl(org.kie.workbench.common.stunner.core.graph.processing.traverse.tree.TreeWalkTraverseProcessorImpl) Graph(org.kie.workbench.common.stunner.core.graph.Graph) DefinitionSet(org.kie.workbench.common.stunner.core.graph.content.definition.DefinitionSet) Edge(org.kie.workbench.common.stunner.core.graph.Edge) HasBounds(org.kie.workbench.common.stunner.core.graph.content.HasBounds)

Aggregations

Collection (java.util.Collection)3 Optional (java.util.Optional)3 DefinitionManager (org.kie.workbench.common.stunner.core.api.DefinitionManager)3 Edge (org.kie.workbench.common.stunner.core.graph.Edge)3 Graph (org.kie.workbench.common.stunner.core.graph.Graph)3 Node (org.kie.workbench.common.stunner.core.graph.Node)3 Definition (org.kie.workbench.common.stunner.core.graph.content.definition.Definition)3 AbstractTreeTraverseCallback (org.kie.workbench.common.stunner.core.graph.processing.traverse.tree.AbstractTreeTraverseCallback)3 List (java.util.List)2 Set (java.util.Set)2 Stream (java.util.stream.Stream)2 ApplicationScoped (javax.enterprise.context.ApplicationScoped)2 Inject (javax.inject.Inject)2 Element (org.kie.workbench.common.stunner.core.graph.Element)2 DefinitionSet (org.kie.workbench.common.stunner.core.graph.content.definition.DefinitionSet)2 Child (org.kie.workbench.common.stunner.core.graph.content.relationship.Child)2 Dock (org.kie.workbench.common.stunner.core.graph.content.relationship.Dock)2 View (org.kie.workbench.common.stunner.core.graph.content.view.View)2 TreeWalkTraverseProcessor (org.kie.workbench.common.stunner.core.graph.processing.traverse.tree.TreeWalkTraverseProcessor)2 RuleViolations (org.kie.workbench.common.stunner.core.rule.RuleViolations)2