1 12 13 package com.openedit.modules.scriptrunner; 14 15 import org.apache.commons.logging.Log; 16 import org.apache.commons.logging.LogFactory; 17 import org.mozilla.javascript.Context; 18 import org.mozilla.javascript.Function; 19 import org.mozilla.javascript.ImporterTopLevel; 20 import org.mozilla.javascript.NativeArray; 21 import org.mozilla.javascript.NativeJavaObject; 22 import org.mozilla.javascript.Scriptable; 23 24 import com.openedit.OpenEditException; 25 26 27 32 public class RhinoScriptRunner implements ScriptRunner 33 { 34 private static final Log LOGGER = LogFactory.getLog(RhinoScriptRunner.class); 35 protected static Scriptable fieldGlobalScope; 36 protected Script fieldScript; 37 protected Scriptable fieldScope; 38 protected boolean fieldInitialized = false; 39 40 public RhinoScriptRunner() 41 { 42 this(null); 43 } 44 45 50 public RhinoScriptRunner(Script inScripts) 51 { 52 setScript(inScripts); 53 54 Context context = Context.enter(); 56 } 57 58 63 public static Scriptable getGlobalScope() 64 { 65 if (fieldGlobalScope == null) 66 { 67 Context context = Context.enter(); 68 fieldGlobalScope = new ImporterTopLevel(context); 69 Context.exit(); 70 } 71 72 return fieldGlobalScope; 73 } 74 75 80 public void setInitialized(boolean initialized) 81 { 82 fieldInitialized = initialized; 83 } 84 85 90 public boolean isInitialized() 91 { 92 return fieldInitialized; 93 } 94 95 100 public void setScope(Scriptable scope) 101 { 102 fieldScope = scope; 103 } 104 105 112 public Scriptable getScope() throws OpenEditException 113 { 114 if (fieldScope == null) 115 { 116 try 117 { 118 Context context = Context.enter(); 119 fieldScope = context.newObject(getGlobalScope()); 120 fieldScope.setPrototype(getGlobalScope()); 121 fieldScope.setParentScope(null); 122 } 123 catch (Exception e) 124 { 125 throw new OpenEditException(e); 126 } 127 finally 128 { 129 Context.exit(); 130 } 131 } 132 133 return fieldScope; 134 } 135 136 141 public void setScript(Script inScript) 142 { 143 fieldScript = inScript; 144 } 145 146 149 public Script getScript() 150 { 151 return fieldScript; 152 } 153 154 159 public void declareBean(String name, Object bean) throws OpenEditException 160 { 161 getScope().put(name, getScope(), Context.toObject(bean, getScope())); 162 } 163 164 167 public Object execFunction(String inFuncName) throws OpenEditException 168 { 169 return execFunction(inFuncName, new Object [0]); 170 } 171 172 175 public Object execFunction(String inFuncName, Object [] inParameters) 176 throws OpenEditException 177 { 178 try 179 { 180 Context context = Context.enter(); 181 182 Thread.currentThread().setContextClassLoader(getClass().getClassLoader()); 184 185 Object function = getScope().get(inFuncName, getScope()); 186 187 if (function instanceof Function) 188 { 189 LOGGER.debug( 190 "Evaluating the " + inFuncName + "() function on " + 191 getScript().getDescription()); 192 193 Object result = ((Function) function).call(context, getScope(), null, inParameters); 194 195 return unmarshal(result); 196 } 197 else 198 { 199 LOGGER.debug( 200 "No " + inFuncName + "() function found on " + getScript().getDescription() + 201 ", was " + function.toString()); 202 } 203 } 204 catch (Exception e) 205 { 206 LOGGER.error("execFunction(): Error during " + inFuncName + "(): " + e.getMessage()); 207 208 throw new OpenEditException(e); 210 } 211 finally 212 { 213 Context.exit(); 214 } 215 216 return null; 217 } 218 219 222 public void init() throws OpenEditException 223 { 224 if (getScript() != null) 225 { 226 try 229 { 230 if (Thread.currentThread().getContextClassLoader() == getClass().getClassLoader()) 235 { 236 setInitialized(true); 237 } 238 239 Context context = Context.enter(); 240 241 if (!isInitialized()) 242 { 243 Thread.currentThread().setContextClassLoader(getClass().getClassLoader()); 244 245 context.setOptimizationLevel(-1); 246 } 247 248 Script script = getScript(); 249 250 context.evaluateString( 251 getScope(), script.getScriptText(), script.getDescription(), 252 script.getStartLineNumber(), null); 253 254 } 256 catch (Exception e) 257 { 258 LOGGER.error("init(): " + e.getMessage()); 259 260 throw new OpenEditException(e); 262 } 263 finally 264 { 265 Context.exit(); 266 } 267 } 268 } 269 270 273 public void terminate() 274 { 275 setScope(null); 276 } 277 278 protected String makeStringFromCode(String inCode) 279 { 280 if ((inCode.indexOf('"') < 0) && (inCode.indexOf('\\') < 0)) 281 { 282 return "\"" + inCode + "\""; 283 } 284 285 StringBuffer sb = new StringBuffer ('"'); 286 287 for (int i = 0; i < inCode.length(); i++) 288 { 289 char c = inCode.charAt(i); 290 291 switch (c) 292 { 293 case '"': 294 sb.append("\\\""); 295 296 break; 297 298 case '\\': 299 sb.append("\\\\"); 300 301 break; 302 303 default: 304 sb.append(c); 305 306 break; 307 } 308 } 309 310 sb.append('"'); 311 312 return sb.toString(); 313 } 314 315 322 protected Object unmarshal(Object inObj) 323 { 324 if (inObj instanceof NativeJavaObject) 325 { 326 return ((NativeJavaObject) inObj).unwrap(); 327 } 328 329 if (inObj instanceof NativeArray) 330 { 331 NativeArray array = (NativeArray) inObj; 332 Object [] result = new Object [(int) array.jsGet_length()]; 333 334 for (int i = 0; i < array.jsGet_length(); i++) 335 { 336 result[i] = unmarshal(array.get(i, null)); 337 } 338 339 return result; 340 } 341 342 return inObj; 343 } 344 } 345 | Popular Tags |