001: /*
002: * $Id: CachingGroovyEngine.java 4166 2006-10-25 07:07:33Z paulk $
003: *
004: * Copyright 2003 (C) James Strachan and Bob Mcwhirter. All Rights Reserved.
005: *
006: * Redistribution and use of this software and associated documentation
007: * ("Software"), with or without modification, are permitted provided that the
008: * following conditions are met: 1. Redistributions of source code must retain
009: * copyright statements and notices. Redistributions must also contain a copy
010: * of this document. 2. Redistributions in binary form must reproduce the above
011: * copyright notice, this list of conditions and the following disclaimer in
012: * the documentation and/or other materials provided with the distribution. 3.
013: * The name "groovy" must not be used to endorse or promote products derived
014: * from this Software without prior written permission of The Codehaus. For
015: * written permission, please contact info@codehaus.org. 4. Products derived
016: * from this Software may not be called "groovy" nor may "groovy" appear in
017: * their names without prior written permission of The Codehaus. "groovy" is a
018: * registered trademark of The Codehaus. 5. Due credit should be given to The
019: * Codehaus - http://groovy.codehaus.org/
020: *
021: * THIS SOFTWARE IS PROVIDED BY THE CODEHAUS AND CONTRIBUTORS ``AS IS'' AND ANY
022: * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
023: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
024: * DISCLAIMED. IN NO EVENT SHALL THE CODEHAUS OR ITS CONTRIBUTORS BE LIABLE FOR
025: * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
026: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
027: * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
028: * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
029: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
030: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
031: * DAMAGE.
032: *
033: */
034: package org.codehaus.groovy.bsf;
035:
036: import groovy.lang.Binding;
037: import groovy.lang.GroovyClassLoader;
038: import groovy.lang.GroovyShell;
039: import groovy.lang.Script;
040: import org.apache.bsf.BSFDeclaredBean;
041: import org.apache.bsf.BSFException;
042: import org.apache.bsf.BSFManager;
043: import org.apache.bsf.util.BSFFunctions;
044: import org.codehaus.groovy.control.CompilerConfiguration;
045: import org.codehaus.groovy.runtime.InvokerHelper;
046:
047: import java.io.ByteArrayInputStream;
048: import java.security.AccessController;
049: import java.security.PrivilegedAction;
050: import java.util.HashMap;
051: import java.util.Map;
052: import java.util.Vector;
053: import java.util.logging.Logger;
054: import java.util.logging.Level;
055:
056: /**
057: * A Caching implementation of the GroovyEngine
058: *
059: * @author James Birchfield
060: */
061: public class CachingGroovyEngine extends GroovyEngine {
062: private static final Logger LOG = Logger
063: .getLogger(CachingGroovyEngine.class.getName());
064: private static final Object[] EMPTY_ARGS = new Object[] { new String[] {} };
065:
066: private Map evalScripts;
067: private Map execScripts;
068: private Binding context;
069: private GroovyClassLoader loader;
070:
071: /**
072: * Evaluate an expression.
073: */
074: public Object eval(String source, int lineNo, int columnNo,
075: Object script) throws BSFException {
076: try {
077: Class scriptClass = (Class) evalScripts.get(script);
078: if (scriptClass == null) {
079: scriptClass = loader.parseClass(
080: new ByteArrayInputStream(script.toString()
081: .getBytes()), source);
082: evalScripts.put(script, scriptClass);
083: } else {
084: LOG.fine("eval() - Using cached script...");
085: }
086: //can't cache the script because the context may be different.
087: //but don't bother loading parsing the class again
088: Script s = InvokerHelper.createScript(scriptClass, context);
089: return s.run();
090: } catch (Exception e) {
091: throw new BSFException(BSFException.REASON_EXECUTION_ERROR,
092: "exception from Groovy: " + e, e);
093: }
094: }
095:
096: /**
097: * Execute a script.
098: */
099: public void exec(String source, int lineNo, int columnNo,
100: Object script) throws BSFException {
101: try {
102: // shell.run(script.toString(), source, EMPTY_ARGS);
103:
104: Class scriptClass = (Class) execScripts.get(script);
105: if (scriptClass == null) {
106: scriptClass = loader.parseClass(
107: new ByteArrayInputStream(script.toString()
108: .getBytes()), source);
109: execScripts.put(script, scriptClass);
110: } else {
111: LOG.fine("exec() - Using cached version of class...");
112: }
113: InvokerHelper.invokeMethod(scriptClass, "main", EMPTY_ARGS);
114: } catch (Exception e) {
115: LOG.log(Level.WARNING, "BSF trace", e);
116: throw new BSFException(BSFException.REASON_EXECUTION_ERROR,
117: "exception from Groovy: " + e, e);
118: }
119: }
120:
121: /**
122: * Initialize the engine.
123: */
124: public void initialize(final BSFManager mgr, String lang,
125: Vector declaredBeans) throws BSFException {
126: super .initialize(mgr, lang, declaredBeans);
127: ClassLoader parent = mgr.getClassLoader();
128: if (parent == null)
129: parent = GroovyShell.class.getClassLoader();
130: final ClassLoader finalParent = parent;
131: this .loader = (GroovyClassLoader) AccessController
132: .doPrivileged(new PrivilegedAction() {
133: public Object run() {
134: CompilerConfiguration configuration = new CompilerConfiguration();
135: configuration.setClasspath(mgr.getClassPath());
136: return new GroovyClassLoader(finalParent,
137: configuration);
138: }
139: });
140: execScripts = new HashMap();
141: evalScripts = new HashMap();
142: context = shell.getContext();
143: // create a shell
144: // register the mgr with object name "bsf"
145: context.setVariable("bsf", new BSFFunctions(mgr, this ));
146: int size = declaredBeans.size();
147: for (int i = 0; i < size; i++) {
148: declareBean((BSFDeclaredBean) declaredBeans.elementAt(i));
149: }
150: }
151: }
|