/* * Copyright 2016 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.lookup.rule; import java.util.Collection; import java.util.HashSet; import java.util.LinkedList; import java.util.List; 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.lookup.criteria.AbstractCriteriaLookupManager; import org.kie.workbench.common.stunner.core.rule.Rule; import org.kie.workbench.common.stunner.core.rule.context.EdgeCardinalityContext; import org.kie.workbench.common.stunner.core.rule.impl.CanConnect; import org.kie.workbench.common.stunner.core.rule.impl.CanContain; import org.kie.workbench.common.stunner.core.rule.impl.EdgeOccurrences; import org.kie.workbench.common.stunner.core.rule.impl.Occurrences; @ApplicationScoped public class RuleLookupManagerImpl extends AbstractCriteriaLookupManager<Rule, Rule, RuleLookupRequest> implements RuleLookupManager { private static final String TYPE = "type"; private static final String ROLES = "roles"; private static final String ID = "id"; private static final String ROLE = "role"; private static final String ROLE_IN = "roleIn"; private static final String EDGE_TYPE = "edgeType"; private static final String FROM = "from"; private static final String TO = "to"; private static final String INCOMING = "incoming"; private static final String CONTAINMENT = "containment"; private static final String CONNECTION = "connection"; private static final String CARDINALITY = "cardinality"; private static final String EDGECARDINALITY = "edgecardinality"; private final DefinitionManager definitionManager; protected RuleLookupManagerImpl() { this(null); } @Inject public RuleLookupManagerImpl(final DefinitionManager definitionManager) { this.definitionManager = definitionManager; } @Override protected List<Rule> getItems(final RuleLookupRequest request) { final String defSetId = request.getDefinitionSetId(); final Object defSet = definitionManager.definitionSets().getDefinitionSetById(defSetId); if (null != defSet) { final Collection<Rule> rules = (Collection<Rule>) definitionManager.adapters().forRules().getRuleSet(defSet).getRules(); return new LinkedList<>(rules); } return null; } @Override protected Rule buildResult(final Rule rule) { return rule; } @Override protected boolean matches(final String key, final String value, final Rule rule) { switch (key) { case TYPE: return CONTAINMENT.equals(value) && (rule instanceof CanContain) || CONNECTION.equals(value) && (rule instanceof CanConnect) || CARDINALITY.equals(value) && (rule instanceof Occurrences) || EDGECARDINALITY.equals(value) && (rule instanceof EdgeOccurrences); case ROLES: try { // Permitted roles on containment rules. final CanContain cr = (CanContain) rule; final Set<String> rolesSet = toSet(value); if (null != rolesSet) { return isIntersect(cr.getAllowedRoles(), rolesSet); } } catch (final ClassCastException e) { return false; } return true; case ID: String _id = null; if (rule instanceof CanContain) { final CanContain er = (CanContain) rule; _id = er.getRole(); } else if (rule instanceof CanConnect) { final CanConnect er = (CanConnect) rule; _id = er.getRole(); } return _id != null && _id.equals(value); case ROLE: if (rule instanceof EdgeOccurrences) { final EdgeOccurrences er = (EdgeOccurrences) rule; return (er.getRole().equals(value)); } return false; case ROLE_IN: if (rule instanceof EdgeOccurrences) { final EdgeOccurrences er = (EdgeOccurrences) rule; final Set<String> set = toSet(value); if (null != set && !set.isEmpty()) { for (final String s : set) { if (er.getRole().equals(value)) { return true; } } } } return false; case EDGE_TYPE: try { final EdgeOccurrences er = (EdgeOccurrences) rule; return er.getDirection().equals(INCOMING.equals(value) ? EdgeCardinalityContext.Direction.INCOMING : EdgeCardinalityContext.Direction.OUTGOING); } catch (final ClassCastException e) { return false; } case FROM: case TO: // Connection rules. try { final CanConnect cr = (CanConnect) rule; final Set<String> fromSet = toSet(value); Set<String> ruleSet = getRoles(cr.getPermittedConnections(), FROM.equals(key)); if (null != fromSet) { return isIntersect(fromSet, ruleSet); } } catch (final Exception e) { return false; } } throw new UnsupportedOperationException("Cannot filter rules by key [" + key + "]"); } private Set<String> getRoles(final List<CanConnect.PermittedConnection> connections, final boolean from) { if (null != connections) { final HashSet<String> result = new HashSet<>(connections.size()); for (final CanConnect.PermittedConnection c : connections) { if (from) { result.add(c.getStartRole()); } else { result.add(c.getEndRole()); } } return result; } return null; } }