KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > codehaus > groovy > bsf > CachingGroovyEngine


1 /*
2  * $Id: CachingGroovyEngine.java,v 1.5 2004/12/14 00:08:26 spullara Exp $
3  *
4  * Copyright 2003 (C) James Strachan and Bob Mcwhirter. All Rights Reserved.
5  *
6  * Redistribution and use of this software and associated documentation
7  * ("Software"), with or without modification, are permitted provided that the
8  * following conditions are met: 1. Redistributions of source code must retain
9  * copyright statements and notices. Redistributions must also contain a copy
10  * of this document. 2. Redistributions in binary form must reproduce the above
11  * copyright notice, this list of conditions and the following disclaimer in
12  * the documentation and/or other materials provided with the distribution. 3.
13  * The name "groovy" must not be used to endorse or promote products derived
14  * from this Software without prior written permission of The Codehaus. For
15  * written permission, please contact info@codehaus.org. 4. Products derived
16  * from this Software may not be called "groovy" nor may "groovy" appear in
17  * their names without prior written permission of The Codehaus. "groovy" is a
18  * registered trademark of The Codehaus. 5. Due credit should be given to The
19  * Codehaus - http://groovy.codehaus.org/
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE CODEHAUS AND CONTRIBUTORS ``AS IS'' AND ANY
22  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24  * DISCLAIMED. IN NO EVENT SHALL THE CODEHAUS OR ITS CONTRIBUTORS BE LIABLE FOR
25  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
31  * DAMAGE.
32  *
33  */

34 package org.codehaus.groovy.bsf;
35
36 import groovy.lang.Binding;
37 import groovy.lang.GroovyClassLoader;
38 import groovy.lang.GroovyShell;
39 import groovy.lang.Script;
40 import org.apache.bsf.BSFDeclaredBean;
41 import org.apache.bsf.BSFException;
42 import org.apache.bsf.BSFManager;
43 import org.apache.bsf.util.BSFFunctions;
44 import org.codehaus.groovy.control.CompilerConfiguration;
45 import org.codehaus.groovy.runtime.InvokerHelper;
46
47 import java.io.ByteArrayInputStream JavaDoc;
48 import java.security.AccessController JavaDoc;
49 import java.security.PrivilegedAction JavaDoc;
50 import java.util.HashMap JavaDoc;
51 import java.util.Map JavaDoc;
52 import java.util.Vector JavaDoc;
53
54 /**
55  * A Caching implementation of the GroovyEngine
56  *
57  * @author James Birchfield
58  */

59 public class CachingGroovyEngine extends GroovyEngine {
60     private static final String JavaDoc[] EMPTY_ARGS = {
61     };
62
63     private Map JavaDoc evalScripts;
64     private Map JavaDoc execScripts;
65     private Binding context;
66     private ClassLoader JavaDoc parent;
67     private GroovyClassLoader loader;
68
69
70     /**
71      * Evaluate an expression.
72      */

73     public Object JavaDoc eval(String JavaDoc source, int lineNo, int columnNo, Object JavaDoc script) throws BSFException {
74         try {
75             // Object result = shell.evaluate(script.toString(), source);
76
Class JavaDoc scriptClass = (Class JavaDoc) evalScripts.get(script);
77             if (scriptClass == null) {
78                 scriptClass = loader.parseClass(new ByteArrayInputStream JavaDoc(script.toString().getBytes()), source);
79                 evalScripts.put(script, scriptClass);
80             } else {
81                 System.out.println("eval() - Using cached script...");
82             }
83             //can't cache the script because the context may be different.
84
//but don't bother loading parsing the class again
85
Script s = InvokerHelper.createScript(scriptClass, context);
86             return s.run();
87         } catch (Exception JavaDoc e) {
88             throw new BSFException(BSFException.REASON_EXECUTION_ERROR, "exception from Groovy: " + e, e);
89         }
90     }
91
92     /**
93      * Execute a script.
94      */

95     public void exec(String JavaDoc source, int lineNo, int columnNo, Object JavaDoc script) throws BSFException {
96         try {
97             // shell.run(script.toString(), source, EMPTY_ARGS);
98

99             Class JavaDoc scriptClass = (Class JavaDoc) execScripts.get(script);
100             if (scriptClass == null) {
101                 scriptClass = loader.parseClass(new ByteArrayInputStream JavaDoc(script.toString().getBytes()), source);
102                 execScripts.put(script, scriptClass);
103             } else {
104                 System.out.println("exec() - Using cached version of class...");
105             }
106             InvokerHelper.invokeMethod(scriptClass, "main", EMPTY_ARGS);
107         } catch (Exception JavaDoc e) {
108             throw new BSFException(BSFException.REASON_EXECUTION_ERROR, "exception from Groovy: " + e, e);
109         }
110     }
111
112     /**
113      * Initialize the engine.
114      */

115     public void initialize(final BSFManager mgr, String JavaDoc lang, Vector JavaDoc declaredBeans) throws BSFException {
116         super.initialize(mgr, lang, declaredBeans);
117         parent = mgr.getClassLoader();
118         if (parent == null)
119             parent = GroovyShell.class.getClassLoader();
120         final ClassLoader JavaDoc finalParent = parent;
121         this.loader =
122                 (GroovyClassLoader) AccessController.doPrivileged(new PrivilegedAction JavaDoc() {
123                     public Object JavaDoc run() {
124                         CompilerConfiguration configuration = new CompilerConfiguration();
125                         configuration.setClasspath(mgr.getClassPath());
126                         return new GroovyClassLoader(finalParent, configuration);
127                     }
128                 });
129         execScripts = new HashMap JavaDoc();
130         evalScripts = new HashMap JavaDoc();
131         context = shell.getContext();
132         // create a shell
133

134         // register the mgr with object name "bsf"
135
context.setVariable("bsf", new BSFFunctions(mgr, this));
136
137         int size = declaredBeans.size();
138         for (int i = 0; i < size; i++) {
139             declareBean((BSFDeclaredBean) declaredBeans.elementAt(i));
140         }
141     }
142 }
143
Popular Tags