/* * 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.drools.workbench.services.verifier.plugin.client.builders; import org.drools.workbench.models.datamodel.oracle.DataType; import org.drools.workbench.models.datamodel.oracle.OperatorsOracle; import org.drools.workbench.models.datamodel.rule.BaseSingleFieldConstraint; import org.drools.workbench.models.datamodel.rule.DSLSentence; import org.drools.workbench.models.datamodel.rule.FactPattern; import org.drools.workbench.models.datamodel.rule.IAction; import org.drools.workbench.models.datamodel.rule.IPattern; import org.drools.workbench.models.guided.dtable.shared.model.ActionCol52; import org.drools.workbench.models.guided.dtable.shared.model.ActionInsertFactCol52; import org.drools.workbench.models.guided.dtable.shared.model.ActionSetFieldCol52; import org.drools.workbench.models.guided.dtable.shared.model.ActionWorkItemCol52; import org.drools.workbench.models.guided.dtable.shared.model.ActionWorkItemInsertFactCol52; import org.drools.workbench.models.guided.dtable.shared.model.ActionWorkItemSetFieldCol52; import org.drools.workbench.models.guided.dtable.shared.model.AttributeCol52; import org.drools.workbench.models.guided.dtable.shared.model.BRLActionColumn; import org.drools.workbench.models.guided.dtable.shared.model.BRLActionVariableColumn; import org.drools.workbench.models.guided.dtable.shared.model.BRLConditionColumn; import org.drools.workbench.models.guided.dtable.shared.model.BRLConditionVariableColumn; import org.drools.workbench.models.guided.dtable.shared.model.BaseColumn; import org.drools.workbench.models.guided.dtable.shared.model.CompositeColumn; import org.drools.workbench.models.guided.dtable.shared.model.ConditionCol52; import org.drools.workbench.models.guided.dtable.shared.model.DTColumnConfig52; import org.drools.workbench.models.guided.dtable.shared.model.DescriptionCol52; import org.drools.workbench.models.guided.dtable.shared.model.GuidedDecisionTable52; import org.drools.workbench.models.guided.dtable.shared.model.LimitedEntryCol; import org.drools.workbench.models.guided.dtable.shared.model.MetadataCol52; import org.drools.workbench.models.guided.dtable.shared.model.Pattern52; import org.drools.workbench.models.guided.dtable.shared.model.RowNumberCol52; import org.uberfire.commons.validation.PortablePreconditions; /** * Utilities for Columns */ public abstract class ColumnUtilitiesBase { private final GuidedDecisionTable52 model; public ColumnUtilitiesBase( final GuidedDecisionTable52 model ) { this.model = PortablePreconditions.checkNotNull( "model", model ); } public String getType( final BaseColumn col ) { if ( col instanceof RowNumberCol52 ) { return getType( (RowNumberCol52) col ); } else if ( col instanceof AttributeCol52 ) { return getType( (AttributeCol52) col ); } else if ( col instanceof BRLConditionVariableColumn ) { return getType( (BRLConditionVariableColumn) col ); } else if ( col instanceof ConditionCol52 ) { return getType( (ConditionCol52) col ); } else if ( col instanceof ActionSetFieldCol52 ) { return getType( (ActionSetFieldCol52) col ); } else if ( col instanceof ActionInsertFactCol52 ) { return getType( (ActionInsertFactCol52) col ); } else if ( col instanceof BRLActionVariableColumn ) { return getType( (BRLActionVariableColumn) col ); } return DataType.TYPE_STRING; } private String getType( final RowNumberCol52 col ) { return DataType.TYPE_NUMERIC_INTEGER; } private String getType( final AttributeCol52 col ) { String type = DataType.TYPE_STRING; final String attrName = col.getAttribute(); if ( attrName.equals( GuidedDecisionTable52.SALIENCE_ATTR ) ) { type = DataType.TYPE_NUMERIC_INTEGER; } else if ( attrName.equals( GuidedDecisionTable52.ENABLED_ATTR ) ) { type = DataType.TYPE_BOOLEAN; } else if ( attrName.equals( GuidedDecisionTable52.NO_LOOP_ATTR ) ) { type = DataType.TYPE_BOOLEAN; } else if ( attrName.equals( GuidedDecisionTable52.DURATION_ATTR ) ) { type = DataType.TYPE_NUMERIC_LONG; } else if ( attrName.equals( GuidedDecisionTable52.TIMER_ATTR ) ) { type = DataType.TYPE_STRING; } else if ( attrName.equals( GuidedDecisionTable52.CALENDARS_ATTR ) ) { type = DataType.TYPE_STRING; } else if ( attrName.equals( GuidedDecisionTable52.AUTO_FOCUS_ATTR ) ) { type = DataType.TYPE_BOOLEAN; } else if ( attrName.equals( GuidedDecisionTable52.LOCK_ON_ACTIVE_ATTR ) ) { type = DataType.TYPE_BOOLEAN; } else if ( attrName.equals( GuidedDecisionTable52.DATE_EFFECTIVE_ATTR ) ) { type = DataType.TYPE_DATE; } else if ( attrName.equals( GuidedDecisionTable52.DATE_EXPIRES_ATTR ) ) { type = DataType.TYPE_DATE; } else if ( attrName.equals( GuidedDecisionTable52.DIALECT_ATTR ) ) { type = DataType.TYPE_STRING; } else if ( attrName.equals( GuidedDecisionTable52.NEGATE_RULE_ATTR ) ) { type = DataType.TYPE_BOOLEAN; } return type; } private String getType( final ConditionCol52 col ) { final Pattern52 pattern = model.getPattern( col ); return getType( pattern, col ); } protected String getType( final Pattern52 pattern, final ConditionCol52 col ) { // Columns with "Value Lists" etc are always Text (for now) if ( hasValueList( col ) ) { return DataType.TYPE_STRING; } // Operator "in" and "not in" requires a List as the value. These are always Text (for now) if ( OperatorsOracle.operatorRequiresList( col.getOperator() ) ) { return DataType.TYPE_STRING; } //Literals without operators are always Text (as the user can specify the operator "in cell") if ( col.getConstraintValueType() == BaseSingleFieldConstraint.TYPE_LITERAL ) { if ( col.getOperator() == null || "".equals( col.getOperator() ) ) { return DataType.TYPE_STRING; } } //Formula are always Text (as the user can specify anything "in cell") if ( col.getConstraintValueType() == BaseSingleFieldConstraint.TYPE_PREDICATE ) { return DataType.TYPE_STRING; } //Predicates are always Text (as the user can specify anything "in cell") if ( col.getConstraintValueType() == BaseSingleFieldConstraint.TYPE_RET_VALUE ) { return DataType.TYPE_STRING; } //Otherwise lookup from SuggestionCompletionEngine final String factType = pattern.getFactType(); final String fieldName = col.getFactField(); return getTypeFromDataOracle( factType, fieldName ); } private String getType( final BRLConditionVariableColumn col ) { //If the parameter is not bound to a Fact or FactField use the explicit type. This is (currently) //used when a BRL fragment does not contain any Template Keys and a single BRLConditionVariableColumn //is created with type SuggestionCompletionEngine.TYPE_BOOLEAN i.e. Limited Entry if ( col.getFactType() == null && col.getFactField() == null ) { return col.getFieldType(); } //Otherwise lookup from SuggestionCompletionEngine final String factType = col.getFactType(); final String fieldName = col.getFactField(); return getTypeFromDataOracle( factType, fieldName ); } private String getType( final ActionSetFieldCol52 col ) { // Columns with "Value Lists" etc are always Text (for now) if ( hasValueList( col ) ) { return DataType.TYPE_STRING; } //Otherwise lookup from SuggestionCompletionEngine final String factType = getBoundFactType( col.getBoundName() ); final String fieldName = col.getFactField(); return getTypeFromDataOracle( factType, fieldName ); } private String getType( final Pattern52 pattern, final ActionSetFieldCol52 col ) { // Columns with "Value Lists" etc are always Text (for now) if ( hasValueList( col ) ) { return DataType.TYPE_STRING; } //Otherwise lookup from SuggestionCompletionEngine final String factType = pattern.getFactType(); final String fieldName = col.getFactField(); return getTypeFromDataOracle( factType, fieldName ); } private String getType( final ActionInsertFactCol52 col ) { // Columns with "Value Lists" etc are always Text (for now) if ( hasValueList( col ) ) { return DataType.TYPE_STRING; } //Otherwise lookup from SuggestionCompletionEngine final String factType = col.getFactType(); final String fieldName = col.getFactField(); return getTypeFromDataOracle( factType, fieldName ); } private String getType( final BRLActionVariableColumn col ) { //If the parameter is not bound to a Fact or FactField use the explicit type. This is (currently) //used when a BRL fragment does not contain any Template Keys and a single BRLActionVariableColumn //is created with type SuggestionCompletionEngine.TYPE_BOOLEAN i.e. Limited Entry if ( col.getFactType() == null && col.getFactField() == null ) { return col.getFieldType(); } //Otherwise lookup from SuggestionCompletionEngine final String factType = col.getFactType(); final String fieldName = col.getFactField(); return getTypeFromDataOracle( factType, fieldName ); } protected abstract String getTypeFromDataOracle( final String factType, final String fieldName ); // Get the Data Type corresponding to a given column public DataType.DataTypes getTypeSafeType( final BaseColumn column ) { final String type = getType( column ); return convertToTypeSafeType( type ); } // Get the Data Type corresponding to a given column public DataType.DataTypes getTypeSafeType( final Pattern52 pattern, final ConditionCol52 column ) { final String type = getType( pattern, column ); return convertToTypeSafeType( type ); } // Get the Data Type corresponding to a given column public DataType.DataTypes getTypeSafeType( final Pattern52 pattern, final ActionSetFieldCol52 column ) { final String type = getType( pattern, column ); return convertToTypeSafeType( type ); } private DataType.DataTypes convertToTypeSafeType( final String type ) { if ( DataType.TYPE_NUMERIC.equals( type ) ) { return DataType.DataTypes.NUMERIC; } else if ( DataType.TYPE_NUMERIC_BIGDECIMAL.equals( type ) ) { return DataType.DataTypes.NUMERIC_BIGDECIMAL; } else if ( DataType.TYPE_NUMERIC_BIGINTEGER.equals( type ) ) { return DataType.DataTypes.NUMERIC_BIGINTEGER; } else if ( DataType.TYPE_NUMERIC_BYTE.equals( type ) ) { return DataType.DataTypes.NUMERIC_BYTE; } else if ( DataType.TYPE_NUMERIC_DOUBLE.equals( type ) ) { return DataType.DataTypes.NUMERIC_DOUBLE; } else if ( DataType.TYPE_NUMERIC_FLOAT.equals( type ) ) { return DataType.DataTypes.NUMERIC_FLOAT; } else if ( DataType.TYPE_NUMERIC_INTEGER.equals( type ) ) { return DataType.DataTypes.NUMERIC_INTEGER; } else if ( DataType.TYPE_NUMERIC_LONG.equals( type ) ) { return DataType.DataTypes.NUMERIC_LONG; } else if ( DataType.TYPE_NUMERIC_SHORT.equals( type ) ) { return DataType.DataTypes.NUMERIC_SHORT; } else if ( DataType.TYPE_BOOLEAN.equals( type ) ) { return DataType.DataTypes.BOOLEAN; } else if ( DataType.TYPE_DATE.equals( type ) ) { return DataType.DataTypes.DATE; } return DataType.DataTypes.STRING; } public String[] getValueList( final BaseColumn col ) { if ( col instanceof AttributeCol52 ) { return getValueList( (AttributeCol52) col ); } else if ( col instanceof ConditionCol52 ) { return getValueList( (ConditionCol52) col ); } else if ( col instanceof ActionSetFieldCol52 ) { return getValueList( (ActionSetFieldCol52) col ); } else if ( col instanceof ActionInsertFactCol52 ) { return getValueList( (ActionInsertFactCol52) col ); } return new String[0]; } private String[] getValueList( final AttributeCol52 col ) { if ( "no-loop".equals( col.getAttribute() ) || "enabled".equals( col.getAttribute() ) ) { return new String[]{"true", "false"}; } return new String[0]; } private String[] getValueList( final ConditionCol52 col ) { if ( col.getValueList() != null && !"".equals( col.getValueList() ) ) { return col.getValueList() .split( "," ); } return new String[0]; } private String[] getValueList( final ActionSetFieldCol52 col ) { if ( col.getValueList() != null && !"".equals( col.getValueList() ) ) { return col.getValueList() .split( "," ); } return new String[0]; } private String[] getValueList( final ActionInsertFactCol52 col ) { if ( col.getValueList() != null && !"".equals( col.getValueList() ) ) { return col.getValueList() .split( "," ); } return new String[0]; } public boolean hasValueList( final AttributeCol52 col ) { if ( "no-loop".equals( col.getAttribute() ) || "enabled".equals( col.getAttribute() ) ) { return true; } return false; } public boolean hasValueList( final ConditionCol52 col ) { if ( col.getValueList() != null && !"".equals( col.getValueList() ) ) { return true; } return false; } public boolean hasValueList( final ActionSetFieldCol52 col ) { if ( col.getValueList() != null && !"".equals( col.getValueList() ) ) { return true; } return false; } public boolean hasValueList( final ActionInsertFactCol52 col ) { if ( col.getValueList() != null && !"".equals( col.getValueList() ) ) { return true; } return false; } public boolean isConstraintValid( final DTColumnConfig52 col ) { if ( col instanceof RowNumberCol52 ) { return true; } if ( col instanceof DescriptionCol52 ) { return true; } if ( col instanceof MetadataCol52 ) { return true; } if ( col instanceof AttributeCol52 ) { return true; } if ( col instanceof ConditionCol52 ) { final ConditionCol52 c = (ConditionCol52) col; if ( c.getConstraintValueType() == BaseSingleFieldConstraint.TYPE_LITERAL ) { if ( c.getFactField() == null || c.getFactField() .equals( "" ) ) { return false; } if ( c.getOperator() == null || c.getOperator() .equals( "" ) ) { return false; } return true; } return true; } if ( col instanceof ActionCol52 ) { return true; } return false; } public String getBoundFactType( String boundName ) { for ( CompositeColumn<?> cc : this.model.getConditions() ) { if ( cc instanceof Pattern52 ) { final Pattern52 p = (Pattern52) cc; if ( p.isBound() && p.getBoundName() .equals( boundName ) ) { return p.getFactType(); } } else if ( cc instanceof BRLConditionColumn ) { final BRLConditionColumn brl = (BRLConditionColumn) cc; for ( IPattern p : brl.getDefinition() ) { if ( p instanceof FactPattern ) { FactPattern fp = (FactPattern) p; if ( fp.isBound() && fp.getBoundName() .equals( boundName ) ) { return fp.getFactType(); } } } } } return ""; } /** * Check is the model uses DSLSentences and hence requires expansion * @return true if any BRLColumn's contain DSLSentence's */ public boolean hasDSLSentences() { for ( CompositeColumn<? extends BaseColumn> column : this.model.getConditions() ) { if ( column instanceof BRLConditionColumn ) { final BRLConditionColumn brlColumn = (BRLConditionColumn) column; for ( IPattern pattern : brlColumn.getDefinition() ) { if ( pattern instanceof DSLSentence ) { return true; } } } } for ( ActionCol52 column : this.model.getActionCols() ) { if ( column instanceof BRLActionColumn ) { final BRLActionColumn brlColumn = (BRLActionColumn) column; for ( IAction action : brlColumn.getDefinition() ) { if ( action instanceof DSLSentence ) { return true; } } } } return false; } /** * Get the Data Type corresponding to a given column. If the column is a * ConditonCol52 and it is not associated with a Pattern52 in the decision * table (e.g. it has been cloned) the overloaded method * getDataType(Pattern52, ConditionCol52) should be used. * @param column * @return */ public DataType.DataTypes getDataType( BaseColumn column ) { //Limited Entry are simply boolean if ( column instanceof LimitedEntryCol ) { return DataType.DataTypes.BOOLEAN; } //Action Work Items are always boolean if ( column instanceof ActionWorkItemCol52 ) { return DataType.DataTypes.BOOLEAN; } //Actions setting Field Values from Work Item Result Parameters are always boolean if ( column instanceof ActionWorkItemSetFieldCol52 || column instanceof ActionWorkItemInsertFactCol52 ) { return DataType.DataTypes.BOOLEAN; } //Operators "is null" and "is not null" require a boolean cell if ( column instanceof ConditionCol52 ) { ConditionCol52 cc = (ConditionCol52) column; if ( cc.getOperator() != null && ( cc.getOperator() .equals( "== null" ) || cc.getOperator() .equals( "!= null" ) ) ) { return DataType.DataTypes.BOOLEAN; } } //Extended Entry... return getTypeSafeType( column ); } /** * Get the Data Type corresponding to a given column * @param pattern Pattern52 * @param condition ConditionCol52 * @return */ public DataType.DataTypes getDataType( Pattern52 pattern, ConditionCol52 condition ) { //Limited Entry are simply boolean if ( condition instanceof LimitedEntryCol ) { return DataType.DataTypes.BOOLEAN; } //Operators "is null" and "is not null" require a boolean cell if ( condition.getOperator() != null && ( condition.getOperator() .equals( "== null" ) || condition.getOperator() .equals( "!= null" ) ) ) { return DataType.DataTypes.BOOLEAN; } //Extended Entry... return getTypeSafeType( pattern, condition ); } /** * Get the Data Type corresponding to a given column * @param pattern Pattern52 * @param action ActionSetFieldCol52 * @return */ public DataType.DataTypes getDataType( Pattern52 pattern, ActionSetFieldCol52 action ) { //Limited Entry are simply boolean if ( action instanceof LimitedEntryCol ) { return DataType.DataTypes.BOOLEAN; } //Extended Entry... return getTypeSafeType( pattern, action ); } }