KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > ofbiz > base > util > OfbizBshBsfEngine


1 /*
2  * $Id: OfbizBshBsfEngine.java 5462 2005-08-05 18:35:48Z jonesde $
3  *
4  * Copyright (c) 2001-2005 The Open For Business Project - www.ofbiz.org
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included
14  * in all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
21  * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
22  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  */

24 package org.ofbiz.base.util;
25
26 /*
27  * Based on code that started with this header/license:
28         This file is associated with the BeanShell Java Scripting language
29         distribution (http://www.beanshell.org/).
30  
31         This file is hereby placed into the public domain... You may copy,
32         modify, and redistribute it without restriction.
33  
34  */

35
36 import java.io.StringReader JavaDoc;
37 import java.util.Vector JavaDoc;
38
39 import bsh.EvalError;
40 import bsh.Interpreter;
41 import bsh.InterpreterError;
42 import bsh.TargetError;
43
44 import com.ibm.bsf.BSFDeclaredBean;
45 import com.ibm.bsf.BSFException;
46 import com.ibm.bsf.BSFManager;
47 import com.ibm.bsf.util.BSFEngineImpl;
48
49 import org.ofbiz.base.util.cache.UtilCache;
50
51 /**
52  * This is the BeanShell adapter for IBM's Bean Scripting Famework.
53  * It is an implementation of the BSFEngine class, allowing BSF aware
54  * applications to use BeanShell as a scripting language.
55  * <p>
56  *
57  * I believe this implementation is complete (with some hesitation about the
58  * the usefullness of the compileXXX() style methods - provided by the base
59  * utility class).
60  *
61  * @author Pat Niemeyer
62  * @author David E. Jones
63  */

