/* * Copyright 2010 JBoss Inc * * 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.ide.common.client.modeldriven.dt; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.drools.ide.common.client.modeldriven.SuggestionCompletionEngine; import org.drools.ide.common.client.modeldriven.brl.BaseSingleFieldConstraint; import org.drools.ide.common.client.modeldriven.brl.PortableObject; /** * This is a decision table model for a guided editor. It is not template or XLS * based. (template could be done relatively easily by taking a template, as a * String, and then String[][] data and driving the SheetListener interface in * the decision tables module). * * This works by taking the column definitions, and combining them with the * table of data to produce rule models. * * * @author Michael Neale */ public class GuidedDecisionTable implements PortableObject { private static final long serialVersionUID = 510l; /** * Number of internal elements before ( used for offsets in serialization ) */ public static final int INTERNAL_ELEMENTS = 2; /** * The name - obviously. */ private String tableName; private String parentName; // metadata defined for table ( will be represented as a column per table // row of DATA private List<MetadataCol> metadataCols; private List<AttributeCol> attributeCols = new ArrayList<AttributeCol>(); private List<ConditionCol> conditionCols = new ArrayList<ConditionCol>(); private List<ActionCol> actionCols = new ArrayList<ActionCol>(); /** * First column is always row number. Second column is description. * Subsequent ones follow the above column definitions: attributeCols, then * conditionCols, then actionCols, in that order, left to right. */ private String[][] data = new String[0][0]; /** * The width to display the description column. */ private int descriptionWidth = -1; private String groupField; public GuidedDecisionTable() { } /** * This will return a list of valid values. if there is no such * "enumeration" of values, then it will return an empty array. */ public String[] getValueList(DTColumnConfig col, SuggestionCompletionEngine sce) { if ( col instanceof AttributeCol ) { AttributeCol at = (AttributeCol) col; if ( "no-loop".equals( at.attr ) || "enabled".equals( at.attr ) ) { return new String[]{"true", "false"}; } } else if ( col instanceof ConditionCol ) { // conditions: if its a formula etc, just return String[0], // otherwise check with the sce ConditionCol c = (ConditionCol) col; if ( c.getConstraintValueType() == BaseSingleFieldConstraint.TYPE_RET_VALUE || c.getConstraintValueType() == BaseSingleFieldConstraint.TYPE_PREDICATE ) { return new String[0]; } else { if ( c.getValueList() != null && !"".equals( c.getValueList() ) ) { return c.getValueList().split( "," ); } else { String[] r = sce.getEnumValues( c.getFactType(), c.getFactField() ); return (r != null) ? r : new String[0]; } } } else if ( col instanceof ActionSetFieldCol ) { ActionSetFieldCol c = (ActionSetFieldCol) col; if ( c.getValueList() != null && !"".equals( c.getValueList() ) ) { return c.getValueList().split( "," ); } else { String[] r = sce.getEnumValues( getBoundFactType( c.getBoundName() ), c.getFactField() ); return (r != null) ? r : new String[0]; } } else if ( col instanceof ActionInsertFactCol ) { ActionInsertFactCol c = (ActionInsertFactCol) col; if ( c.getValueList() != null && !"".equals( c.getValueList() ) ) { return c.getValueList().split( "," ); } else { String[] r = sce.getEnumValues( c.getFactType(), c.getFactField() ); return (r != null) ? r : new String[0]; } } return new String[0]; } public String getType(DTColumnConfig col, SuggestionCompletionEngine sce) { String type = null; if ( col instanceof AttributeCol ) { AttributeCol at = (AttributeCol) col; type = at.attr; } else if ( col instanceof ConditionCol ) { ConditionCol c = (ConditionCol) col; type = sce.getFieldType( c.getFactType(), c.getFactField() ); } else if ( col instanceof ActionSetFieldCol ) { ActionSetFieldCol c = (ActionSetFieldCol) col; type = sce.getFieldType( getBoundFactType( c.getBoundName() ), c.getFactField() ); } else if ( col instanceof ActionInsertFactCol ) { ActionInsertFactCol c = (ActionInsertFactCol) col; type = sce.getFieldType( c.getFactType(), c.getFactField() ); } return type; } private String getBoundFactType(String boundName) { for ( Iterator<ConditionCol> iterator = getConditionCols().iterator(); iterator.hasNext(); ) { ConditionCol c = iterator.next(); if ( c.getBoundName().equals( boundName ) ) { return c.getFactType(); } } return null; } public boolean isNumeric(DTColumnConfig col, SuggestionCompletionEngine sce) { if ( col instanceof AttributeCol ) { AttributeCol at = (AttributeCol) col; return "salience".equals( at.attr ); } else if ( col instanceof ConditionCol ) { ConditionCol c = (ConditionCol) col; if ( c.getConstraintValueType() == BaseSingleFieldConstraint.TYPE_LITERAL ) { if ( c.getOperator() == null || "".equals( c.getOperator() ) ) { return false; } String ft = sce.getFieldType( c.getFactType(), c.getFactField() ); if ( ft != null && ft.equals( SuggestionCompletionEngine.TYPE_NUMERIC ) ) { return true; } } } else if ( col instanceof ActionSetFieldCol ) { ActionSetFieldCol c = (ActionSetFieldCol) col; String ft = sce.getFieldType( getBoundFactType( c.getBoundName() ), c.getFactField() ); if ( ft != null && ft.equals( SuggestionCompletionEngine.TYPE_NUMERIC ) ) { return true; } } else if ( col instanceof ActionInsertFactCol ) { ActionInsertFactCol c = (ActionInsertFactCol) col; String ft = sce.getFieldType( c.getFactType(), c.getFactField() ); if ( ft != null && ft.equals( SuggestionCompletionEngine.TYPE_NUMERIC ) ) { return true; } } // we can reuse text filter from guided editor to enforce this for data // entry. return false; } public void setMetadataCols(List<MetadataCol> metadataCols) { this.metadataCols = metadataCols; } public List<MetadataCol> getMetadataCols() { if ( null == metadataCols ) { metadataCols = new ArrayList<MetadataCol>(); } return metadataCols; } /** * Locate index of attribute name if it exists * * @param attributeName * Name of metadata we are looking for * @return index of attribute name or -1 if not found */ public int getMetadataColIndex(String attributeName) { for ( int i = 0; metadataCols != null && i < metadataCols.size(); i++ ) { if ( attributeName.equals( metadataCols.get( i ).attr ) ) { return i; } } return -1; } /** * Update all rows of metadata with value it attribute is present * * @param attributeName * Name of metadata we are looking for * @return true if values update, false if not */ public boolean updateMetadata(String attributeName, String newValue) { // see if metaData exists for int metaIndex = getMetadataColIndex( attributeName ); if ( metaIndex < 0 ) return false; for ( int i = 0; i < getData().length; i++ ) { String[] row = getData()[i]; row[GuidedDecisionTable.INTERNAL_ELEMENTS + metaIndex] = newValue; } return true; } public void setGroupField(String groupField) { this.groupField = groupField; } public String getGroupField() { return groupField; } public void setTableName(String tableName) { this.tableName = tableName; } public String getTableName() { return tableName; } public void setParentName(String parentName) { this.parentName = parentName; } public String getParentName() { return parentName; } public void setAttributeCols(List<AttributeCol> attributeCols) { this.attributeCols = attributeCols; } public List<AttributeCol> getAttributeCols() { return attributeCols; } public void setConditionCols(List<ConditionCol> conditionCols) { this.conditionCols = conditionCols; } public List<ConditionCol> getConditionCols() { return conditionCols; } public void setActionCols(List<ActionCol> actionCols) { this.actionCols = actionCols; } public List<ActionCol> getActionCols() { return actionCols; } public void setData(String[][] data) { this.data = data; } public String[][] getData() { return data; } public void setDescriptionWidth(int descriptionWidth) { this.descriptionWidth = descriptionWidth; } public int getDescriptionWidth() { return descriptionWidth; } }