1 33 package org.jruby.javasupport.bsf; 34 35 import java.util.Arrays ; 36 import java.util.List ; 37 import java.util.Vector ; 38 39 import org.apache.bsf.BSFDeclaredBean; 40 import org.apache.bsf.BSFException; 41 import org.apache.bsf.BSFManager; 42 import org.apache.bsf.util.BSFEngineImpl; 43 import org.apache.bsf.util.BSFFunctions; 44 import org.jruby.Ruby; 45 import org.jruby.ast.Node; 46 import org.jruby.exceptions.JumpException; 47 import org.jruby.exceptions.RaiseException; 48 import org.jruby.javasupport.Java; 49 import org.jruby.javasupport.JavaEmbedUtils; 50 import org.jruby.javasupport.JavaObject; 51 import org.jruby.javasupport.JavaUtil; 52 import org.jruby.runtime.Block; 53 import org.jruby.runtime.DynamicScope; 54 import org.jruby.runtime.GlobalVariable; 55 import org.jruby.runtime.IAccessor; 56 import org.jruby.runtime.ThreadContext; 57 import org.jruby.runtime.builtin.IRubyObject; 58 59 63 public class JRubyEngine extends BSFEngineImpl { 64 private Ruby runtime; 65 66 public Object apply(String file, int line, int col, Object funcBody, Vector paramNames, Vector args) { 67 ThreadContext threadContext = runtime.getCurrentContext(); 68 try { 69 String [] names = new String [paramNames.size()]; 71 paramNames.toArray(names); 72 73 threadContext.preBsfApply(names); 74 75 DynamicScope scope = threadContext.getCurrentScope(); 78 79 for (int i = 0, size = args.size(); i < size; i++) { 81 scope.setValue(i, JavaEmbedUtils.javaToRuby(runtime, args.get(i)), 0); 82 } 83 84 87 Node node = runtime.parse(file, funcBody.toString(), null); 88 return JavaEmbedUtils.rubyToJava(runtime, runtime.getTopSelf().eval(node), Object .class); 89 } finally { 90 threadContext.postBsfApply(); 91 } 92 } 93 94 public Object eval(String file, int line, int col, Object expr) throws BSFException { 95 try { 96 IRubyObject result = runtime.evalScript(expr.toString()); 102 return JavaEmbedUtils.rubyToJava(runtime, result, Object .class); 103 } catch (Exception excptn) { 104 throw new BSFException(BSFException.REASON_EXECUTION_ERROR, "Exception", excptn); 105 } 106 } 107 108 public void exec(String file, int line, int col, Object expr) throws BSFException { 109 try { 110 runtime.evalScript(expr.toString()); 113 } catch (Exception excptn) { 114 throw new BSFException(BSFException.REASON_EXECUTION_ERROR, "Exception", excptn); 115 } 116 } 117 118 public Object call(Object recv, String method, Object [] args) throws BSFException { 119 try { 120 return JavaEmbedUtils.invokeMethod(runtime, recv, method, args, Object .class); 121 } catch (Exception excptn) { 122 printException(runtime, excptn); 123 throw new BSFException(BSFException.REASON_EXECUTION_ERROR, excptn.getMessage(), excptn); 124 } 125 } 126 127 public void initialize(BSFManager manager, String language, Vector someDeclaredBeans) throws BSFException { 128 super.initialize(manager, language, someDeclaredBeans); 129 130 runtime = JavaEmbedUtils.initialize(getClassPath(manager)); 131 132 for (int i = 0, size = someDeclaredBeans.size(); i < size; i++) { 133 BSFDeclaredBean bean = (BSFDeclaredBean) someDeclaredBeans.elementAt(i); 134 runtime.getGlobalVariables().define( 135 GlobalVariable.variableName(bean.name), 136 new BeanGlobalVariable(runtime, bean)); 137 } 138 139 runtime.getGlobalVariables().defineReadonly("$bsf", new FunctionsGlobalVariable(runtime, new BSFFunctions(manager, this))); 140 } 141 142 private List getClassPath(BSFManager manager) { 143 return Arrays.asList(manager.getClassPath().split(System.getProperty("path.separator"))); 144 } 145 146 public void declareBean(BSFDeclaredBean bean) throws BSFException { 147 runtime.getGlobalVariables().define( 148 GlobalVariable.variableName(bean.name), 149 new BeanGlobalVariable(runtime, bean)); 150 } 151 152 public void undeclareBean(BSFDeclaredBean bean) throws BSFException { 153 runtime.getGlobalVariables().set(GlobalVariable.variableName(bean.name), runtime.getNil()); 154 } 155 156 public void handleException(BSFException bsfExcptn) { 157 printException(runtime, (Exception ) bsfExcptn.getTargetException()); 158 } 159 160 166 private static void printException(Ruby runtime, Exception exception) { 167 if (exception instanceof JumpException) { 168 JumpException je = (JumpException)exception; 169 if (je.getJumpType() == JumpException.JumpType.RaiseJump) { 170 runtime.printError(((RaiseException)je).getException()); 171 } else if (je.getJumpType() == JumpException.JumpType.ThrowJump) { 172 runtime.getErrorStream().println("internal error: throw jump caught"); 173 } else if (je.getJumpType() == JumpException.JumpType.BreakJump) { 174 runtime.getErrorStream().println("break without block."); 175 } else if (je.getJumpType() == JumpException.JumpType.ReturnJump) { 176 runtime.getErrorStream().println("return without block."); 177 } 178 } 179 } 180 181 private static class BeanGlobalVariable implements IAccessor { 182 private Ruby runtime; 183 private BSFDeclaredBean bean; 184 185 public BeanGlobalVariable(Ruby runtime, BSFDeclaredBean bean) { 186 this.runtime = runtime; 187 this.bean = bean; 188 } 189 190 public IRubyObject getValue() { 191 IRubyObject result = JavaUtil.convertJavaToRuby(runtime, bean.bean, bean.type); 192 if (result instanceof JavaObject) { 193 return runtime.getModule("JavaUtilities").callMethod(runtime.getCurrentContext(), "wrap", result); 194 } 195 return result; 196 } 197 198 public IRubyObject setValue(IRubyObject value) { 199 bean.bean = JavaUtil.convertArgument(Java.ruby_to_java(runtime.getObject(), value, Block.NULL_BLOCK), bean.type); 200 return value; 201 } 202 } 203 204 private static class FunctionsGlobalVariable implements IAccessor { 205 private Ruby runtime; 206 private BSFFunctions functions; 207 208 public FunctionsGlobalVariable(Ruby runtime, BSFFunctions functions) { 209 this.runtime = runtime; 210 this.functions = functions; 211 } 212 213 public IRubyObject getValue() { 214 IRubyObject result = JavaUtil.convertJavaToRuby(runtime, functions, BSFFunctions.class); 215 if (result instanceof JavaObject) { 216 return runtime.getModule("JavaUtilities").callMethod(runtime.getCurrentContext(), "wrap", result); 217 } 218 return result; 219 } 220 221 public IRubyObject setValue(IRubyObject value) { 222 return value; 223 } 224 } 225 226 229 public void terminate() { 230 JavaEmbedUtils.terminate(runtime); 231 runtime = null; 232 super.terminate(); 233 } 234 } 235 | Popular Tags |