1 /*
2 * Copyright 2004,2004 The Apache Software Foundation.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package org.apache.bsf.util;
18
19 import java.beans.PropertyChangeEvent;
20 import java.util.Vector;
21
22 import org.apache.bsf.BSFDeclaredBean;
23 import org.apache.bsf.BSFEngine;
24 import org.apache.bsf.BSFException;
25 import org.apache.bsf.BSFManager;
26
27 /**
28 * This is a base implementation of the BSFEngine interface which
29 * engine implementations may choose to extend to get the basic
30 * methods of the interface implemented.
31 * <p>
32 *
33 * @author Sanjiva Weerawarana
34 * @author Olivier Gruber (added original debugging support)
35 */
36
37 public abstract class BSFEngineImpl implements BSFEngine {
38
39 protected BSFManager mgr; // my manager
40 protected String lang; // my language string
41 protected Vector declaredBeans; // BSFDeclaredBeans
42 protected String classPath;
43 protected String tempDir;
44 protected ClassLoader classLoader;
45
46 /**
47 * Default impl of apply - calls eval ignoring parameters and returns
48 * the result.
49 */
50 public Object apply(String source, int lineNo, int columnNo,
51 Object funcBody, Vector paramNames, Vector arguments)
52 throws BSFException {
53 return eval(source, lineNo, columnNo, funcBody);
54 }
55
56 /**
57 * Default impl of compileApply - calls compileExpr ignoring parameters.
58 */
59 public void compileApply(String source, int lineNo, int columnNo,
60 Object funcBody, Vector paramNames,
61 Vector arguments, CodeBuffer cb)
62 throws BSFException {
63 compileExpr(source, lineNo, columnNo, funcBody, cb);
64 }
65
66 /**
67 * Default impl of compileExpr - generates code that'll create a new
68 * manager, evaluate the expression, and return the value.
69 */
70 public void compileExpr(String source, int lineNo, int columnNo,
71 Object expr, CodeBuffer cb) throws BSFException {
72 ObjInfo bsfInfo = cb.getSymbol("bsf");
73
74 if (bsfInfo == null) {
75 bsfInfo = new ObjInfo(BSFManager.class, "bsf");
76 cb.addFieldDeclaration("org.apache.bsf.BSFManager bsf = " +
77 "new org.apache.bsf.BSFManager();");
78 cb.putSymbol("bsf", bsfInfo);
79 }
80
81 String evalString = bsfInfo.objName + ".eval(\"" + lang + "\", ";
82 evalString += "request.getRequestURI(), " + lineNo + ", " + columnNo;
83 evalString += "," + StringUtils.lineSeparator;
84 evalString += StringUtils.getSafeString(expr.toString()) + ")";
85
86 ObjInfo oldRet = cb.getFinalServiceMethodStatement();
87
88 if (oldRet != null && oldRet.isExecutable()) {
89 cb.addServiceMethodStatement(oldRet.objName + ";");
90 }
91
92 cb.setFinalServiceMethodStatement(new ObjInfo(Object.class,
93 evalString));
94
95 cb.addServiceMethodException("org.apache.bsf.BSFException");
96 }
97
98 /**
99 * Default impl of compileScript - generates code that'll create a new
100 * manager, and execute the script.
101 */
102 public void compileScript(String source, int lineNo, int columnNo,
103 Object script, CodeBuffer cb)
104 throws BSFException {
105 ObjInfo bsfInfo = cb.getSymbol("bsf");
106
107 if (bsfInfo == null) {
108 bsfInfo = new ObjInfo(BSFManager.class, "bsf");
109 cb.addFieldDeclaration("org.apache.bsf.BSFManager bsf = " +
110 "new org.apache.bsf.BSFManager();");
111 cb.putSymbol("bsf", bsfInfo);
112 }
113
114 String execString = bsfInfo.objName + ".exec(\"" + lang + "\", ";
115 execString += "request.getRequestURI(), " + lineNo + ", " + columnNo;
116 execString += "," + StringUtils.lineSeparator;
117 execString += StringUtils.getSafeString(script.toString()) + ")";
118
119 ObjInfo oldRet = cb.getFinalServiceMethodStatement();
120
121 if (oldRet != null && oldRet.isExecutable()) {
122 cb.addServiceMethodStatement(oldRet.objName + ";");
123 }
124
125 cb.setFinalServiceMethodStatement(new ObjInfo(void.class, execString));
126
127 cb.addServiceMethodException("org.apache.bsf.BSFException");
128 }
129
130 public void declareBean(BSFDeclaredBean bean) throws BSFException {
131 throw new BSFException(BSFException.REASON_UNSUPPORTED_FEATURE,
132 "language " + lang +
133 " does not support declareBean(...).");
134 }
135
136 /**
137 * Default impl of execute - calls eval and ignores the result.
138 */
139 public void exec(String source, int lineNo, int columnNo, Object script)
140 throws BSFException {
141 eval(source, lineNo, columnNo, script);
142 }
143
144 /**
145 * Default impl of interactive execution - calls eval and ignores the result.
146 */
147 public void iexec(String source, int lineNo, int columnNo, Object script)
148 throws BSFException {
149 eval(source, lineNo, columnNo, script);
150 }
151
152 /**
153 * initialize the engine; called right after construction by
154 * the manager. Declared beans are simply kept in a vector and
155 * that's it. Subclasses must do whatever they want with it.
156 */
157 public void initialize(BSFManager mgr, String lang, Vector declaredBeans)
158 throws BSFException {
159
160 this.mgr = mgr;
161 this.lang = lang;
162 this.declaredBeans = declaredBeans;
163
164 // initialize my properties from those of the manager. It'll send
165 // propagate change events to me
166 this.classPath = mgr.getClassPath();
167 this.tempDir = mgr.getTempDir();
168 this.classLoader = mgr.getClassLoader();
169 }
170
171 /**
172 * Receive property change events from the manager and update my fields
173 * as needed.
174 *
175 * @param e PropertyChange event with the change data
176 */
177 public void propertyChange(PropertyChangeEvent e) {
178 String name = e.getPropertyName();
179 Object value = e.getNewValue();
180
181 if (name.equals("classPath")) {
182 classPath = (String) value;
183 }
184 else if (name.equals("tempDir")) {
185 tempDir = (String) value;
186 }
187 else if (name.equals("classLoader")) {
188 classLoader = (ClassLoader) value;
189 }
190 }
191
192 public void terminate() {
193 mgr = null;
194 declaredBeans = null;
195 classLoader = null;
196 }
197
198 public void undeclareBean(BSFDeclaredBean bean) throws BSFException {
199 throw new BSFException(BSFException.REASON_UNSUPPORTED_FEATURE,
200 "language " + lang +
201 " does not support undeclareBean(...).");
202 }
203 }