/* * Copyright 2012 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.drools.workbench.screens.guided.template.client.editor; import java.util.ArrayList; import java.util.List; import org.drools.workbench.models.datamodel.rule.ActionFieldList; import org.drools.workbench.models.datamodel.rule.ActionFieldValue; import org.drools.workbench.models.datamodel.rule.BaseSingleFieldConstraint; import org.drools.workbench.models.datamodel.rule.CompositeFactPattern; import org.drools.workbench.models.datamodel.rule.CompositeFieldConstraint; import org.drools.workbench.models.datamodel.rule.FactPattern; import org.drools.workbench.models.datamodel.rule.FieldConstraint; import org.drools.workbench.models.datamodel.rule.FieldNatureType; import org.drools.workbench.models.datamodel.rule.FromAccumulateCompositeFactPattern; import org.drools.workbench.models.datamodel.rule.FromCollectCompositeFactPattern; import org.drools.workbench.models.datamodel.rule.FromCompositeFactPattern; import org.drools.workbench.models.datamodel.rule.IAction; import org.drools.workbench.models.datamodel.rule.IPattern; import org.drools.workbench.models.datamodel.rule.RuleModel; import org.drools.workbench.models.datamodel.rule.SingleFieldConstraint; import org.drools.workbench.models.datamodel.rule.SingleFieldConstraintEBLeftSide; /** * A Rule Model Visitor to extract InterpolationVariables that are defined on * the same Pattern or Action as the provided base variable. This is used to get * a list of InterpolationVariables (or literal values) used to drive dependent * enumerations. */ public class RuleModelPeerVariableVisitor { private final RuleModel model; private final String baseVariableName; private final List<ValueHolder> peerVariables = new ArrayList<ValueHolder>(); //Container for extracted InterpolationVariable or literal value public static class ValueHolder { private final String fieldName; private final String value; private final Type type; public enum Type { VALUE, TEMPLATE_KEY } ValueHolder( String fieldName, String value, Type type ) { this.fieldName = fieldName; this.value = value; this.type = type; } public String getFieldName() { return this.fieldName; } public String getValue() { return this.value; } public Type getType() { return this.type; } } public RuleModelPeerVariableVisitor( final RuleModel model, final String baseVariableName ) { this.model = model; this.baseVariableName = baseVariableName; } public List<ValueHolder> getPeerVariables() { visit( this.model ); return this.peerVariables; } private void visit( Object o ) { if ( o == null ) { return; } if ( o instanceof RuleModel ) { visitRuleModel( (RuleModel) o ); } else if ( o instanceof FactPattern ) { visitFactPattern( (FactPattern) o ); } else if ( o instanceof CompositeFieldConstraint ) { visitCompositeFieldConstraint( (CompositeFieldConstraint) o ); } else if ( o instanceof SingleFieldConstraintEBLeftSide ) { visitSingleFieldConstraint( (SingleFieldConstraintEBLeftSide) o ); } else if ( o instanceof SingleFieldConstraint ) { visitSingleFieldConstraint( (SingleFieldConstraint) o ); } else if ( o instanceof CompositeFactPattern ) { visitCompositeFactPattern( (CompositeFactPattern) o ); } else if ( o instanceof FromAccumulateCompositeFactPattern ) { visitFromAccumulateCompositeFactPattern( (FromAccumulateCompositeFactPattern) o ); } else if ( o instanceof FromCollectCompositeFactPattern ) { visitFromCollectCompositeFactPattern( (FromCollectCompositeFactPattern) o ); } else if ( o instanceof FromCompositeFactPattern ) { visitFromCompositeFactPattern( (FromCompositeFactPattern) o ); } else if ( o instanceof ActionFieldList ) { visitActionFieldList( (ActionFieldList) o ); } } private void visitRuleModel( final RuleModel rm ) { for ( IPattern p : rm.lhs ) { visit( p ); } for ( IAction a : rm.rhs ) { visit( a ); } } private void visitFactPattern( final FactPattern fp ) { if ( isParentFactPattern( fp ) ) { for ( FieldConstraint fc : fp.getFieldConstraints() ) { visit( fc ); } } } private boolean isParentFactPattern( final FactPattern fp ) { for ( FieldConstraint fc : fp.getFieldConstraints() ) { if ( isParentFactPattern( fc ) ) { return true; } } return false; } private boolean isParentFactPattern( FieldConstraint fc ) { if ( fc instanceof SingleFieldConstraint ) { final SingleFieldConstraint sfc = (SingleFieldConstraint) fc; return isParentFactPattern( sfc ); } else if ( fc instanceof CompositeFieldConstraint ) { final CompositeFieldConstraint cfc = (CompositeFieldConstraint) fc; return isParentFactPattern( cfc ); } return false; } private boolean isParentFactPattern( final SingleFieldConstraint sfc ) { if ( sfc.getConstraintValueType() == BaseSingleFieldConstraint.TYPE_TEMPLATE ) { if ( sfc.getValue().equals( this.baseVariableName ) ) { return true; } } return false; } private boolean isParentFactPattern( final CompositeFieldConstraint cfc ) { if ( cfc.getCompositeJunctionType().equals( CompositeFieldConstraint.COMPOSITE_TYPE_AND ) ) { for ( FieldConstraint fc : cfc.getConstraints() ) { if ( isParentFactPattern( fc ) ) { return true; } } } return false; } private void visitCompositeFactPattern( final CompositeFactPattern cfp ) { for ( IPattern p : cfp.getPatterns() ) { visit( p ); } } private void visitCompositeFieldConstraint( final CompositeFieldConstraint cfc ) { for ( FieldConstraint fc : cfc.getConstraints() ) { visit( fc ); } } private void visitFromAccumulateCompositeFactPattern( final FromAccumulateCompositeFactPattern pattern ) { if ( pattern.getFactPattern() != null ) { visit( pattern.getFactPattern() ); } } private void visitFromCollectCompositeFactPattern( final FromCollectCompositeFactPattern pattern ) { if ( pattern.getFactPattern() != null ) { visit( pattern.getFactPattern() ); } } private void visitFromCompositeFactPattern( final FromCompositeFactPattern pattern ) { if ( pattern.getFactPattern() != null ) { visit( pattern.getFactPattern() ); } } private void visitSingleFieldConstraint( final SingleFieldConstraint sfc ) { if ( sfc.getConstraintValueType() == BaseSingleFieldConstraint.TYPE_TEMPLATE ) { this.peerVariables.add( new ValueHolder( sfc.getFieldName(), sfc.getValue(), ValueHolder.Type.TEMPLATE_KEY ) ); } else { this.peerVariables.add( new ValueHolder( sfc.getFieldName(), sfc.getValue(), ValueHolder.Type.VALUE ) ); } } private void visitSingleFieldConstraint( final SingleFieldConstraintEBLeftSide sfexp ) { if ( sfexp.getConstraintValueType() == BaseSingleFieldConstraint.TYPE_TEMPLATE ) { this.peerVariables.add( new ValueHolder( sfexp.getFieldName(), sfexp.getValue(), ValueHolder.Type.TEMPLATE_KEY ) ); } else { this.peerVariables.add( new ValueHolder( sfexp.getFieldName(), sfexp.getValue(), ValueHolder.Type.VALUE ) ); } } private void visitActionFieldList( final ActionFieldList afl ) { boolean addVariables = false; List<ValueHolder> variables = new ArrayList<ValueHolder>(); for ( ActionFieldValue afv : afl.getFieldValues() ) { if ( afv.getNature() == FieldNatureType.TYPE_TEMPLATE ) { if ( afv.getValue().equals( this.baseVariableName ) ) { addVariables = true; } ValueHolder vh = new ValueHolder( afv.getField(), afv.getValue(), ValueHolder.Type.TEMPLATE_KEY ); variables.add( vh ); } else { ValueHolder vh = new ValueHolder( afv.getField(), afv.getValue(), ValueHolder.Type.VALUE ); variables.add( vh ); } } if ( addVariables ) { this.peerVariables.addAll( variables ); } } }