/* * 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.core.rule.handler.impl; import java.util.List; import java.util.Optional; import java.util.Set; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import org.kie.workbench.common.stunner.core.api.DefinitionManager; import org.kie.workbench.common.stunner.core.graph.Edge; import org.kie.workbench.common.stunner.core.graph.Element; import org.kie.workbench.common.stunner.core.graph.Node; import org.kie.workbench.common.stunner.core.graph.content.view.View; import org.kie.workbench.common.stunner.core.rule.RuleEvaluationHandler; import org.kie.workbench.common.stunner.core.rule.RuleViolations; import org.kie.workbench.common.stunner.core.rule.context.CardinalityContext; import org.kie.workbench.common.stunner.core.rule.context.ConnectorCardinalityContext; import org.kie.workbench.common.stunner.core.rule.context.EdgeCardinalityContext; import org.kie.workbench.common.stunner.core.rule.context.impl.RuleContextBuilder; import org.kie.workbench.common.stunner.core.rule.impl.EdgeOccurrences; import org.kie.workbench.common.stunner.core.rule.violations.DefaultRuleViolations; @ApplicationScoped public class ConnectorCardinalityEvaluationHandler implements RuleEvaluationHandler<EdgeOccurrences, ConnectorCardinalityContext> { private final GraphEvaluationHandlerUtils evalUtils; private final EdgeCardinalityEvaluationHandler edgeCardinalityEvaluationHandler; protected ConnectorCardinalityEvaluationHandler() { this.evalUtils = null; this.edgeCardinalityEvaluationHandler = null; } @Inject public ConnectorCardinalityEvaluationHandler(final DefinitionManager definitionManager, final EdgeCardinalityEvaluationHandler edgeCardinalityEvaluationHandler) { this.evalUtils = new GraphEvaluationHandlerUtils(definitionManager); this.edgeCardinalityEvaluationHandler = edgeCardinalityEvaluationHandler; } ConnectorCardinalityEvaluationHandler(final GraphEvaluationHandlerUtils evalUtils, final EdgeCardinalityEvaluationHandler edgeCardinalityEvaluationHandler) { this.evalUtils = evalUtils; this.edgeCardinalityEvaluationHandler = edgeCardinalityEvaluationHandler; } @Override public Class<EdgeOccurrences> getRuleType() { return EdgeOccurrences.class; } @Override public Class<ConnectorCardinalityContext> getContextType() { return ConnectorCardinalityContext.class; } @Override public boolean accepts(final EdgeOccurrences rule, final ConnectorCardinalityContext context) { final Edge<? extends View<?>, Node> edge = context.getEdge(); final Element<? extends View<?>> candidate = context.getCandidate(); final String edgeId = evalUtils.getElementDefinitionId(edge); final Set<String> candidateRoles = evalUtils.getLabels(candidate); // Take into account that there is no need to provide the candidate count value, as not necessary // just to check if the handler accepts the runtime rule and candidates. return edgeCardinalityEvaluationHandler.accepts(rule, RuleContextBuilder.DomainContexts.edgeCardinality(candidateRoles, edgeId, -1, context.getDirection(), context.getOperation())); } @Override @SuppressWarnings("unchecked") public RuleViolations evaluate(final EdgeOccurrences rule, final ConnectorCardinalityContext context) { final DefaultRuleViolations result = new DefaultRuleViolations(); final Node<? extends View<?>, ? extends Edge> candidate = (Node<? extends View<?>, ? extends Edge>) context.getCandidate(); final Edge<? extends View<?>, Node> edge = context.getEdge(); final Optional<CardinalityContext.Operation> operation = context.getOperation(); final EdgeCardinalityContext.Direction direction = context.getDirection(); final List<? extends Edge> edges = isIncoming(direction) ? candidate.getInEdges() : candidate.getOutEdges(); final String edgeId = evalUtils.getElementDefinitionId(edge); final int count = evalUtils.countEdges(edgeId, edges); // Delegate to the domain model cardinality rule manager. result.addViolations( edgeCardinalityEvaluationHandler .evaluate(rule, RuleContextBuilder.DomainContexts.edgeCardinality(candidate.getLabels(), edgeId, count, rule.getDirection(), operation)) ); return GraphEvaluationHandlerUtils.addViolationsSourceUUID(edge.getUUID(), result); } private boolean isIncoming(final EdgeCardinalityContext.Direction direction) { return EdgeCardinalityContext.Direction.INCOMING.equals(direction); } }