Clover coverage report - Drools - 2.0-rc2
Coverage timestamp: Wed May 11 2005 07:12:26 BST
file stats: LOC: 241   Methods: 6
NCLOC: 132   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
GroovyInterp.java 75% 82.4% 100% 82.2%
coverage coverage
 1    package org.drools.semantics.groovy;
 2   
 3    /*
 4    * $Id: GroovyInterp.java,v 1.6.2.5 2005/05/03 23:45:24 mproctor Exp $
 5    *
 6    * Copyright 2002 (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 groovy.lang.Binding;
 45    import groovy.lang.GroovyClassLoader;
 46    import groovy.lang.GroovyCodeSource;
 47    import groovy.lang.Script;
 48   
 49    import java.io.IOException;
 50    import java.io.ObjectInputStream;
 51    import java.io.ObjectOutputStream;
 52    import java.io.Serializable;
 53    import java.util.Iterator;
 54    import java.util.Map;
 55   
 56    import org.drools.WorkingMemory;
 57    import org.drools.rule.Declaration;
 58    import org.drools.rule.Rule;
 59    import org.drools.spi.DefaultKnowledgeHelper;
 60    import org.drools.spi.Functions;
 61    import org.drools.spi.RuleBaseContext;
 62    import org.drools.spi.Tuple;
 63   
 64    /**
 65    * Base class for Groovy based semantic components.
 66    *
 67    * @author <a href="mailto:james@coredevelopers.net">James Strachan </a>
 68    * @author <a href="mailto:ckl@dacelo.nl">Christiaan ten Klooster </a>
 69    */
 70    public class GroovyInterp
 71    implements
 72    Serializable
 73    {
 74    private static final String LINE_SEPARATOR = System.getProperty( "line.separator" );
 75   
 76    // ------------------------------------------------------------
 77    // Instance members
 78    // ------------------------------------------------------------
 79   
 80    /** Text. */
 81    private final String originalText;
 82   
 83    private String text;
 84   
 85    /** The rule. */
 86    private final Rule rule;
 87   
 88    private transient Script code;
 89   
 90    // ------------------------------------------------------------
 91    // Constructors
 92    // ------------------------------------------------------------
 93   
 94    /**
 95    * Construct.
 96    */
 97  27 protected GroovyInterp(String text,
 98    Rule rule)
 99    {
 100  27 this.rule = rule;
 101  27 this.originalText = text;
 102  27 try
 103    {
 104  27 StringBuffer newText = new StringBuffer( );
 105   
 106  27 Iterator it = rule.getImporter( ).getImports( ).iterator( );
 107  27 while ( it.hasNext( ) )
 108    {
 109  44 newText.append( "import " );
 110  44 newText.append( it.next( ) );
 111  44 newText.append( ";" );
 112  44 newText.append( LINE_SEPARATOR );
 113    }
 114   
 115  27 Functions functions = this.rule.getRuleSet( ).getFunctions( "groovy" );
 116  27 if ( functions != null )
 117    {
 118  0 newText.append( functions.getText( ) );
 119    }
 120   
 121  27 if ( this instanceof GroovyCondition )
 122    {
 123  21 text = "return (" + text + ")";
 124    }
 125  27 newText.append( text );
 126  27 this.text = newText.toString();
 127  27 this.code = buildScript( );
 128    }
 129    catch ( Exception e )
 130    {
 131  0 throw new RuntimeException( e.getLocalizedMessage( ) );
 132    }
 133    }
 134   
 135    // ------------------------------------------------------------
 136    // Instance methods
 137    // ------------------------------------------------------------
 138   
 139    /**
 140    * Retrieve the text to evaluate.
 141    *
 142    * @return The text to evaluate.
 143    */
 144  22 public String getText()
 145    {
 146  22 return this.originalText;
 147    }
 148   
 149  54 protected Script getCode()
 150    {
 151  54 if ( this.code == null )
 152    {
 153  0 try
 154    {
 155  0 this.code = buildScript( );
 156    }
 157    catch( Exception e )
 158    {
 159  0 throw new RuntimeException( e.getLocalizedMessage( ) );
 160    }
 161    }
 162  54 return this.code;
 163    }
 164   
 165  8 protected Rule getRule()
 166    {
 167  8 return this.rule;
 168    }
 169   
 170    /**
 171    * Configure a <code>ScriptContext</code> using a <code>Tuple</code> for
 172    * variable bindings.
 173    *
 174    * @param tuple
 175    * Tuple containing variable bindings.
 176    *
 177    * @return The dictionary
 178    */
 179  27 protected Binding setUpDictionary(Tuple tuple,
 180    Iterator declIter)
 181    {
 182  27 Binding dict = new Binding( );
 183  27 Declaration eachDecl;
 184  27 while ( declIter.hasNext( ) )
 185    {
 186  25 eachDecl = (Declaration) declIter.next( );
 187   
 188  25 dict.setVariable( eachDecl.getIdentifier( ).intern( ),
 189    tuple.get( eachDecl ) );
 190    }
 191   
 192  27 WorkingMemory workingMemory = tuple.getWorkingMemory( );
 193   
 194  27 dict.setVariable( "drools".intern( ),
 195    new DefaultKnowledgeHelper( this.rule,
 196    tuple ) );
 197   
 198  27 Map appDataMap = workingMemory.getApplicationDataMap( );
 199   
 200  27 for ( Iterator keyIter = appDataMap.keySet( ).iterator( ); keyIter.hasNext( ); )
 201    {
 202  10 String key = (String) keyIter.next( );
 203  10 Object value = appDataMap.get( key );
 204   
 205  10 dict.setVariable( key,
 206    value );
 207    }
 208   
 209  27 return dict;
 210    }
 211   
 212  27 private Script buildScript() throws Exception
 213    {
 214  27 GroovyCodeSource codeSource = new GroovyCodeSource( this.text,
 215    "groovy.script",
 216    "groovy.script" );
 217   
 218  27 RuleBaseContext ruleBaseContext = rule.getRuleSet( ).getRuleBaseContext( );
 219  27 ClassLoader cl = (ClassLoader) ruleBaseContext.get( "smf-classLoader" );
 220  27 if ( cl == null )
 221    {
 222  0 cl = Thread.currentThread( ).getContextClassLoader( );
 223  0 ruleBaseContext.put( "smf-classLoader",
 224    cl );
 225    }
 226   
 227  27 if ( cl == null )
 228    {
 229  0 cl = getClass( ).getClassLoader( );
 230  0 ruleBaseContext.put( "smf-classLoader",
 231    cl );
 232    }
 233   
 234  27 GroovyClassLoader loader = new GroovyClassLoader( cl );
 235   
 236  27 Class clazz = loader.parseClass( codeSource );
 237   
 238  27 return (Script) clazz.newInstance( );
 239    }
 240   
 241    }