Clover coverage report - Drools - 2.0-rc2
Coverage timestamp: Wed May 11 2005 07:12:26 BST
file stats: LOC: 407   Methods: 11
NCLOC: 174   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
StatefulRuleSessionImpl.java 68.8% 83.3% 100% 82.7%
coverage coverage
 1    package org.drools.jsr94.rules;
 2   
 3    /*
 4    * $Id: StatefulRuleSessionImpl.java,v 1.17 2004/12/05 20:25:15 dbarnett Exp $
 5    *
 6    * Copyright 2002-2004 (C) The Werken Company. All Rights Reserved.
 7    *
 8    * Redistribution and use of this software and associated documentation
 9    * ("Software"), with or without modification, are permitted provided that the
 10    * following conditions are met:
 11    *
 12    * 1. Redistributions of source code must retain copyright statements and
 13    * notices. Redistributions must also contain a copy of this document.
 14    *
 15    * 2. Redistributions in binary form must reproduce the above copyright notice,
 16    * this list of conditions and the following disclaimer in the documentation
 17    * and/or other materials provided with the distribution.
 18    *
 19    * 3. The name "drools" must not be used to endorse or promote products derived
 20    * from this Software without prior written permission of The Werken Company.
 21    * For written permission, please contact bob@werken.com.
 22    *
 23    * 4. Products derived from this Software may not be called "drools" nor may
 24    * "drools" appear in their names without prior written permission of The Werken
 25    * Company. "drools" is a registered trademark of The Werken Company.
 26    *
 27    * 5. Due credit should be given to The Werken Company.
 28    * (http://drools.werken.com/).
 29    *
 30    * THIS SOFTWARE IS PROVIDED BY THE WERKEN COMPANY AND CONTRIBUTORS ``AS IS''
 31    * AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 32    * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 33    * ARE DISCLAIMED. IN NO EVENT SHALL THE WERKEN COMPANY OR ITS CONTRIBUTORS BE
 34    * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 35    * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 36    * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 37    * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 38    * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 39    * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 40    * POSSIBILITY OF SUCH DAMAGE.
 41    *
 42    */
 43   
 44    import java.util.ArrayList;
 45    import java.util.Iterator;
 46    import java.util.LinkedList;
 47    import java.util.List;
 48    import java.util.Map;
 49   
 50    import javax.rules.Handle;
 51    import javax.rules.InvalidHandleException;
 52    import javax.rules.InvalidRuleSessionException;
 53    import javax.rules.ObjectFilter;
 54    import javax.rules.RuleExecutionSetNotFoundException;
 55    import javax.rules.StatefulRuleSession;
 56   
 57    import org.drools.DroolsException;
 58    import org.drools.FactException;
 59    import org.drools.FactHandle;
 60    import org.drools.NoSuchFactObjectException;
 61    import org.drools.jsr94.rules.admin.RuleExecutionSetImpl;
 62    import org.drools.jsr94.rules.admin.RuleExecutionSetRepository;
 63   
 64    /**
 65    * The Drools implementation of the <code>StatefulRuleSession</code> interface
 66    * which is a representation of a stateful rules engine session. A stateful
 67    * rules engine session exposes a stateful rule execution API to an underlying
 68    * rules engine. The session allows arbitrary objects to be added and removed
 69    * to and from the rule session state. Additionally, objects currently part of
 70    * the rule session state may be updated.
 71    * <p/>
 72    * There are inherently side-effects to adding objects to the rule session
 73    * state. The execution of a RuleExecutionSet can add, remove and update objects
 74    * in the rule session state. The objects in the rule session state are
 75    * therefore dependent on the rules within the <code>RuleExecutionSet</code> as
 76    * well as the rule engine vendor's specific rule engine behavior.
 77    * <p/>
 78    * <code>Handle</code> instances are used by the rule engine vendor to track
 79    * <code>Object</code>s added to the rule session state. This allows multiple
 80    * instances of equivalent <code>Object</code>s to be added to the session state
 81    * and identified, even after serialization.
 82    *
 83    * @see StatefulRuleSession
 84    *
 85    * @author N. Alex Rupp (n_alex <at>codehaus.org)
 86    * @author <a href="mailto:thomas.diesler@softcon-itec.de">thomas diesler </a>
 87    */
 88    public class StatefulRuleSessionImpl
 89    extends AbstractRuleSessionImpl implements StatefulRuleSession
 90    {
 91    // ----------------------------------------------------------------------
 92    // Constructors
 93    // ----------------------------------------------------------------------
 94   
 95    /**
 96    * Gets the <code>RuleExecutionSet</code> for this URI and associates it
 97    * with a RuleBase.
 98    *
 99    * @param bindUri the URI the <code>RuleExecutionSet</code> has been bound
 100    * to
 101    * @param properties additional properties used to create the
 102    * <code>RuleSession</code> implementation.
 103    *
 104    * @throws RuleExecutionSetNotFoundException if there is no rule set under
 105    * the given URI
 106    */
 107  35 StatefulRuleSessionImpl( String bindUri, Map properties )
 108    throws RuleExecutionSetNotFoundException
 109    {
 110  35 this.setProperties( properties );
 111   
 112  35 RuleExecutionSetRepository repository =
 113    RuleExecutionSetRepository.getInstance( );
 114   
 115  35 RuleExecutionSetImpl ruleSet =
 116    ( RuleExecutionSetImpl ) repository.getRuleExecutionSet( bindUri );
 117   
 118  35 if ( ruleSet == null )
 119    {
 120  1 throw new RuleExecutionSetNotFoundException(
 121    "no execution set bound to: " + bindUri );
 122    }
 123   
 124  34 this.setRuleExecutionSet( ruleSet );
 125   
 126  34 this.initWorkingMemory( );
 127    }
 128   
 129    // ----------------------------------------------------------------------
 130    // Instance methods
 131    // ----------------------------------------------------------------------
 132   
 133    /**
 134    * Returns <code>true</code> if the given object is contained
 135    * within rulesession state of this rule session.
 136    *
 137    * @param objectHandle the handle to the target object.
 138    *
 139    * @return <code>true</code> if the given object is contained
 140    * within the rule session state of this rule session.
 141    */
 142  8 public boolean containsObject( Handle objectHandle )
 143    {
 144  8 if ( objectHandle instanceof FactHandle )
 145    {
 146  8 return this.getWorkingMemory( ).containsObject(
 147    ( FactHandle ) objectHandle );
 148    }
 149   
 150  0 return false;
 151    }
 152   
 153    /**
 154    * Adds a given object to the rule session state of this rule session.
 155    * The argument to this method is Object because in the non-managed
 156    * env. not all objects should have to implement Serializable. If the
 157    * <code>RuleSession</code> is <code>Serializable</code> and it contains
 158    * non-serializable fields a runtime exception will be thrown.
 159    *
 160    * @param object the object to be added.
 161    *
 162    * @return the Handle for the newly added Object
 163    *
 164    * @throws InvalidRuleSessionException on illegal rule session state.
 165    */
 166  19 public Handle addObject( Object object ) throws InvalidRuleSessionException
 167    {
 168  19 this.checkRuleSessionValidity( );
 169   
 170  19 try
 171    {
 172  19 return ( Handle ) this.getWorkingMemory( ).assertObject( object );
 173    }
 174    catch ( FactException e )
 175    {
 176  0 throw new InvalidRuleSessionException( "cannot assert object", e );
 177    }
 178    }
 179   
 180    /**
 181    * Adds a <code>List</code> of <code>Object</code>s to the rule session
 182    * state of this rule session.
 183    *
 184    * @param objList the objects to be added.
 185    *
 186    * @return a <code>List</code> of <code>Handle</code>s, one for each added
 187    * <code>Object</code>. The <code>List</code> must be ordered in
 188    * the same order as the input <code>objList</code>.
 189    *
 190    * @throws InvalidRuleSessionException on illegal rule session state.
 191    */
 192  2 public List addObjects( List objList ) throws InvalidRuleSessionException
 193    {
 194  2 this.checkRuleSessionValidity( );
 195   
 196  2 List handles = new ArrayList( );
 197   
 198  2 for ( Iterator objectIter = objList.iterator( ); objectIter.hasNext( ); )
 199    {
 200  5 handles.add( this.addObject( objectIter.next( ) ) );
 201    }
 202  2 return handles;
 203    }
 204   
 205    /**
 206    * Notifies the rules engine that a given object in the rule session
 207    * state has changed.
 208    * <p/>
 209    * The semantics of this call are equivalent to calling
 210    * <code>removeObject</code> followed by <code>addObject</code>. The
 211    * original <code>Handle</code> is rebound to the new value for the
 212    * <code>Object</code> however.
 213    *
 214    * @param objectHandle the handle to the original object.
 215    * @param newObject the new object to bind to the handle.
 216    *
 217    * @throws InvalidRuleSessionException on illegal rule session state.
 218    * @throws InvalidHandleException if the input <code>Handle</code>
 219    * is no longer valid
 220    */
 221  3 public void updateObject( Handle objectHandle, Object newObject )
 222    throws InvalidRuleSessionException, InvalidHandleException
 223    {
 224  3 this.checkRuleSessionValidity( );
 225   
 226  3 if ( objectHandle instanceof FactHandle )
 227    {
 228  3 try
 229    {
 230  3 this.getWorkingMemory( ).modifyObject(
 231    ( FactHandle ) objectHandle, newObject );
 232    }
 233    catch ( FactException e )
 234    {
 235  0 throw new InvalidRuleSessionException(
 236    "cannot update object", e );
 237    }
 238    }
 239    else
 240    {
 241  0 throw new InvalidHandleException( "invalid handle" );
 242   
 243    }
 244    }
 245   
 246    /**
 247    * Removes a given object from the rule session state of this rule session.
 248    *
 249    * @param handleObject the handle to the object to be removed
 250    * from the rule session state.
 251    *
 252    * @throws InvalidRuleSessionException on illegal rule session state.
 253    * @throws InvalidHandleException if the input <code>Handle</code>
 254    * is no longer valid
 255    */
 256  3 public void removeObject( Handle handleObject )
 257    throws InvalidRuleSessionException, InvalidHandleException
 258    {
 259  3 this.checkRuleSessionValidity( );
 260   
 261  3 if ( handleObject instanceof FactHandle )
 262    {
 263  3 try
 264    {
 265  3 this.getWorkingMemory( ).retractObject(
 266    ( FactHandle ) handleObject );
 267    }
 268    catch ( FactException e )
 269    {
 270  0 throw new InvalidRuleSessionException(
 271    "cannot remove object", e );
 272    }
 273    }
 274    else
 275    {
 276  0 throw new InvalidHandleException( "invalid handle" );
 277    }
 278    }
 279   
 280    /**
 281    * Returns a List of all objects in the rule session state of this rule
 282    * session. The objects should pass the default filter test of the default
 283    * <code>RuleExecutionSet</code> filter (if present).
 284    * <p/>
 285    * This may not neccessarily include all objects added by calls to
 286    * <code>addObject</code>, and may include <code>Object</code>s created by
 287    * side-effects. The execution of a <code>RuleExecutionSet</code> can add,
 288    * remove and update objects as part of the rule session state. Therefore
 289    * the rule session state is dependent on the rules that are part of the
 290    * executed <code>RuleExecutionSet</code> as well as the rule vendor's
 291    * specific rule engine behavior.
 292    *
 293    * @return a <code>List</code> of all objects part of the rule session state.
 294    *
 295    * @throws InvalidRuleSessionException on illegal rule session state.
 296    */
 297  5 public List getObjects( ) throws InvalidRuleSessionException
 298    {
 299  5 this.checkRuleSessionValidity( );
 300   
 301  5 return this.getObjects( this.getRuleExecutionSet( ).getObjectFilter( ) );
 302    }
 303   
 304    /**
 305    * Returns a <code>List</code> over the objects in rule session state of
 306    * this rule session. The objects should pass the filter test on the
 307    * specified <code>ObjectFilter</code>.
 308    * <p/>
 309    * This may not neccessarily include all objects added by calls to
 310    * <code>addObject</code>, and may include <code>Object</code>s created by
 311    * side-effects. The execution of a <code>RuleExecutionSet</code> can add,
 312    * remove and update objects as part of the rule session state. Therefore
 313    * the rule session state is dependent on the rules that are part of the
 314    * executed <code>RuleExecutionSet</code> as well as the rule vendor's
 315    * specific rule engine behavior.
 316    *
 317    * @param filter the object filter.
 318    *
 319    * @return a <code>List</code> of all the objects in the rule session state
 320    * of this rule session based upon the given object filter.
 321    *
 322    * @throws InvalidRuleSessionException on illegal rule session state.
 323    */
 324  8 public List getObjects( ObjectFilter filter )
 325    throws InvalidRuleSessionException
 326    {
 327  8 this.checkRuleSessionValidity( );
 328   
 329  8 List objects = new ArrayList( );
 330   
 331  8 objects.addAll( this.getWorkingMemory( ).getObjects( ) );
 332   
 333  8 this.applyFilter( objects, filter );
 334   
 335  8 return objects;
 336    }
 337   
 338    /**
 339    * Executes the rules in the bound rule execution set using the objects
 340    * present in the rule session state. This will typically modify the rule
 341    * session state - and may add, remove or update <code>Object</code>s bound
 342    * to <code>Handle</code>s.
 343    *
 344    * @throws InvalidRuleSessionException on illegal rule session state.
 345    */
 346  4 public void executeRules( ) throws InvalidRuleSessionException
 347    {
 348  4 this.checkRuleSessionValidity( );
 349   
 350  4 try
 351    {
 352  4 this.getWorkingMemory( ).fireAllRules( );
 353    }
 354    catch ( DroolsException e )
 355    {
 356  0 throw new InvalidRuleSessionException( "cannot execute rules", e );
 357    }
 358    }
 359   
 360    /**
 361    * @see StatefulRuleSessionImpl
 362    */
 363  11 public Object getObject( Handle handle )
 364    throws InvalidRuleSessionException, InvalidHandleException
 365    {
 366  11 this.checkRuleSessionValidity( );
 367   
 368  11 if ( handle instanceof FactHandle )
 369    {
 370  11 try
 371    {
 372  11 return this.getWorkingMemory( ).getObject(
 373    ( FactHandle ) handle );
 374    }
 375    catch ( NoSuchFactObjectException e )
 376    {
 377  0 throw new InvalidHandleException( "invalid handle", e );
 378    }
 379    }
 380    else
 381    {
 382  0 throw new InvalidHandleException( "invalid handle" );
 383    }
 384    }
 385   
 386    /**
 387    * Returns a <code>List</code> of the <code>Handle</code>s
 388    * being used for object identity.
 389    *
 390    * @return a <code>List</code> of <code>Handle</code>s present
 391    * in the currect state of the rule session.
 392    */
 393  1 public List getHandles( )
 394    {
 395  1 List handles = new LinkedList( );
 396  1 for ( Iterator i = this.getWorkingMemory( ).getFactHandles( ).iterator( );
 397  3 i.hasNext( ); )
 398    {
 399  2 Object object = i.next( );
 400  2 if ( object instanceof Handle )
 401    {
 402  2 handles.add( object );
 403    }
 404    }
 405  1 return handles;
 406    }
 407    }