Package com.dtrules.session

Source Code of com.dtrules.session.RSession

/**
* Copyright 2004-2009 DTRules.com, 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 com.dtrules.session;


import java.io.PrintStream;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;

import com.dtrules.decisiontables.RDecisionTable;
import com.dtrules.entity.IREntity;
import com.dtrules.entity.REntity;
import com.dtrules.infrastructure.RulesException;
import com.dtrules.interpreter.IRObject;
import com.dtrules.interpreter.RArray;
import com.dtrules.interpreter.RName;
import com.dtrules.interpreter.RString;
import com.dtrules.interpreter.operators.ROperator;
import com.dtrules.xmlparser.IXMLPrinter;
import com.dtrules.mapping.DataMap;
import com.dtrules.mapping.Mapping;

@SuppressWarnings("unchecked")
public class RSession implements IRSession {

    final RuleSet               rs;
  final DTState               dtstate;
  final EntityFactory         ef;
    int                         uniqueID = 1;
    HashMap<Object,IREntity>    entityInstances = new HashMap<Object,IREntity>();
    ICompiler                   compiler = null;      
    ArrayList<DataMap>          registeredMaps = new ArrayList<DataMap>()
    IDateParser          dateParser = new DateParser();
   
   
    public IDateParser getDateParser() {
    return dateParser;
  }

  public void setDateParser(IDateParser dateParser) {
    this.dateParser = dateParser;
  }

  /**
     * Get the list of Data Maps Registered to this session.
     * @return
     */
    public ArrayList<DataMap> getRegisteredMaps(){
        return registeredMaps;
    }

    private void registerMap(DataMap datamap){
        if(!registeredMaps.contains(datamap)){
            registeredMaps.add(datamap);
        }
    }
   
    /**
     * Allocate a registered data map.  If you want to map Data Objects
     * into the Rules Engine, you need to use this call, providing the
     * mapping which provides information about these Data Objects.
     * @return
     */
    public DataMap getDataMap(Mapping map, String tag){
        DataMap datamap = new DataMap(map,tag,null);
        registerMap(datamap);
        return datamap;
    }
   
   
    /**
     * Get the default mapping
     * @return
     */
    public Mapping getMapping () {
        return rs.getMapping(this);
    }
   
    /**
     * Get a named mapping file
     * @param filename
     * @return
     */
    public Mapping getMapping (String filename){
        return rs.getMapping(filename, this);
    }
   
    /**
     * Gets the Rules Directory used to create this session
     * @return The Rules Directory used to create this session
     */
    public RulesDirectory getRulesDirectory() {
        return rs.getRulesDirectory();
    }
    /**
     * If the session is provided a compiler object, then it can compile
     * the Formal syntax into posfix using this compiler.  A Compiler is
     * really specific to the RuleSet.  However, in the future we may
     * wish that a compiler be specific to the decision table.
     *
     * @param _compiler
     */
    public void setCompiler(ICompiler _compiler){
        compiler = _compiler;
    }
   
    /**
     * Each RSession is associated with a particular RuleSet
     * @param _ef
     * @throws RulesException
     */
    public RSession(RuleSet _rs) throws RulesException {
        rs      = _rs;
        dtstate = new DTState(this);
        ef      = _rs.getEntityFactory(this);
        if(ef.getUniqueID()<100000){
            uniqueID = 100000;
        }else{
            uniqueID = ef.getUniqueID()+100000;
        }   
        /**
         * Add all the reference entities to the session list
         * of entities.
         */
        Iterator<RName> ie = ef.referenceEntities.keySet().iterator();
        while(ie.hasNext()){
            IREntity e  = ef.findRefEntity(ie.next());
            String   id = e.getID()+"";
            if(entityInstances.containsKey(id)){
                throw new RulesException("duplicate","new RSession()","Duplicate id "+id+" found between:\n"
                        +e.getName()+" and "+entityInstances.get(id).getName());
            }
            entityInstances.put(id,e);
        }
        try {
            dtstate.entitypush(ROperator.getPrimitives());
            dtstate.entitypush(ef.decisiontables);
        } catch (RulesException e) {
            throw new RulesException("Initialization Error",
                    "RSession",
                    "Failed to initialize dtstate in init(): "+e.toString());
        }
    }
   
    /**
     * Does a recursive dump of the given entity to standard out.
     * This is a debugging thing.  If DEBUG isn't set in the State of the Session,
     * calling this routine does nothing at all.
     * @param e
     */
    public void dump(REntity e) throws RulesException {

        if(!dtstate.testState(DTState.DEBUG))return;    // Leave if nothing to do.
        dtstate.traceTagBegin("entity", "name",e.getName().stringValue(),"id=",e.getID()+"");
        dump(e,1);
        dtstate.traceTagEnd();
    }
   
    private HashMap<REntity,ArrayList> boundries = new HashMap<REntity,ArrayList>(); // Track printing Entity from Entity boundries to stop recursive printing.
   
    private String getType(REntity e, RName n) throws RulesException{
        int type = e.getEntry(n).type;
        return RSession.typeInt2Str(type);
    }
       
    /**
     * Dumps the Entity and its attributes to the debug output source.  However,
     * if debug isn't enabled, the routine does absolutely nothing.
     * @param e The Entity to be dumped.
     * @param depth Dumping is a private, recursive thing.  depth helps us track its recursive nature.
     */
    private void dump(REntity e,int depth){
        Iterator<RName> anames = e.getAttributeIterator();
        while(anames.hasNext()){
            try {
                RName        aname = anames.next();
                IRObject     value = e.get(aname);
               
                dtstate.traceTagBegin("attribute", "name",aname.stringValue(),"type",getType(e,aname));
                switch(e.getEntry(aname).type){
                   case IRObject.iEntity: {
                      if(value.type()==IRObject.iNull){
                          dtstate.traceInfo("value","type","null","value","null",null);
                          break;
                      }
                      dtstate.traceTagBegin("entity",
                              "name",   ((REntity)value).getName().stringValue(),
                              "id",     ((REntity)value).getID()+"");
                     
                      if(!(boundries.get(e)!= null && boundries.get(e).contains(value))){
                          dtstate.debug(" recurse\n");
                      }else{
                          if(boundries.get(e)==null)boundries.put(e, new ArrayList());
                          boundries.get(e).add(value);
                          dump((REntity)value, depth+1);
                      }
                      dtstate.traceTagEnd();
                      break;
                   }  
                   case IRObject.iArray: {
                      ArrayList values = value.arrayValue();
                      Iterator iv = values.iterator();
                      while(iv.hasNext()){
                          IRObject v = (IRObject) iv.next();
                          if(v.type()==IRObject.iEntity){
                              dump((REntity)v,depth+2);
                          }else{
                              dtstate.traceInfo("value","v",v.stringValue(),null);
                          }
                      }
                      break;
                   }
                   default : {
                       dtstate.traceInfo("value","v",value.stringValue(),null);
                   }
                }
                dtstate.traceTagEnd();
            } catch (RulesException e1) {
                dtstate.debug("Rules Engine Exception\n");
                e1.printStackTrace(dtstate.getErrorOut());
            }
        }
    }
   
   
    /**
     * Return an ID that is unique for this session.  The ID is generated using a simple
     * counter.  This ID will not be unique across all sessions, nor is it very likely to
     * be unique when compared to IDs generated with by methods.
     * <br><br>
     * Unique IDs are used to distinguish various instances of entities apart during
     * exectuion and/or during the generation or loading of a Trace file. They can be
     * used for other purposes as well, under the assumption that the number of unique IDs
     * are less than or equal to 0x7FFFFFFF hex or 2147483647 decimal.
     *
     * @return a Unique ID generated by a simple counter.
     */
    public int getUniqueID(){
        return uniqueID++;
   
 

  /**
     * Compiles the given string into an executable array, per the Rules Engine's interpreter.
     * Assuming this compile completes, the given array is executed.  A RulesException can be
     * thrown either by the compile of the string, or the execution of the resulting array.
     * @param s String to be compiled.
     * @exception RulesException thrown if any problem occurs compiling or executing the string.
     * @see com.dtrules.session.IRSession#execute(java.lang.String)
     */
  public void execute(String s) throws RulesException {
    try {
            RString.newRString(s,true).execute(dtstate);
        } catch (RulesException e) {
            if(getState().testState(DTState.TRACE)){
                getState().traceInfo("Error", e.toString());
                getState().traceEnd();
            }
            throw e;
        }
    return;
  }
  /**
   * Converts the string representation of a type into an index.
   * @param type
   * @return
   * @throws RulesException
   */
  static public int typeStr2Int(String type, String entity, String attribute)throws RulesException{
    type = type.trim();
    if(type.equalsIgnoreCase("list"))type = IRObject.rArray;
        if(type.equalsIgnoreCase("date"))type = IRObject.rTime;
        if(type.equalsIgnoreCase("double"))type = IRObject.rFloat;
    for(int i=0;i<IRObject.types.length;i++){
      if(IRObject.types[i].equalsIgnoreCase(type))return i;
    }
    throw new RulesException("Undefined","typeStr2Int on entity: '"+entity+"' attribute: '"+attribute+"'","Bad Type Encountered:"+type);
  }
  /**
   * Converts the index representation of a type into a String.
   * @param type
   * @return
   * @throws RulesException
   */
  static public String typeInt2Str(int type)throws RulesException {
    if(type<0 || type > IRObject.types.length){
      throw new RulesException("Undefined","typeInt2Str","Bad Type Index Encountered: "+type);
    }
    return IRObject.types[type];
  }
   
  /**
     * Returns the state object for this Session.  The state is used by the Rules Engine in
     * the interpretation of the decision tables.
     * @return DTState The object holds the Data Stack, Entity Stack, and other state of the Rules Engine.
   */
    public DTState getState(){return dtstate; }

  /**
   * @return the ef
   */
  public EntityFactory getEntityFactory() {
    return ef;
  }
  /**
     * Create an Instance of an Entity of the given name.
     * @param name The name of the Entity to create
     * @return     The entity created.
     * @throws RulesException Thrown if any problem occurs (such as an undefined Entity name)
   */
  public IREntity createEntity(Object id, String name) throws RulesException{
        RName entity = RName.getRName(name);
    return createEntity(id, entity);
  }

    /**
     * Create an Instance of an Entity of the given name.
     * @param name The name of the Entity to create
     * @return     The entity created.
     * @throws RulesException Thrown if any problem occurs (such as an undefined Entity name)
     */
  public IREntity createEntity(Object id, RName name) throws RulesException{
      if(id==null){
          id = getUniqueID()+"";
      }
    REntity ref = ef.findRefEntity(name);
        if(ref==null){
            throw new RulesException("undefined","session.createEntity","An attempt ws made to create the entity "+name.stringValue()+"\n" +
                    "This entity isn't defined in the EDD");
        }
        if(!ref.isReadOnly()){
            REntity e = (REntity) ref.clone(this);
            entityInstances.put(e.getID(),e);
            return e;
        }
    return ref;
  }
 
 
  /**
   * @return the rs
   */
  public RuleSet getRuleSet() {
    return rs;
  }
 
 
   public void printEntity(IXMLPrinter rpt, String tag, IREntity e) throws Exception {
       if(tag==null)tag = e.getName().stringValue();
       IRObject id = e.get(RName.getRName("mapping*key"));
       String   idString = id!=null?id.stringValue():"--none--";
         rpt.opentag(tag,"DTRulesId",e.getID()+"","id",idString);
         Iterator<RName> names = e.getAttributeIterator();
         while(names.hasNext()){
             RName    name = names.next();
             IRObject v    = e.get(name);
             if(v.type()==IRObject.iArray && v.rArrayValue().size()==0) continue;
             String   vstr = v==null?"":v.stringValue();
             rpt.printdata("attribute","name",name.stringValue(), vstr);
         }
   }

   public void printArray(IXMLPrinter rpt, ArrayList<IRObject> entitypath, ArrayList<IRObject> printed, DTState state, String name, RArray rarray)throws RulesException{
         if(name!=null && name.length()>0){
             rpt.opentag("array","name",name, "id", rarray.getID());
         }else{
             rpt.opentag("array");
         }
         for(IRObject element : rarray){
             printIRObject(rpt, entitypath, printed, state,"",element);
         }
         rpt.closetag();
     }
    
     public void printEntityReport(IXMLPrinter rpt, DTState state, String objname ) {
         printEntityReport(rpt,false,state,objname);
     }
     public void printEntityReport(IXMLPrinter rpt, boolean verbose, DTState state, String name ) {
         IRObject obj = state.find(name);
         printEntityReport(rpt,verbose,state,name,obj);
     }
    
     public void printEntityReport(IXMLPrinter rpt, boolean verbose, DTState state, String name, IRObject obj ) {
         ArrayList<IRObject> entitypath = new ArrayList<IRObject>();
         ArrayList<IRObject> printed = null;
         if (!verbose) printed = new ArrayList<IRObject>();
         try {
             if(obj==null){
                 rpt.printdata("unknown", "object", name,null);
             }else{
                 printIRObject(rpt,entitypath, printed,state,name,obj);
             }   
         } catch (RulesException e) {
             rpt.print_error(e.toString());
         }
     }
         
     public void printIRObject(IXMLPrinter rpt, ArrayList<IRObject> entitypath, ArrayList<IRObject> printed, DTState state, String name, IRObject v) throws RulesException {
         switch(v.type()){
             case IRObject.iEntity :
                 if(name.length()!=0)rpt.opentag(name);
                 printAllEntities(rpt, entitypath, printed, state, v.rEntityValue());
                 if(name.length()!=0)rpt.closetag();
                 break;
             case IRObject.iArray :
                 if(name.length()!=0)rpt.opentag(name);
                 printArray(rpt, entitypath, printed, state, name, v.rArrayValue());
                 if(name.length()!=0)rpt.closetag();
                 break;
             default:
                 String   vstr = v==null?"":v.stringValue();
                 rpt.printdata("attribute","name",name, vstr);
         }
     }
    
    public void printAllEntities(IXMLPrinter rpt, ArrayList<IRObject> entitypath, ArrayList<IRObject> printed, DTState state, IREntity e) throws RulesException   {
         String entityName = e.getName().stringValue();
         if(entitypath.contains(e) && entitypath.get(entitypath.size()-1)==e){
                 rpt.printdata("entity","name",entityName, "self reference");
         }else if (printed!= null && printed.contains(e)){
                 rpt.printdata("entity","name",entityName,"DTRulesId",e.getID(),"id",e.get("mapping*key").stringValue(),"multiple reference")
         }else{
             entitypath.add(e);
             if(printed!=null) printed.add(e);
             IRObject id = e.get(RName.getRName("mapping*key"));
             String   idString = id!=null?id.stringValue():"--none--";
             rpt.opentag("entity","name",entityName,"DTRulesId",e.getID()+"","id",idString);
             Iterator<RName> names = e.getAttributeIterator();
             while(names.hasNext()){
                 RName    name = names.next();
                 IRObject v    = e.get(name);
                 printIRObject(rpt, entitypath, printed, state, name.stringValue(), v);
             }
             rpt.closetag();
             entitypath.remove(entitypath.size()-1);
         }
     }
  /**
   * Prints all the balanced form of all the decision tables in this session to
   * the given output stream
   * @throws RulesException
   */
    public void printBalancedTables(PrintStream out)throws RulesException {
        Iterator<RName> dts = this.getEntityFactory().getDecisionTableRNameIterator();
        while(dts.hasNext()){
            RName dtname = dts.next();
            RDecisionTable dt = this.getEntityFactory().findDecisionTable(dtname);
            String t = dt.getBalancedTable().getPrintableTable();
           
            out.println();
            out.println(dtname.stringValue());
            out.println();
            out.println(t);
        }
    }
   
}
TOP

Related Classes of com.dtrules.session.RSession

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.