/********************************************************************
 * Copyright © 2004 VHA. All rights reserved
 ********************************************************************/
package gov.va.med.fw.rule;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

// Java classes

// Library classes

// Framework classes

// EDB classes

/**
 * Project: Framework
 * 
 * @author DNS   LEV
 * @version 1.0
 */
public class SimpleRuleSession implements RuleSession {

   /**
	 * An instance of serialVersionUID
	 */
	private static final long serialVersionUID = 7376346636442345309L;

	/**
    * An exception handler
    */
   private RuleExceptionHandler handler = null;

   /**
    * A system proerty name to set a debug mode
    */
   public static final String DEBUG_MODE = "rule.engine.debug.mode";

   /**
    * A logger to log information
    */
   protected Log logger = LogFactory.getLog( getClass() );

   /**
    * A rule's state object
    */
   private RuleState state = null;

   /**
    * A flag to indicate whether to continue to execute a next rule
    */
   private boolean continueOnFail = false;

   /**
    * A default constructor
    */
   public SimpleRuleSession() {
      super();
      state = new RuleState();
      setExceptionHandler( new RuleExceptionHandler() );
   }

   /**
    * Returns true to connect to a rule engine to debug a fule. Otherwise,
    * return false. A concrete class returns a default value of false.
    * 
    * @return True if connected to a rule engine to debug false otherwise
    */
   public boolean isDebugEnabled() {

      boolean enabled = false;

      // Geta debug flag as an environment property passed into a JVM in -D
      // option
      String flag = System.getProperty( DEBUG_MODE );

      if( flag != null ) {
         try {
            enabled = Boolean.valueOf( flag ).booleanValue();
         }
         catch( Exception e ) {
            if( logger.isDebugEnabled() ) {
               logger.debug( "Failed to parse a " + DEBUG_MODE + " flag = "
                        + flag, e );
            }
         }
      }
      return enabled;
   }

   /**
    * Returns a state object encapsulates information about the current state of
    * a rule
    * 
    * @return RuleState A rule's state
    */
   public RuleState getState() {
      return state;
   }

   /**
    * Sets a state object encapsulates information about the current state of a
    * rule
    * 
    * @param state
    *           A rule's state
    */
   public void setState(RuleState state) {
      this.state = state;
   }

   /**
    * Check if a next rule in a rule flow should be executed in case of an
    * exception or error
    * 
    * @return True to continue to a next rule. False otherwise
    */
   public boolean isContinueOnFail() {
      return this.continueOnFail;
   }

   /**
    * Sets a flag to indicate whether a next rule in a rule flow should be
    * executed in case of error or exception
    * 
    * @param flag
    *           A flag to indicate whether to continue execution
    */
   public void setContinueOnFail(boolean flag) {
      this.continueOnFail = flag;
   }

   /**
    * Returns an exception handler that is called by a rule engine to handle
    * internal rule engine exceptions or exceptions triggered either in an
    * evaluation or an action part of a rule.
    * 
    * @return RuleExceptionHandler A handler to handle exceptions
    */
   public RuleExceptionHandler getExceptionHandler() {
      return handler;
   }

   /**
    * Sets exception handler that is called by a rule engine to handle internal
    * rule engine exceptions or exceptions triggered either in an evaluation or
    * an action part of a rule.
    * 
    * @param handler
    *           A RuleExceptionHandler to handle exceptions
    */
   public void setExceptionHandler(RuleExceptionHandler handler) {
      this.handler = handler;
   }
}