001: /*
002: * The Apache Software License, Version 1.1
003: *
004: * Copyright (c) 2002 The Apache Software Foundation. All rights
005: * reserved.
006: *
007: * Redistribution and use in source and binary forms, with or without
008: * modification, are permitted provided that the following conditions
009: * are met:
010: *
011: * 1. Redistributions of source code must retain the above copyright
012: * notice, this list of conditions and the following disclaimer.
013: *
014: * 2. Redistributions in binary form must reproduce the above copyright
015: * notice, this list of conditions and the following disclaimer in
016: * the documentation and/or other materials provided with the
017: * distribution.
018: *
019: * 3. The end-user documentation included with the redistribution, if
020: * any, must include the following acknowlegement:
021: * "This product includes software developed by the
022: * Apache Software Foundation (http://www.apache.org/)."
023: * Alternately, this acknowlegement may appear in the software itself,
024: * if and wherever such third-party acknowlegements normally appear.
025: *
026: * 4. The names "Apache BSF", "Apache", and "Apache Software Foundation"
027: * must not be used to endorse or promote products derived from
028: * this software without prior written permission. For written
029: * permission, please contact apache@apache.org.
030: *
031: * 5. Products derived from this software may not be called "Apache"
032: * nor may "Apache" appear in their names without prior written
033: * permission of the Apache Group.
034: *
035: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
036: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
037: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
038: * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
039: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
040: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
041: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
042: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
043: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
044: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
045: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
046: * SUCH DAMAGE.
047: * ====================================================================
048: *
049: * This software consists of voluntary contributions made by many individuals
050: * on behalf of the Apache Software Foundation and was originally created by
051: * Sanjiva Weerawarana and others at International Business Machines
052: * Corporation. For more information on the Apache Software Foundation,
053: * please see <http://www.apache.org/>.
054: */
055:
056: package org.apache.bsf.engines.jacl;
057:
058: import tcl.lang.*;
059:
060: import java.lang.reflect.Array;
061: import java.util.Vector;
062: import org.apache.bsf.BSFDeclaredBean;
063: import org.apache.bsf.BSFException;
064: import org.apache.bsf.BSFManager;
065: import org.apache.bsf.util.BSFEngineImpl;
066:
067: /**
068: * This is the interface to Scriptics's Jacl (Tcl) from the
069: * Bean Scripting Framework.
070: * <p>
071: *
072: * @author Sanjiva Weerawarana
073: */
074:
075: public class JaclEngine extends BSFEngineImpl {
076: /* the Jacl interpretor object */
077: private Interp interp;
078:
079: /**
080: *
081: * @param method The name of the method to call.
082: * @param args an array of arguments to be
083: * passed to the extension, which may be either
084: * Vectors of Nodes, or Strings.
085: */
086: public Object call(Object obj, String method, Object[] args)
087: throws BSFException {
088: StringBuffer tclScript = new StringBuffer(method);
089: if (args != null) {
090: for (int i = 0; i < args.length; i++) {
091: if (args[i].getClass().isArray()) {
092: tclScript.append(" {");
093:
094: int array_length = Array.getLength(args[i]);
095: for (int j = 0; j < array_length; j++) {
096: tclScript.append("\"").append(
097: Array.get(args[i], j).toString())
098: .append("\"");
099: if (j + 1 < array_length) {
100: tclScript.append(" ");
101: }
102: }
103: tclScript.append("}");
104: } else {
105: tclScript.append(" \"");
106: tclScript.append(args[i].toString());
107: tclScript.append("\"");
108: }
109: }
110:
111: }
112:
113: return eval("<function call>", 0, 0, tclScript.toString());
114: }
115:
116: /**
117: * Declare a bean
118: */
119: public void declareBean(BSFDeclaredBean bean) throws BSFException {
120: String expr = "set " + bean.name + " [bsf lookupBean \""
121: + bean.name + "\"]";
122: eval("<declare bean>", 0, 0, expr);
123: }
124:
125: /**
126: * This is used by an application to evaluate a string containing
127: * some expression.
128: */
129: public Object eval(String source, int lineNo, int columnNo,
130: Object oscript) throws BSFException {
131: String script = oscript.toString();
132: try {
133: interp.eval(script);
134: TclObject result = interp.getResult();
135: Object internalRep = result.getInternalRep();
136:
137: // if the object has a corresponding Java type, unwrap it
138: if (internalRep instanceof ReflectObject)
139: return ReflectObject.get(interp, result);
140: if (internalRep instanceof TclString)
141: return result.toString();
142: if (internalRep instanceof TclDouble)
143: return new Double(TclDouble.get(interp, result));
144: if (internalRep instanceof TclInteger)
145: return new Integer(TclInteger.get(interp, result));
146:
147: return result;
148: } catch (TclException e) {
149: throw new BSFException(BSFException.REASON_EXECUTION_ERROR,
150: "error while eval'ing Jacl expression: "
151: + interp.getResult(), e);
152: }
153: }
154:
155: /**
156: * Initialize the engine.
157: */
158: public void initialize(BSFManager mgr, String lang,
159: Vector declaredBeans) throws BSFException {
160: super .initialize(mgr, lang, declaredBeans);
161:
162: // create interpreter
163: interp = new Interp();
164:
165: // register the extension that user's can use to get at objects
166: // registered by the app
167: interp.createCommand("bsf", new BSFCommand(mgr, this ));
168:
169: // Make java functions be available to Jacl
170: try {
171: interp.eval("jaclloadjava");
172: } catch (TclException e) {
173: throw new BSFException(BSFException.REASON_OTHER_ERROR,
174: "error while loading java package: "
175: + interp.getResult(), e);
176: }
177:
178: int size = declaredBeans.size();
179: for (int i = 0; i < size; i++) {
180: declareBean((BSFDeclaredBean) declaredBeans.elementAt(i));
181: }
182: }
183:
184: /**
185: * Undeclare a previously declared bean.
186: */
187: public void undeclareBean(BSFDeclaredBean bean) throws BSFException {
188: eval("<undeclare bean>", 0, 0, "set " + bean.name + " \"\"");
189: }
190: }
|