RuleSession.java :  » Rule-Engine » hammurapi-rules » biz » hammurapi » rules » jsr94 » Java Open Source

Java Open Source » Rule Engine » hammurapi rules 
hammurapi rules » biz » hammurapi » rules » jsr94 » RuleSession.java
package biz.hammurapi.rules.jsr94;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.rules.Handle;
import javax.rules.InvalidRuleSessionException;
import javax.rules.ObjectFilter;
import javax.rules.RuleExecutionSetMetadata;
import javax.rules.RuleRuntime;
import javax.rules.RuleSessionCreateException;
import javax.rules.RuleSessionTypeUnsupportedException;
import javax.rules.StatefulRuleSession;
import javax.rules.StatelessRuleSession;

import biz.hammurapi.config.Component;
import biz.hammurapi.config.ConfigurationException;
import biz.hammurapi.config.Context;
import biz.hammurapi.rules.CollectionManager;
import biz.hammurapi.rules.HandleManager;
import biz.hammurapi.rules.KnowledgeBase;
import biz.hammurapi.rules.KnowledgeCompactor;


/**
 * Rule session, a facade to internal components.
 * @author Pavel Vlasov
 * @revision $Revision$
 */
class RuleSession implements StatefulRuleSession, StatelessRuleSession {
  
  /**
   * 
   */
  private static final long serialVersionUID = 5619441714641338077L;
  
  private HandleManager handleManager; 
  private KnowledgeBase knowledgeBase;
  private CollectionManager collectionManager;
  private ObjectFilter objectFilter;
  private int sessionType;
  private RuleExecutionSetMetadata metadata;
  private Component container;

  private KnowledgeCompactor knowledgeCompactor;

  /**
   * Wraps container into a session.
   * Container shall contain at least the following entries:
   * <code>/handle-manager</code> of type <code>HandleManager</code>,
   * <code>/collection-manager</code> of type <code>CollectionManager</code>,
   * <code>/rules</code> with <code>rule</code> subelements,
   * <code>/name</code> (String),
   * <code>/description</code> (String).
   * @throws ConfigurationException 
   * @throws RuleSessionTypeUnsupportedException 
   */
  public RuleSession(Context container, int sessionType, String uri) throws RuleSessionCreateException, RuleSessionTypeUnsupportedException {
    
    if (sessionType==RuleRuntime.STATEFUL_SESSION_TYPE || sessionType==RuleRuntime.STATELESS_SESSION_TYPE) {
      this.sessionType=sessionType;
    } else {
      throw new RuleSessionTypeUnsupportedException("Invalid session type: "+sessionType);
    }    
    
    handleManager=(HandleManager) container.get("/handle-manager");
    if (handleManager==null) {
      throw new RuleSessionCreateException("Handle manager not found");
    }
    
    objectFilter=(ObjectFilter) container.get("/object-filter");
    
    collectionManager=(CollectionManager) container.get("/collection-manager");
    if (collectionManager==null) {
      throw new RuleSessionCreateException("Collection manager not found");
    }
    
    knowledgeBase=(KnowledgeBase) container.get("/rules");
    if (knowledgeBase==null) {
      throw new RuleSessionCreateException("/rules element not found");
    }
    
    knowledgeCompactor=(KnowledgeCompactor) container.get("/knowledge-compactor");
    
    metadata=new biz.hammurapi.rules.jsr94.RuleExecutionSetMetadata(uri, (String) container.get("/name"), (String) container.get("/description"));
    
    if (container instanceof Component) {
      this.container = (Component) container;
      try {
        this.container.start();
      } catch (ConfigurationException e) {
        throw new RuleSessionCreateException("Could not start container: "+e, e);
      }
    }    
  }

  /**
   * This call is delegated to <code>handleManager</code>
   */
  public boolean containsObject(Handle handle) {
    return handleManager.contains(handle);
  }

  /**
   * Adds object to handle manager and to knowledge base.
   */
  public Handle addObject(Object obj) {
    Handle ret = handleManager.addObject(obj);
    knowledgeBase.add(obj);
    return ret;
  }

  /**
   * Invokes addObject() for each member of the list and returns collection of handles.
   */
  public List addObjects(List objs) {
    List ret=new ArrayList();
    Iterator it=objs.iterator();
    while (it.hasNext()) {
      ret.add(addObject(it.next()));
    }
    return ret;
  }

  /**
   * Invokes knowledge base's remove() for the old object, add() for the new object
   * and rebinds the handle to the new object.
   */
  public void updateObject(Handle handle, Object obj) {
    knowledgeBase.remove(handleManager.getObject(handle));
    knowledgeBase.add(obj);
    handleManager.rebind(handle, obj);    
  }

  /**
   * Removes object from knowledge base. Knowledge base is 
   * responsible for removal of the object from the handle manager.
   */
  public void removeObject(Handle handle) {
    knowledgeBase.remove(handleManager.getObject(handle));    
  }

  /**
   * @return List of objects filtered by default object filter.
   */
  public List getObjects() {
    return getObjects(objectFilter);
  }

  /**
   * @return List of handles.
   */
  public List getHandles() {
    return new ArrayList(handleManager.getHandles());
  }

  /**
   * @return List of objects filtered by the <code>filter</code>
   * @param Object filter, can be null.
   */
  public List getObjects(ObjectFilter filter) {  
    List ret = new ArrayList();

    Iterator hit=getHandles().iterator();
    while (hit.hasNext()) {
      Object obj=getObject((Handle) hit.next());
      if (filter==null) {
        ret.add(obj);
      } else {
        obj = filter.filter(obj);
        if (obj!=null) {
          ret.add(obj);
        }
      }
    }
    
    return knowledgeCompactor==null ? ret : knowledgeCompactor.compact(ret);
  }
  
  /**
   * Delegates to knowledgeBase.executeRules(). Normally rules are executed automatically when objects 
   * are added or updated. Invocation of this method may be required in multithreaded inference scenario to make sure that 
   * all threads finished inference process.
   */
  public void executeRules()  {
    knowledgeBase.executeRules();
  }

  /**
   * Clears collection manager, handle manager and resets object filter.
   */
  public void reset() {
    executeRules(); // Make sure that object queue is empty.
    collectionManager.clear();
    handleManager.clear();
    if (objectFilter!=null) {
      objectFilter.reset();
    }
    knowledgeBase.reset();
  }

  /**
   * Returns object by handle.
   */
  public Object getObject(Handle handle) {
    return handleManager.getObject(handle);
  }

  /**
   * Returns execution set metadata.
   */
  public RuleExecutionSetMetadata getRuleExecutionSetMetadata() {
    return metadata;
  }

  /**
   * Stops container.
   */
  public void release() throws InvalidRuleSessionException {
    if (container!=null) {
      try {
        container.stop();
      } catch (ConfigurationException e) {
        throw new InvalidRuleSessionException("Could not stop container", e);
      }
    }    
  }

  /**
   * Returns session type.
   */
  public int getType() {
    return sessionType;
  }
  
  // --- Stateless rule session methods ---

  /**
   * Calls executeRules(object, null)
   */
  public List executeRules(List objects) {    
    return executeRules(objects, null);
  }

  /**
   * This method is a wrapper around stateful method.
   * It adds all objects to the session, executes rules,
   * returns objects and finally resets the session.
   */
  public List executeRules(List objects, ObjectFilter objectFilter) {
    try {
      Iterator it=objects.iterator();
      while (it.hasNext()) {
        addObject(it.next());
      }
      executeRules();
      return getObjects(objectFilter);
    } finally {
      reset();
    }
  }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.