Package org.drools.brms.client.modeldriven

Source Code of org.drools.brms.client.modeldriven.SuggestionCompletionEngine

package org.drools.brms.client.modeldriven;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import org.drools.brms.client.modeldriven.brl.ActionFieldList;
import org.drools.brms.client.modeldriven.brl.ActionFieldValue;
import org.drools.brms.client.modeldriven.brl.DSLSentence;
import org.drools.brms.client.modeldriven.brl.FactPattern;
import org.drools.brms.client.modeldriven.brl.FieldConstraint;
import org.drools.brms.client.modeldriven.brl.PortableObject;
import org.drools.brms.client.modeldriven.brl.SingleFieldConstraint;

/**
* An suggestion completion processor. This should be usable in both GWT/Web and the IDE.
* The data for this can be loaded into this from simple string lists.
*
* @author Michael Neale
*/
public class SuggestionCompletionEngine
    implements
    PortableObject {

    /** These are the explicit types supported */
    public static final String    TYPE_COLLECTION        = "Collection";
    public static final String    TYPE_COMPARABLE        = "Comparable";
    public static final String    TYPE_STRING            = "String";
    public static final String    TYPE_NUMERIC           = "Numeric";
    public static final String    TYPE_BOOLEAN           = "Boolean";
    //public static final String    TYPE_DATE              = "Date";
    public static final String    TYPE_OBJECT            = "Object"; //for all other unknown types

    /**
     * The operators that are used at different times (based on type).
     */
    private static final String[] STANDARD_CONNECTIVES   = new String[]{"|| ==", "|| !=", "&& !="};
    private static final String[] STRING_CONNECTIVES     = new String[]{"|| ==", "|| !=", "&& !=", "&& matches", "|| matches"};
    private static final String[] COMPARABLE_CONNECTIVES = new String[]{"|| ==", "|| !=", "&& !=", "&& >", "&& <", "|| >", "|| <", "&& >=", "&& <=", "|| <=", "|| >="};
    private static final String[] COLLECTION_CONNECTIVES = new String[]{"|| ==", "|| !=", "&& !=", "|| contains", "&& contains", "|| excludes", "&& excludes"};

    private static final String[] STANDARD_OPERATORS     = new String[]{"==", "!="};
    private static final String[] COMPARABLE_OPERATORS   = new String[]{"==", "!=", "<", ">", "<=", ">="};
    private static final String[] STRING_OPERATORS       = new String[]{"==", "!=", "matches", "soundslike"};
    private static final String[] COLLECTION_OPERATORS   = new String[]{"contains", "excludes", "==", "!="};

    /** The top level conditional elements (first order logic) */
    private static final String[] CONDITIONAL_ELEMENTS   = new String[]{"not", "exists", "or"};

    /**
     * A list of fact types (never fully qualified).
     */
    public String[]               factTypes;

    /**
     * A map of types to the fields. key is type, value is (String[] of fields)
     *
     * @gwt.typeArgs <java.lang.String, java.lang.String[]>
     */
    public Map                    fieldsForType;

    /**
     * A map of the Fields to their types, needed for operator completions,
     * as well as other things like rendering strings, dates etc.
     * This is in the format of: { 'Type.field' => 'typename' }.
     * Should not be the exact type, perhaps just a high level interface, eg "Comparable".
     *
     * @gwt.typeArgs <java.lang.String, java.lang.String>
     */
    public Map                    fieldTypes;

    /**
     * Contains a map of globals (name is key) and their type (value).
     * @gwt.typeArgs <java.lang.String, java.lang.String>
     */
    public Map                    globalTypes            = new HashMap();

    /**
     * Contains a map of { TypeName.field : String[] } - where a list is
     * valid values to display in a drop down for a given Type.field combination.
     * @gwt.typeArgs <java.lang.String, java.lang.String[]>
     */
    public Map             dataEnumLists       = new HashMap();

    /** Operators (from the grammar):
     *      op=(    '=='
     |   '>'
     |   '>='
     |   '<'
     |   '<='
     |   '!='
     |   'contains'
     |   'matches'
     |       'excludes'
     )
     * Connectives add "&" and "|" to this.
     */

    /**
     * DSL language extensions, if needed, if provided by the package.
     */
    public DSLSentence[]          conditionDSLSentences  = new DSLSentence[0];
    public DSLSentence[]          actionDSLSentences     = new DSLSentence[0];

    /**
     * This is used to calculate what fields an enum list may depend on. Optional.
     */
  private transient Map dataEnumLookupFields;

    //    /**
    //     * For bulk loading up the data (from a previous rule save)
    //     *
    //     * @param factToFields A map of "FactType" (key - String) to String[] (value)
    //     * @param factFieldToOperator A map of "FactType.field" (key - String) to String[] operators
    //     * @param factFieldToConnectiveOperator A map of "FactType.field" (key -String) to String[] operators
    //     *                                  that are valid CONNECTIVE operators.
    //     *
    //     * @param globals A map of global variable name to its fields (String[]).
    //     * @param boundFacts A map of bound facts to types.
    //     * @param conditionDSLs a list of DSLSentence suggestions for the LHS
    //     * @param actionDSLs a list of DSLSentence suggestions for the RHS
    //     *
    //     */
    //    public void load(
    //                      Map factToFields,
    //                      Map factFieldToOperator,
    //                      Map factFieldToConnectiveOperator,
    //                      Map globals,
    //                      List conditionDSLs,
    //                      List actionDSLs
    //                    ) {
    //        this.factToFields = factToFields;
    //        this.factFieldToOperator = factFieldToOperator;
    //        this.factFieldToConnectiveOperator = factFieldToConnectiveOperator;
    //        this.actionDSLSentences = actionDSLs;
    //        this.conditionDSLSentences = conditionDSLs;
    //        this.globals = globals;
    //
    //    }

    public SuggestionCompletionEngine() {

    }

    public String[] getConditionalElements() {
        return CONDITIONAL_ELEMENTS;
    }

    public DSLSentence[] getDSLConditions() {
        return this.conditionDSLSentences;
    }

    public DSLSentence[] getDSLActions() {
        return this.actionDSLSentences;
    }

    public String[] getConnectiveOperatorCompletions(final String factType,
                                                     final String fieldName) {
        final String type = (String) this.fieldTypes.get( factType + "." + fieldName );
        if ( type == null ) {
            return STANDARD_CONNECTIVES;
        } else if ( type.equals( TYPE_STRING ) ) {
            return STRING_CONNECTIVES;
        } else if ( type.equals( TYPE_COMPARABLE ) || type.equals( TYPE_NUMERIC ) ) {
            return COMPARABLE_CONNECTIVES;
        } else if ( type.equals( TYPE_COLLECTION ) ) {
            return COLLECTION_CONNECTIVES;
        } else {
            return STANDARD_CONNECTIVES;
        }

    }

    public String[] getFactTypes() {
        return this.factTypes;
    }

    public String[] getFieldCompletions(final String factType) {
        return (String[]) this.fieldsForType.get( factType );

    }

    public String[] getOperatorCompletions(final String factType,
                                           final String fieldName) {
        final String type = (String) this.fieldTypes.get( factType + "." + fieldName );
        if ( type == null ) {
            return STANDARD_OPERATORS;
        } else if ( type.equals( TYPE_STRING ) ) {
            return STRING_OPERATORS;
        } else if ( type.equals( TYPE_COMPARABLE ) || type.equals( TYPE_NUMERIC ) ) {
            return COMPARABLE_OPERATORS;
        } else if ( type.equals( TYPE_COLLECTION ) ) {
            return COLLECTION_OPERATORS;
        } else {
            return STANDARD_OPERATORS;
        }

    }


    /**
     * A map of the Fields to their types, needed for operator completions,
     * as well as other things like rendering strings, dates etc.
     * This is in the format of: { 'Type.field' => 'typename' }.
     * Should not be the exact type, perhaps just a high level interface, eg "Comparable", "Numeric", "String".
     *
     */
    public String getFieldType(final String factType,
                               final String fieldName) {
        return (String) this.fieldTypes.get( factType + "." + fieldName );
    }

    public boolean isGlobalVariable(final String variable) {
        return this.globalTypes.containsKey( variable );
    }

    public String[] getFieldCompletionsForGlobalVariable(final String varName) {
        final String type = (String) this.globalTypes.get( varName );
        return (String[]) this.fieldsForType.get( type );
    }

    private String[] toStringArray(final Set set) {
        final String[] f = new String[set.size()];
        int i = 0;
        for ( final Iterator iter = set.iterator(); iter.hasNext(); ) {
            f[i] = (String) iter.next();
            i++;
        }
        return f;
    }

    public String[] getGlobalVariables() {
        return toStringArray( this.globalTypes.keySet() );
    }

    /**
     * This returns a list of enums options (values) that can be used
     * for the given field of the given FactPattern.
     *
     * This also takes into account enums that depend on other fields.
     *
     */
  public String[] getEnums(FactPattern pat, String field) {

    Map dataEnumLookupFields = loadDataEnumLookupFields();
    String typeField = (String) dataEnumLookupFields.get(pat.factType + "." + field );

    if (pat.constraintList != null && pat.constraintList.constraints != null) {
      FieldConstraint[] cons = pat.constraintList.constraints;
      for (int i = 0; i < cons.length; i++) {
        FieldConstraint con = cons[i];
        if (con instanceof SingleFieldConstraint) {
          SingleFieldConstraint sfc = (SingleFieldConstraint) con;
          if ( sfc.fieldName.equals(typeField)) {
            String key = pat.factType + "." + field + "[" + typeField + "=" + sfc.value + "]";
            return (String[]) this.dataEnumLists.get(key);
          }
        }
      }
    }

    return (String[]) this.dataEnumLists.get(pat.factType + "." + field);
  }

  public String[] getEnums(String type, ActionFieldValue[] currentValues, String field) {
    Map dataEnumLookupFields = loadDataEnumLookupFields();
    String typeField = (String) dataEnumLookupFields.get(type + "." + field );

    if (currentValues != null) {
      for (int i = 0; i < currentValues.length; i++) {
        ActionFieldValue val = currentValues[i];
        if (val.field.equals(typeField)) {
          String key = type + "." + field + "[" + typeField + "=" + val.value + "]";
          return (String[]) this.dataEnumLists.get(key);
        }
      }
    }

    return (String[]) this.dataEnumLists.get(type + "." + field);


  }


  private Map loadDataEnumLookupFields() {
    if (this.dataEnumLookupFields == null) {
      this.dataEnumLookupFields = new HashMap();
      Set keys = this.dataEnumLists.keySet();
      for (Iterator iter = keys.iterator(); iter.hasNext();) {
        String key = (String) iter.next();
        if (key.indexOf('[') != -1) {
          int ix = key.indexOf('[');
          String factField = key.substring(0, ix);
          String predicate = key.substring(ix + 1, key.indexOf(']'));
          String typeField = predicate.substring(0, predicate.indexOf('='));
          dataEnumLookupFields.put(factField, typeField);
        }
      }
    }


    return dataEnumLookupFields;
  }

}
TOP

Related Classes of org.drools.brms.client.modeldriven.SuggestionCompletionEngine

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.