64 public class OfbizBshBsfEngine extends BSFEngineImpl {
65     
66     public static final String JavaDoc module = OfbizBshBsfEngine.class.getName();
67     
68     protected Interpreter interpreter;
69     protected boolean installedApplyMethod;
70     
71     public static UtilCache parsedScripts = new UtilCache("script.BshBsfParsedCache", 0, 0, false);
72     
73     public void initialize(BSFManager mgr, String JavaDoc lang, Vector JavaDoc declaredBeans) throws BSFException {
74         super.initialize(mgr, lang, declaredBeans);
75         
76         interpreter = BshUtil.getMasterInterpreter(null);
77         
78         // declare the bsf manager for callbacks, etc.
79
try {
80             interpreter.set("bsf", mgr);
81         } catch (EvalError e) {
82             throw new BSFException("bsh internal error: "+e.toString());
83         }
84         
85         for(int i=0; i<declaredBeans.size(); i++) {
86             BSFDeclaredBean bean = (BSFDeclaredBean)declaredBeans.get(i);
87             declareBean(bean);
88         }
89     }
90     
91     public void setDebug(boolean debug) {
92         Interpreter.DEBUG=debug;
93     }
94     
95     /**
96      * Invoke method name on the specified bsh scripted object.
97      * The object may be null to indicate the global namespace of the
98      * interpreter.
99      * @param object may be null for the global namespace.
100      */

101     public Object JavaDoc call(Object JavaDoc object, String JavaDoc name, Object JavaDoc[] args) throws BSFException {
102         if (object == null) {
103             try {
104                 object = interpreter.get("global");
105             } catch (EvalError e) {
106                 throw new BSFException("bsh internal error: "+e.toString());
107             }
108         }
109         
110         if (object instanceof bsh.This) {
111             try {
112                 return ((bsh.This)object).invokeMethod(name, args);
113             } catch (InterpreterError e) {
114                 throw new BSFException("BeanShell interpreter internal error: "+e);
115             } catch (TargetError e2) {
116                 throw new BSFException("The application script threw an exception: " + e2.getTarget());
117             } catch (EvalError e3) {
118                 throw new BSFException("BeanShell script error: "+e3);
119             }
120         } else {
121             throw new BSFException("Cannot invoke method: " + name +
122             ". Object: "+object +" is not a BeanShell scripted object.");
123         }
124     }
125     
126     
127     /**
128      * A helper BeanShell method that implements the anonymous method apply
129      * proposed by BSF. Note that the script below could use the standard
130      * bsh eval() method to set the variables and apply the text, however
131      * then I'd have to escape quotes, etc.
132      */

133     final static String JavaDoc bsfApplyMethod =
134     "_bsfApply(_bsfNames, _bsfArgs, _bsfText) {"
135     +"for(i=0;i<_bsfNames.length;i++)"
136     +"this.namespace.setVariable(_bsfNames[i], _bsfArgs[i]);"
137     +"return this.interpreter.eval(_bsfText, this.namespace);"
138     +"}";
139     
140     /**
141      * This is an implementation of the BSF apply() method.
142      * It exectutes the funcBody text in an "anonymous" method call with
143      * arguments.
144      */

145     public Object JavaDoc apply(String JavaDoc source, int lineNo, int columnNo, Object JavaDoc funcBody, Vector JavaDoc namesVec, Vector JavaDoc argsVec) throws BSFException {
146         if (namesVec.size() != argsVec.size()) throw new BSFException("number of params/names mismatch");
147         if (!(funcBody instanceof String JavaDoc)) throw new BSFException("apply: function body must be a string");
148         
149         String JavaDoc [] names = new String JavaDoc [ namesVec.size() ];
150         namesVec.copyInto(names);
151         Object JavaDoc [] args = new String JavaDoc [ argsVec.size() ];
152         argsVec.copyInto(args);
153         
154         try {
155             if (!installedApplyMethod) {
156                 interpreter.eval(bsfApplyMethod);
157                 installedApplyMethod = true;
158             }
159             
160             bsh.This global = (bsh.This)interpreter.get("global");
161             return global.invokeMethod("_bsfApply", new Object JavaDoc [] { names, args, (String JavaDoc)funcBody });
162             
163         } catch (InterpreterError e) {
164             throw new BSFException("BeanShell interpreter internal error: " + e + sourceInfo(source,lineNo,columnNo));
165         } catch (TargetError e2) {
166             throw new BSFException("The application script threw an exception: " + e2.getTarget() + sourceInfo(source,lineNo,columnNo));
167         } catch (EvalError e3) {
168             throw new BSFException("BeanShell script error: " + e3 + sourceInfo(source,lineNo,columnNo));
169         }
170     }
171     
172     public Object JavaDoc eval(String JavaDoc source, int lineNo, int columnNo, Object JavaDoc expr) throws BSFException {
173         if (!(expr instanceof String JavaDoc)) throw new BSFException("BeanShell expression must be a string");
174         
175         try {
176             //return interpreter.eval(((String) expr));
177

178             Interpreter.ParsedScript script = null;
179             
180             if (source != null && source.length() > 0) {
181                 script = (Interpreter.ParsedScript) parsedScripts.get(source);
182                 if (script == null) {
183                     synchronized (OfbizBshBsfEngine.class) {
184                         script = (Interpreter.ParsedScript) parsedScripts.get(source);
185                         if (script == null) {
186                             script = interpreter.parseScript(source, new StringReader JavaDoc((String JavaDoc) expr));
187                             Debug.logVerbose("Caching BSH script at: " + source, module);
188                             parsedScripts.put(source, script);
189                         }
190                     }
191                 }
192             } else {
193                 script = interpreter.parseScript(source, new StringReader JavaDoc((String JavaDoc) expr));
194             }
195             
196             return interpreter.evalParsedScript(script);
197         } catch (InterpreterError e) {
198             throw new BSFException("BeanShell interpreter internal error: "+ e + sourceInfo(source,lineNo,columnNo));
199         } catch (TargetError e2) {
200             Debug.logError(e2, "Error thrown in BeanShell script called through BSF at: " + sourceInfo(source,lineNo,columnNo), module);
201             //Debug.logError(e2.getTarget(), module);
202
throw new BSFException("The application script threw an exception: " + e2 + " " + sourceInfo(source,lineNo,columnNo));
203         } catch (EvalError e3) {
204             throw new BSFException("BeanShell script error: " + e3 + sourceInfo(source,lineNo,columnNo));
205         }
206     }
207     
208     
209     public void exec(String JavaDoc source, int lineNo, int columnNo, Object JavaDoc script) throws BSFException {
210         eval(source, lineNo, columnNo, script);
211     }
212     
213     
214 /*
215         public void compileApply (String source, int lineNo, int columnNo,
216                 Object funcBody, Vector paramNames, Vector arguments, CodeBuffer cb)
217                 throws BSFException;
218  
219         public void compileExpr (String source, int lineNo, int columnNo,
220                 Object expr, CodeBuffer cb) throws BSFException;
221  
222         public void compileScript (String source, int lineNo, int columnNo,
223                 Object script, CodeBuffer cb) throws BSFException;
224  */

225     
226     public void declareBean(BSFDeclaredBean bean) throws BSFException {
227         try {
228             interpreter.set(bean.name, bean.bean);
229         } catch (EvalError e) {
230             throw new BSFException("error declaring bean: " + bean.name + " : " + e.toString());
231         }
232     }
233     
234     public void undeclareBean(BSFDeclaredBean bean) throws BSFException {
235         try {
236             interpreter.unset(bean.name);
237         } catch (EvalError e) {
238             throw new BSFException("bsh internal error: " + e.toString());
239         }
240     }
241     
242     public void terminate() { }
243     
244     private String JavaDoc sourceInfo(String JavaDoc source, int lineNo, int columnNo) {
245         return "BSF info: " + source + " at line: " + lineNo +" column: " + columnNo;
246     }
247 }
248
Popular Tags