1 16 package org.apache.cocoon.components.flow.javascript.fom; 17 18 import org.apache.avalon.framework.activity.Initializable; 19 import org.apache.avalon.framework.configuration.Configurable; 20 import org.apache.avalon.framework.configuration.Configuration; 21 import org.apache.avalon.framework.configuration.ConfigurationException; 22 import org.apache.avalon.framework.service.ServiceManager; 23 24 import org.apache.cocoon.ResourceNotFoundException; 25 import org.apache.cocoon.components.ContextHelper; 26 import org.apache.cocoon.components.flow.CompilingInterpreter; 27 import org.apache.cocoon.components.flow.Interpreter; 28 import org.apache.cocoon.components.flow.InvalidContinuationException; 29 import org.apache.cocoon.components.flow.WebContinuation; 30 import org.apache.cocoon.components.flow.javascript.JSErrorReporter; 31 import org.apache.cocoon.components.flow.javascript.LocationTrackingDebugger; 32 import org.apache.cocoon.components.flow.javascript.ScriptablePointerFactory; 33 import org.apache.cocoon.components.flow.javascript.ScriptablePropertyHandler; 34 import org.apache.cocoon.environment.ObjectModelHelper; 35 import org.apache.cocoon.environment.Redirector; 36 import org.apache.cocoon.environment.Request; 37 import org.apache.cocoon.environment.Session; 38 39 import org.apache.commons.jxpath.JXPathIntrospector; 40 import org.apache.commons.jxpath.ri.JXPathContextReferenceImpl; 41 import org.apache.excalibur.source.Source; 42 import org.apache.excalibur.source.SourceResolver; 43 import org.apache.excalibur.source.SourceValidity; 44 import org.apache.regexp.RE; 45 import org.apache.regexp.RECompiler; 46 import org.apache.regexp.REProgram; 47 import org.mozilla.javascript.BaseFunction; 48 import org.mozilla.javascript.Context; 49 import org.mozilla.javascript.EcmaError; 50 import org.mozilla.javascript.Function; 51 import org.mozilla.javascript.JavaScriptException; 52 import org.mozilla.javascript.NativeJavaClass; 53 import org.mozilla.javascript.NativeJavaPackage; 54 import org.mozilla.javascript.PropertyException; 55 import org.mozilla.javascript.Script; 56 import org.mozilla.javascript.ScriptRuntime; 57 import org.mozilla.javascript.Scriptable; 58 import org.mozilla.javascript.ScriptableObject; 59 import org.mozilla.javascript.WrappedException; 60 import org.mozilla.javascript.Wrapper; 61 import org.mozilla.javascript.continuations.Continuation; 62 import org.mozilla.javascript.tools.debugger.Main; 63 import org.mozilla.javascript.tools.shell.Global; 64 65 import java.awt.Dimension ; 66 import java.awt.Toolkit ; 67 import java.io.BufferedReader ; 68 import java.io.IOException ; 69 import java.io.InputStreamReader ; 70 import java.io.OutputStream ; 71 import java.io.PushbackInputStream ; 72 import java.io.Reader ; 73 import java.util.ArrayList ; 74 import java.util.HashMap ; 75 import java.util.HashSet ; 76 import java.util.Iterator ; 77 import java.util.LinkedList ; 78 import java.util.List ; 79 import java.util.Map ; 80 import java.util.Set ; 81 import java.util.StringTokenizer ; 82 83 91 public class FOM_JavaScriptInterpreter extends CompilingInterpreter 92 implements Configurable, Initializable { 93 94 100 private final static String LAST_EXEC_TIME = "__PRIVATE_LAST_EXEC_TIME__"; 101 102 105 private static final String USER_GLOBAL_SCOPE = "FOM JavaScript GLOBAL SCOPE/"; 106 107 111 private static final int OPTIMIZATION_LEVEL = -2; 112 113 117 private long lastTimeCheck; 118 119 122 private Global scope; 123 124 private CompilingClassLoader classLoader; 126 private MyClassRepository javaClassRepository = new MyClassRepository(); 127 private String [] javaSourcePath; 128 129 133 private List topLevelScripts = new ArrayList (); 134 135 private JSErrorReporter errorReporter; 136 private boolean enableDebugger; 137 138 142 protected ServiceManager getServiceManager() { 143 return manager; 144 } 145 146 class MyClassRepository implements CompilingClassLoader.ClassRepository { 147 Map javaSource = new HashMap (); 148 Map javaClass = new HashMap (); 149 Map sourceToClass = new HashMap (); 150 Map classToSource = new HashMap (); 151 152 public synchronized void addCompiledClass(String className, Source src, 153 byte[] contents) { 154 javaSource.put(src.getURI(), src.getValidity()); 155 javaClass.put(className, contents); 156 String uri = src.getURI(); 157 Set set = (Set )sourceToClass.get(uri); 158 if (set == null) { 159 set = new HashSet (); 160 sourceToClass.put(uri, set); 161 } 162 set.add(className); 163 classToSource.put(className, src.getURI()); 164 } 165 166 public synchronized byte[] getCompiledClass(String className) { 167 return (byte[])javaClass.get(className); 168 } 169 170 public synchronized boolean upToDateCheck() throws Exception { 171 SourceResolver sourceResolver = (SourceResolver) 172 getServiceManager().lookup(SourceResolver.ROLE); 173 try { 174 List invalid = new LinkedList (); 175 for (Iterator i = javaSource.entrySet().iterator(); i.hasNext();) { 176 Map.Entry e = (Map.Entry ) i.next(); 177 String uri = (String ) e.getKey(); 178 SourceValidity validity = (SourceValidity) e.getValue(); 179 int valid = validity.isValid(); 180 if (valid == SourceValidity.UNKNOWN) { 181 Source newSrc = null; 182 try { 183 newSrc = sourceResolver.resolveURI(uri); 184 valid = newSrc.getValidity().isValid(validity); 185 } catch (Exception ignored) { 186 } finally { 188 if (newSrc != null) { 189 sourceResolver.release(newSrc); 190 } 191 } 192 } 193 if (valid != SourceValidity.VALID) { 194 invalid.add(uri); 195 } 196 } 197 198 for (Iterator i = invalid.iterator(); i.hasNext();) { 199 String uri = (String ) i.next(); 200 Set set = (Set ) sourceToClass.get(uri); 201 Iterator ii = set.iterator(); 202 while (ii.hasNext()) { 203 String className = (String ) ii.next(); 204 sourceToClass.remove(className); 205 javaClass.remove(className); 206 classToSource.remove(className); 207 } 208 set.clear(); 209 javaSource.remove(uri); 210 } 211 212 return invalid.size() == 0; 213 } finally { 214 getServiceManager().release(sourceResolver); 215 } 216 } 217 } 218 219 223 private static Main debugger; 224 225 static synchronized Main getDebugger() { 226 if (debugger == null) { 227 final Main db = new Main("Cocoon Flow Debugger"); 228 db.pack(); 229 Dimension size = Toolkit.getDefaultToolkit().getScreenSize(); 230 size.width *= 0.75; 231 size.height *= 0.75; 232 db.setSize(size); 233 db.setExitAction(new Runnable () { 234 public void run() { 235 db.setVisible(false); 236 } 237 }); 238 db.setOptimizationLevel(OPTIMIZATION_LEVEL); 239 db.setVisible(true); 240 debugger = db; 241 Context.addContextListener(debugger); 242 } 243 return debugger; 244 } 245 246 public void configure(Configuration config) throws ConfigurationException { 247 super.configure(config); 248 249 String loadOnStartup = config.getChild("load-on-startup").getValue(null); 250 if (loadOnStartup != null) { 251 register(loadOnStartup); 252 } 253 254 String debugger = config.getChild("debugger").getValue(null); 255 enableDebugger = "enabled".equalsIgnoreCase(debugger); 256 257 if (reloadScripts) { 258 String classPath = config.getChild("classpath").getValue(null); 259 synchronized (javaClassRepository) { 260 if (classPath != null) { 261 StringTokenizer izer = new StringTokenizer (classPath, ";"); 262 int i = 0; 263 javaSourcePath = new String [izer.countTokens() + 1]; 264 javaSourcePath[javaSourcePath.length - 1] = ""; 265 while (izer.hasMoreTokens()) { 266 javaSourcePath[i++] = izer.nextToken(); 267 } 268 } else { 269 javaSourcePath = new String []{""}; 270 } 271 updateSourcePath(); 272 } 273 } 274 } 275 276 public void initialize() throws Exception { 277 if (enableDebugger) { 278 if (getLogger().isDebugEnabled()) { 279 getLogger().debug("Flow debugger enabled, creating"); 280 } 281 getDebugger().doBreak(); 282 } 283 Context context = Context.enter(); 284 context.setOptimizationLevel(OPTIMIZATION_LEVEL); 285 context.setCompileFunctionsWithDynamicScope(true); 286 context.setGeneratingDebug(true); 287 JXPathIntrospector.registerDynamicClass(Scriptable.class, 289 ScriptablePropertyHandler.class); 290 JXPathContextReferenceImpl.addNodePointerFactory(new ScriptablePointerFactory()); 291 292 try { 293 scope = new Global(context); 294 FOM_Cocoon.init(scope); 296 errorReporter = new JSErrorReporter(getLogger()); 297 } catch (Exception e) { 298 Context.exit(); 299 e.printStackTrace(); 300 throw e; 301 } 302 } 303 304 private ClassLoader getClassLoader(boolean needsRefresh) throws Exception { 305 if (!reloadScripts) { 306 return Thread.currentThread().getContextClassLoader(); 307 } 308 309 synchronized (javaClassRepository) { 310 boolean reload = needsRefresh || classLoader == null; 311 if (needsRefresh && classLoader != null) { 312 reload = !javaClassRepository.upToDateCheck(); 313 } 314 315 if (reload) { 316 classLoader = new CompilingClassLoader( 318 Thread.currentThread().getContextClassLoader(), 319 (SourceResolver) manager.lookup(SourceResolver.ROLE), 320 javaClassRepository); 321 classLoader.addSourceListener( 322 new CompilingClassLoader.SourceListener() { 323 public void sourceCompiled(Source src) { 324 } 326 327 public void sourceCompilationError(Source src, String msg) { 328 if (src != null) { 329 throw Context.reportRuntimeError(msg); 330 } 331 } 332 }); 333 updateSourcePath(); 334 } 335 return classLoader; 336 } 337 } 338 339 private void updateSourcePath() { 340 if (classLoader != null) { 341 classLoader.setSourcePath(javaSourcePath); 342 } 343 } 344 345 352 private ThreadScope getSessionScope() throws Exception { 353 final String scopeID = USER_GLOBAL_SCOPE + getInterpreterID(); 354 final Request request = ContextHelper.getRequest(this.avalonContext); 355 356 ThreadScope scope = null; 357 358 Session session = request.getSession(false); 360 if (session != null) { 361 scope = (ThreadScope) session.getAttribute(scopeID); 362 } else { 363 scope = (ThreadScope) request.getAttribute(scopeID); 364 } 365 366 if (scope == null) { 367 scope = createThreadScope(); 368 request.setAttribute(scopeID, scope); 370 } 371 372 return scope; 373 } 374 375 382 private void setSessionScope(ThreadScope scope) throws Exception { 383 if (scope.useSession) { 384 final String scopeID = USER_GLOBAL_SCOPE + getInterpreterID(); 385 final Request request = ContextHelper.getRequest(this.avalonContext); 386 387 try { 390 Session session = request.getSession(true); 391 session.setAttribute(scopeID, scope); 392 } catch (IllegalStateException e) { 393 if (getLogger().isDebugEnabled()) { 395 getLogger().debug("Got '" + e + "' while trying to set session scope.", e); 396 } 397 } 398 } 399 } 400 401 public static class ThreadScope extends ScriptableObject { 402 private static final String [] BUILTIN_PACKAGES = {"javax", "org", "com"}; 403 404 private ClassLoader classLoader; 405 406 407 boolean useSession; 408 409 boolean locked = false; 410 411 414 public ThreadScope(Global scope) throws Exception { 415 final Context context = Context.getCurrentContext(); 416 417 final String [] names = { "importClass" }; 418 try { 419 defineFunctionProperties(names, 420 ThreadScope.class, 421 ScriptableObject.DONTENUM); 422 } catch (PropertyException e) { 423 throw new Error (); } 425 426 setPrototype(scope); 427 428 setParentScope(null); 432 433 final Object [] args = {}; 437 FOM_Cocoon cocoon = (FOM_Cocoon) context.newObject(this, 438 "FOM_Cocoon", 439 args); 440 cocoon.setParentScope(this); 441 super.put("cocoon", this, cocoon); 442 443 defineProperty(LAST_EXEC_TIME, 444 new Long (0), 445 ScriptableObject.DONTENUM | ScriptableObject.PERMANENT); 446 } 447 448 public String getClassName() { 449 return "ThreadScope"; 450 } 451 452 public void setLock(boolean lock) { 453 this.locked = lock; 454 } 455 456 public void put(String name, Scriptable start, Object value) { 457 if (this.locked && !has(name, start) && !(value instanceof NativeJavaClass)) { 460 throw new WrappedException (new JavaScriptException("Implicit declaration of global variable '" + name + 462 "' forbidden. Please ensure all variables are explicitely declared with the 'var' keyword")); 463 } 464 this.useSession = true; 465 super.put(name, start, value); 466 } 467 468 public void put(int index, Scriptable start, Object value) { 469 if (this.locked && !has(index, start)) { 471 throw new WrappedException(new JavaScriptException("Global scope locked. Cannot set value for index " + index)); 472 } 473 this.useSession = true; 474 super.put(index, start, value); 475 } 476 477 void onExec() { 479 this.useSession = false; 480 super.put(LAST_EXEC_TIME, this, new Long (System.currentTimeMillis())); 481 } 482 483 484 public static void importClass(Context ctx, 485 Scriptable thisObj, 486 Object [] args, 487 Function funObj) { 488 for (int i = 0; i < args.length; i++) { 489 Object clazz = args[i]; 490 if (!(clazz instanceof NativeJavaClass)) { 491 throw Context.reportRuntimeError("Not a Java class: " + 492 Context.toString(clazz)); 493 } 494 String s = ((NativeJavaClass) clazz).getClassObject().getName(); 495 String n = s.substring(s.lastIndexOf('.') + 1); 496 thisObj.put(n, thisObj, clazz); 497 } 498 } 499 500 public void setupPackages(ClassLoader cl) throws Exception { 501 final String JAVA_PACKAGE = "JavaPackage"; 502 if (classLoader != cl) { 503 classLoader = cl; 504 Scriptable newPackages = new NativeJavaPackage("", cl); 505 newPackages.setParentScope(this); 506 newPackages.setPrototype(ScriptableObject.getClassPrototype(this, JAVA_PACKAGE)); 507 super.put("Packages", this, newPackages); 508 for (int i = 0; i < BUILTIN_PACKAGES.length; i++) { 509 String pkgName = BUILTIN_PACKAGES[i]; 510 Scriptable pkg = new NativeJavaPackage(pkgName, cl); 511 pkg.setParentScope(this); 512 pkg.setPrototype(ScriptableObject.getClassPrototype(this, JAVA_PACKAGE)); 513 super.put(pkgName, this, pkg); 514 } 515 } 516 } 517 518 public ClassLoader getClassLoader() { 519 return classLoader; 520 } 521 } 522 523 private ThreadScope createThreadScope() throws Exception { 524 return new ThreadScope(scope); 525 } 526 527 541 private void setupContext(Redirector redirector, Context context, 542 ThreadScope thrScope) 543 throws Exception { 544 554 FOM_Cocoon cocoon = (FOM_Cocoon) thrScope.get("cocoon", thrScope); 555 long lastExecTime = ((Long ) thrScope.get(LAST_EXEC_TIME, 556 thrScope)).longValue(); 557 boolean needsRefresh = false; 558 if (reloadScripts) { 559 long now = System.currentTimeMillis(); 560 if (now >= lastTimeCheck + checkTime) { 561 needsRefresh = true; 562 } 563 lastTimeCheck = now; 564 } 565 566 ClassLoader classLoader = getClassLoader(needsRefresh); 569 Thread.currentThread().setContextClassLoader(classLoader); 570 thrScope.setupPackages(classLoader); 571 cocoon.pushCallContext(this, redirector, manager, 572 avalonContext, getLogger(), null); 573 574 synchronized (compiledScripts) { 576 List execList = new ArrayList (); 577 if (lastExecTime == 0 || needsRefresh || needResolve.size() > 0) { 582 topLevelScripts.addAll(needResolve); 583 if (lastExecTime != 0 && !needsRefresh) { 584 execList.addAll(needResolve); 585 } else { 586 execList.addAll(topLevelScripts); 587 } 588 needResolve.clear(); 589 } 590 for (int i = 0, size = execList.size(); i < size; i++) { 593 String sourceURI = (String )execList.get(i); 594 ScriptSourceEntry entry = 595 (ScriptSourceEntry)compiledScripts.get(sourceURI); 596 if (entry == null) { 597 Source src = this.sourceresolver.resolveURI(sourceURI); 598 entry = new ScriptSourceEntry(src); 599 compiledScripts.put(sourceURI, entry); 600 } 601 entry.getScript(context, this.scope, needsRefresh, this); 603 } 604 for (int i = 0, size = execList.size(); i < size; i++) { 606 String sourceURI = (String ) execList.get(i); 607 ScriptSourceEntry entry = 608 (ScriptSourceEntry) compiledScripts.get(sourceURI); 609 long lastMod = entry.getSource().getLastModified(); 610 Script script = entry.getScript(context, this.scope, false, this); 611 if (lastExecTime == 0 || lastMod > lastExecTime) { 612 script.exec(context, thrScope); 613 thrScope.onExec(); 614 } 615 } 616 } 617 } 618 619 626 Script compileScript(Context cx, String fileName) throws Exception { 627 Source src = this.sourceresolver.resolveURI(fileName); 628 if (src != null) { 629 synchronized (compiledScripts) { 630 ScriptSourceEntry entry = 631 (ScriptSourceEntry)compiledScripts.get(src.getURI()); 632 Script compiledScript = null; 633 if (entry == null) { 634 compiledScripts.put(src.getURI(), 635 entry = new ScriptSourceEntry(src)); 636 } else { 637 this.sourceresolver.release(src); 638 } 639 compiledScript = entry.getScript(cx, this.scope, false, this); 640 return compiledScript; 641 } 642 } 643 throw new ResourceNotFoundException(fileName + ": not found"); 644 } 645 646 protected Script compileScript(Context cx, Scriptable scope, Source src) 647 throws Exception { 648 PushbackInputStream is = new PushbackInputStream (src.getInputStream(), ENCODING_BUF_SIZE); 649 try { 650 String encoding = findEncoding(is); 651 Reader reader = encoding == null ? new InputStreamReader (is) : new InputStreamReader (is, encoding); 652 reader = new BufferedReader (reader); 653 Script compiledScript = cx.compileReader(scope, reader, 654 src.getURI(), 1, null); 655 return compiledScript; 656 } finally { 657 is.close(); 658 } 659 } 660 661 private final static int ENCODING_BUF_SIZE = 100; 664 REProgram encodingRE = new RECompiler().compile("^.*encoding\\s*=\\s*([^\\s]*)"); 666 667 670 String findEncoding(PushbackInputStream is) throws IOException { 671 byte[] buffer = new byte[ENCODING_BUF_SIZE]; 673 int len = is.read(buffer, 0, buffer.length); 674 is.unread(buffer, 0, len); 676 677 String str = new String (buffer, 0, len, "ASCII"); 679 RE re = new RE(encodingRE); 680 if (re.match(str)) { 681 return re.getParen(1); 682 } 683 return null; 684 } 685 686 697 public void callFunction(String funName, List params, Redirector redirector) 698 throws Exception { 699 Context context = Context.enter(); 700 context.setOptimizationLevel(OPTIMIZATION_LEVEL); 701 context.setGeneratingDebug(true); 702 context.setCompileFunctionsWithDynamicScope(true); 703 context.setErrorReporter(errorReporter); 704 705 LocationTrackingDebugger locationTracker = new LocationTrackingDebugger(); 706 if (!enableDebugger) { 707 context.setDebugger(locationTracker, null); 709 } 710 711 ThreadScope thrScope = getSessionScope(); 712 synchronized (thrScope) { 713 ClassLoader savedClassLoader = 714 Thread.currentThread().getContextClassLoader(); 715 FOM_Cocoon cocoon = null; 716 try { 717 try { 718 setupContext(redirector, context, thrScope); 719 cocoon = (FOM_Cocoon) thrScope.get("cocoon", thrScope); 720 721 FOM_JavaScriptFlowHelper.setFOM_FlowScope(cocoon.getObjectModel(), thrScope); 723 724 if (enableDebugger) { 725 if (!getDebugger().isVisible()) { 726 getDebugger().setVisible(true); 728 } 729 } 730 731 int size = (params != null ? params.size() : 0); 732 Object [] funArgs = new Object [size]; 733 Scriptable parameters = context.newObject(thrScope); 734 for (int i = 0; i < size; i++) { 735 Interpreter.Argument arg = (Interpreter.Argument)params.get(i); 736 funArgs[i] = arg.value; 737 if (arg.name == null) { 738 arg.name = ""; 739 } 740 parameters.put(arg.name, parameters, arg.value); 741 } 742 cocoon.setParameters(parameters); 743 744 Object fun = ScriptableObject.getProperty(thrScope, funName); 745 if (fun == Scriptable.NOT_FOUND) { 746 throw new ResourceNotFoundException("Function \"javascript:" + funName + "()\" not found"); 747 } 748 749 if (fun instanceof BaseFunction) { 751 if (((BaseFunction)fun).getArity() != 0) { 752 getLogger().error("Function '" + funName + "' must have no declared arguments! " + 753 "Use cocoon.parameters to reach parameters passed from the sitemap into the function."); 754 } 755 } 756 757 thrScope.setLock(true); 758 ScriptRuntime.call(context, fun, thrScope, funArgs, thrScope); 759 } catch (JavaScriptException ex) { 760 throw locationTracker.getException("Error calling flowscript function " + funName, ex); 761 } catch (EcmaError ee) { 771 throw locationTracker.getException("Error calling flowscript function " + funName, ee); 772 } 782 } finally { 783 thrScope.setLock(false); 784 setSessionScope(thrScope); 785 if (cocoon != null) { 786 cocoon.popCallContext(); 787 } 788 Context.exit(); 789 Thread.currentThread().setContextClassLoader(savedClassLoader); 790 } 791 } 792 } 793 794 public void handleContinuation(String id, List params, 795 Redirector redirector) throws Exception 796 { 797 WebContinuation wk = continuationsMgr.lookupWebContinuation(id, getInterpreterID()); 798 799 if (wk == null) { 800 804 throw new InvalidContinuationException("The continuation ID " + id + " is invalid."); 805 } 806 807 Context context = Context.enter(); 808 context.setOptimizationLevel(OPTIMIZATION_LEVEL); 809 context.setGeneratingDebug(true); 810 context.setCompileFunctionsWithDynamicScope(true); 811 LocationTrackingDebugger locationTracker = new LocationTrackingDebugger(); 812 if (!enableDebugger) { 813 context.setDebugger(locationTracker, null); 815 } 816 817 Continuation k = (Continuation)wk.getContinuation(); 821 ThreadScope kScope = (ThreadScope)k.getParentScope(); 822 synchronized (kScope) { 823 ClassLoader savedClassLoader = 824 Thread.currentThread().getContextClassLoader(); 825 FOM_Cocoon cocoon = null; 826 try { 827 Thread.currentThread().setContextClassLoader(kScope.getClassLoader()); 828 cocoon = (FOM_Cocoon)kScope.get("cocoon", kScope); 829 kScope.setLock(true); 830 cocoon.pushCallContext(this, redirector, manager, 831 avalonContext, 832 getLogger(), wk); 833 834 FOM_JavaScriptFlowHelper.setFOM_FlowScope(cocoon.getObjectModel(), kScope); 836 837 if (enableDebugger) { 838 getDebugger().setVisible(true); 839 } 840 Scriptable parameters = context.newObject(kScope); 841 int size = params != null ? params.size() : 0; 842 for (int i = 0; i < size; i++) { 843 Interpreter.Argument arg = (Interpreter.Argument)params.get(i); 844 parameters.put(arg.name, parameters, arg.value); 845 } 846 cocoon.setParameters(parameters); 847 FOM_WebContinuation fom_wk = new FOM_WebContinuation(wk); 848 fom_wk.setParentScope(kScope); 849 fom_wk.setPrototype(ScriptableObject.getClassPrototype(kScope, 850 fom_wk.getClassName())); 851 Object [] args = new Object [] {k, fom_wk}; 852 try { 853 ScriptableObject.callMethod(cocoon, 854 "handleContinuation", args); 855 } catch (JavaScriptException ex) { 856 throw locationTracker.getException("Error calling continuation", ex); 857 } catch (EcmaError ee) { 867 throw locationTracker.getException("Error calling continuation", ee); 868 } 878 } finally { 879 kScope.setLock(false); 880 setSessionScope(kScope); 881 if (cocoon != null) { 882 cocoon.popCallContext(); 883 } 884 Context.exit(); 885 Thread.currentThread().setContextClassLoader(savedClassLoader); 886 } 887 } 888 } 889 890 private Throwable unwrap(JavaScriptException e) { 891 Object value = e.getValue(); 892 while (value instanceof Wrapper) { 893 value = ((Wrapper)value).unwrap(); 894 } 895 if (value instanceof Throwable ) { 896 return (Throwable )value; 897 } 898 return e; 899 } 900 901 public void forwardTo(Scriptable scope, FOM_Cocoon cocoon, String uri, 902 Object bizData, FOM_WebContinuation fom_wk, 903 Redirector redirector) 904 throws Exception { 905 setupView(scope, cocoon, fom_wk); 906 super.forwardTo(uri, bizData, 907 fom_wk == null ? null : fom_wk.getWebContinuation(), 908 redirector); 909 } 910 911 void process(Scriptable scope, FOM_Cocoon cocoon, String uri, 913 Object bizData, OutputStream out) 914 throws Exception { 915 setupView(scope, cocoon, null); 916 super.process(uri, bizData, out); 917 } 918 919 private void setupView(Scriptable scope, FOM_Cocoon cocoon, FOM_WebContinuation kont) { 920 Map objectModel = ContextHelper.getObjectModel(this.avalonContext); 921 922 FOM_JavaScriptFlowHelper.setPackages(objectModel, 924 (Scriptable)ScriptableObject.getProperty(scope, "Packages")); 925 FOM_JavaScriptFlowHelper.setJavaPackage(objectModel, 926 (Scriptable)ScriptableObject.getProperty(scope, "java")); 927 928 FOM_JavaScriptFlowHelper.setFOM_Request(objectModel, 930 cocoon.jsGet_request()); 931 FOM_JavaScriptFlowHelper.setFOM_Response(objectModel, 932 cocoon.jsGet_response()); 933 Request request = ObjectModelHelper.getRequest(objectModel); 934 Scriptable session = null; 935 if (request.getSession(false) != null) { 936 session = cocoon.jsGet_session(); 937 } 938 FOM_JavaScriptFlowHelper.setFOM_Session(objectModel, session); 939 940 FOM_JavaScriptFlowHelper.setFOM_Context(objectModel, 941 cocoon.jsGet_context()); 942 if (kont != null) { 943 FOM_JavaScriptFlowHelper.setFOM_WebContinuation(objectModel, kont); 944 } 945 } 946 } 947 | Popular Tags |