Return-Path: Delivered-To: apmail-cocoon-cvs-archive@www.apache.org Received: (qmail 61572 invoked from network); 12 Nov 2004 02:15:02 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur-2.apache.org with SMTP; 12 Nov 2004 02:15:02 -0000 Received: (qmail 23650 invoked by uid 500); 12 Nov 2004 02:15:01 -0000 Delivered-To: apmail-cocoon-cvs-archive@cocoon.apache.org Received: (qmail 23587 invoked by uid 500); 12 Nov 2004 02:15:00 -0000 Mailing-List: contact cvs-help@cocoon.apache.org; run by ezmlm Precedence: bulk Reply-To: dev@cocoon.apache.org list-help: list-unsubscribe: list-post: Delivered-To: mailing list cvs@cocoon.apache.org Received: (qmail 23574 invoked by uid 99); 12 Nov 2004 02:15:00 -0000 Received: from [209.237.227.194] (HELO minotaur.apache.org) (209.237.227.194) by apache.org (qpsmtpd/0.28) with SMTP; Thu, 11 Nov 2004 18:15:00 -0800 Received: (qmail 61502 invoked by uid 65534); 12 Nov 2004 02:14:59 -0000 Date: 12 Nov 2004 02:14:59 -0000 Message-ID: <20041112021459.61500.qmail@minotaur.apache.org> From: vgritsenko@apache.org To: cvs@cocoon.apache.org Subject: svn commit: rev 57488 - cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/components/flow/javascript/fom X-Virus-Checked: Checked X-Spam-Rating: minotaur-2.apache.org 1.6.2 0/1000/N Author: vgritsenko Date: Thu Nov 11 18:14:58 2004 New Revision: 57488 Modified: cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/components/flow/javascript/fom/FOM_JavaScriptInterpreter.java Log: Release source resolver! Add FIXME for another not released source resolver. Other code tweaks. Modified: cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/components/flow/javascript/fom/FOM_JavaScriptInterpreter.java ============================================================================== --- cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/components/flow/javascript/fom/FOM_JavaScriptInterpreter.java (original) +++ cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/components/flow/javascript/fom/FOM_JavaScriptInterpreter.java Thu Nov 11 18:14:58 2004 @@ -98,37 +98,38 @@ /** * Prefix for session/request attribute storing JavaScript global scope object. */ - public static final String USER_GLOBAL_SCOPE = "FOM JavaScript GLOBAL SCOPE/"; + private static final String USER_GLOBAL_SCOPE = "FOM JavaScript GLOBAL SCOPE/"; - // This is the only optimization level that supports continuations - // in the Christoper Oliver's Rhino JavaScript implementation - static int OPTIMIZATION_LEVEL = -2; + /** + * This is the only optimization level that supports continuations + * in the Christoper Oliver's Rhino JavaScript implementation + */ + private static final int OPTIMIZATION_LEVEL = -2; /** * When was the last time we checked for script modifications. Used * only if {@link #reloadScripts} is true. */ - protected long lastTimeCheck = 0; + private long lastTimeCheck; /** * Shared global scope for scripts and other immutable objects */ - Global scope; - - CompilingClassLoader classLoader; + private Global scope; - MyClassRepository javaClassRepository = new MyClassRepository(); - - String[] javaSourcePath; + // FIXME: Does not belong here, should be moved into the sitemap or even higher? + private CompilingClassLoader classLoader; + private MyClassRepository javaClassRepository = new MyClassRepository(); + private String[] javaSourcePath; /** * List of String objects that represent files to be * read in by the JavaScript interpreter. */ - List topLevelScripts = new ArrayList(); + private List topLevelScripts = new ArrayList(); - JSErrorReporter errorReporter; - boolean enableDebugger = false; + private JSErrorReporter errorReporter; + private boolean enableDebugger; /** * Needed to get things working with JDK 1.3. Can be removed once we @@ -139,7 +140,6 @@ } class MyClassRepository implements CompilingClassLoader.ClassRepository { - Map javaSource = new HashMap(); Map javaClass = new HashMap(); Map sourceToClass = new HashMap(); @@ -166,45 +166,48 @@ public synchronized boolean upToDateCheck() throws Exception { SourceResolver sourceResolver = (SourceResolver) getServiceManager().lookup(SourceResolver.ROLE); - Iterator iter = javaSource.entrySet().iterator(); - List invalid = new LinkedList(); - while (iter.hasNext()) { - Map.Entry e = (Map.Entry)iter.next(); - String uri = (String)e.getKey(); - SourceValidity validity = - (SourceValidity)e.getValue(); - int valid = validity.isValid(); - if (valid == SourceValidity.UNKNOWN) { - Source newSrc = null; - try { - newSrc = sourceResolver.resolveURI(uri); - valid = newSrc.getValidity().isValid(validity); - } catch (Exception ignored) { - } finally { - if (newSrc != null) { - sourceResolver.release(newSrc); + try { + List invalid = new LinkedList(); + for (Iterator i = javaSource.entrySet().iterator(); i.hasNext();) { + Map.Entry e = (Map.Entry) i.next(); + String uri = (String) e.getKey(); + SourceValidity validity = (SourceValidity) e.getValue(); + int valid = validity.isValid(); + if (valid == SourceValidity.UNKNOWN) { + Source newSrc = null; + try { + newSrc = sourceResolver.resolveURI(uri); + valid = newSrc.getValidity().isValid(validity); + } catch (Exception ignored) { + } finally { + if (newSrc != null) { + sourceResolver.release(newSrc); + } } } + if (valid != SourceValidity.VALID) { + invalid.add(uri); + } } - if (valid != SourceValidity.VALID) { - invalid.add(uri); - } - } - iter = invalid.iterator(); - while (iter.hasNext()) { - String uri = (String)iter.next(); - Set set = (Set)sourceToClass.get(uri); - Iterator ii = set.iterator(); - while (ii.hasNext()) { - String className = (String)ii.next(); - sourceToClass.remove(className); - javaClass.remove(className); - classToSource.remove(className); + + for (Iterator i = invalid.iterator(); i.hasNext();) { + String uri = (String) i.next(); + Set set = (Set) sourceToClass.get(uri); + Iterator ii = set.iterator(); + while (ii.hasNext()) { + String className = (String) ii.next(); + sourceToClass.remove(className); + javaClass.remove(className); + classToSource.remove(className); + } + set.clear(); + javaSource.remove(uri); } - set.clear(); - javaSource.remove(uri); + + return invalid.size() == 0; + } finally { + getServiceManager().release(sourceResolver); } - return invalid.size() == 0; } } @@ -212,7 +215,7 @@ * JavaScript debugger: there's only one of these: it can debug multiple * threads executing JS code. */ - static Main debugger; + private static Main debugger; static synchronized Main getDebugger() { if (debugger == null) { @@ -238,16 +241,13 @@ public void configure(Configuration config) throws ConfigurationException { super.configure(config); - String loadOnStartup - = config.getChild("load-on-startup", true).getValue(null); + String loadOnStartup = config.getChild("load-on-startup").getValue(null); if (loadOnStartup != null) { register(loadOnStartup); } String debugger = config.getChild("debugger").getValue(null); - if ("enabled".equalsIgnoreCase(debugger)) { - enableDebugger = true; - } + enableDebugger = "enabled".equalsIgnoreCase(debugger); if (reloadScripts) { String classPath = config.getChild("classpath").getValue(null); @@ -300,15 +300,18 @@ if (!reloadScripts) { return Thread.currentThread().getContextClassLoader(); } + synchronized (javaClassRepository) { boolean reload = needsRefresh || classLoader == null; if (needsRefresh && classLoader != null) { reload = !javaClassRepository.upToDateCheck(); } + if (reload) { + // FIXME FIXME FIXME Resolver not released! classLoader = new CompilingClassLoader( Thread.currentThread().getContextClassLoader(), - (SourceResolver)manager.lookup(SourceResolver.ROLE), + (SourceResolver) manager.lookup(SourceResolver.ROLE), javaClassRepository); classLoader.addSourceListener( new CompilingClassLoader.SourceListener() { @@ -316,11 +319,9 @@ // no action } - public void sourceCompilationError(Source src, - String errMsg) { - + public void sourceCompilationError(Source src, String msg) { if (src != null) { - throw Context.reportRuntimeError(errMsg); + throw Context.reportRuntimeError(msg); } } }); @@ -402,14 +403,41 @@ boolean locked = false; - public ThreadScope() { + /** + * Initializes new top-level scope. + */ + public ThreadScope(Global scope) throws Exception { + final Context context = Context.getCurrentContext(); + final String[] names = { "importClass" }; try { - defineFunctionProperties(names, ThreadScope.class, + defineFunctionProperties(names, + ThreadScope.class, ScriptableObject.DONTENUM); } catch (PropertyException e) { throw new Error(); // should never happen } + + setPrototype(scope); + + // We want this to be a new top-level scope, so set its + // parent scope to null. This means that any variables created + // by assignments will be properties of this. + setParentScope(null); + + // Put in the thread scope the Cocoon object, which gives access + // to the interpreter object, and some Cocoon objects. See + // FOM_Cocoon for more details. + final Object[] args = {}; + FOM_Cocoon cocoon = (FOM_Cocoon) context.newObject(this, + "FOM_Cocoon", + args); + cocoon.setParentScope(this); + super.put("cocoon", this, cocoon); + + defineProperty(LAST_EXEC_TIME, + new Long(0), + ScriptableObject.DONTENUM | ScriptableObject.PERMANENT); } public String getClassName() { @@ -441,8 +469,10 @@ super.put(index, start, value); } - void reset() { + // Invoked after script execution + void onExec() { this.useSession = false; + super.put(LAST_EXEC_TIME, this, new Long(System.currentTimeMillis())); } /** Override importClass to allow reloading of classes */ @@ -486,29 +516,7 @@ } private ThreadScope createThreadScope() throws Exception { - Context context = Context.getCurrentContext(); - - ThreadScope thrScope = new ThreadScope(); - - thrScope.setPrototype(scope); - // We want 'thrScope' to be a new top-level scope, so set its - // parent scope to null. This means that any variables created - // by assignments will be properties of "thrScope". - thrScope.setParentScope(null); - // Put in the thread scope the Cocoon object, which gives access - // to the interpreter object, and some Cocoon objects. See - // FOM_Cocoon for more details. - Object[] args = {}; - FOM_Cocoon cocoon = (FOM_Cocoon) - context.newObject(thrScope, "FOM_Cocoon", args); - cocoon.setParentScope(thrScope); - thrScope.put("cocoon", thrScope, cocoon); - thrScope.defineProperty(LAST_EXEC_TIME, - new Long(0), - ScriptableObject.DONTENUM | ScriptableObject.PERMANENT); - - thrScope.reset(); - return thrScope; + return new ThreadScope(scope); } /** @@ -527,7 +535,7 @@ */ private void setupContext(Redirector redirector, Context context, ThreadScope thrScope) - throws Exception { + throws Exception { // Try to retrieve the scope object from the session instance. If // no scope is found, we create a new one, but don't place it in // the session. @@ -538,9 +546,9 @@ // behaviour allows multiple JavaScript functions to share the // same global scope. - FOM_Cocoon cocoon = (FOM_Cocoon)thrScope.get("cocoon", thrScope); - long lastExecTime = ((Long)thrScope.get(LAST_EXEC_TIME, - thrScope)).longValue(); + FOM_Cocoon cocoon = (FOM_Cocoon) thrScope.get("cocoon", thrScope); + long lastExecTime = ((Long) thrScope.get(LAST_EXEC_TIME, + thrScope)).longValue(); boolean needsRefresh = false; if (reloadScripts) { long now = System.currentTimeMillis(); @@ -549,6 +557,7 @@ } lastTimeCheck = now; } + // We need to setup the FOM_Cocoon object according to the current // request. Everything else remains the same. ClassLoader classLoader = getClassLoader(needsRefresh); @@ -589,16 +598,14 @@ } // Execute the scripts if necessary for (int i = 0, size = execList.size(); i < size; i++) { - String sourceURI = (String)execList.get(i); + String sourceURI = (String) execList.get(i); ScriptSourceEntry entry = - (ScriptSourceEntry)compiledScripts.get(sourceURI); + (ScriptSourceEntry) compiledScripts.get(sourceURI); long lastMod = entry.getSource().getLastModified(); Script script = entry.getScript(context, this.scope, false, this); if (lastExecTime == 0 || lastMod > lastExecTime) { script.exec(context, thrScope); - thrScope.put(LAST_EXEC_TIME, thrScope, - new Long(System.currentTimeMillis())); - thrScope.reset(); + thrScope.onExec(); } } } @@ -633,19 +640,15 @@ } protected Script compileScript(Context cx, Scriptable scope, Source src) - throws Exception { + throws Exception { InputStream is = src.getInputStream(); - if (is != null) { - try { - Reader reader = new BufferedReader(new InputStreamReader(is)); - Script compiledScript = cx.compileReader(scope, reader, - src.getURI(), 1, null); - return compiledScript; - } finally { - is.close(); - } - } else { - throw new ResourceNotFoundException(src.getURI() + ": not found"); + try { + Reader reader = new BufferedReader(new InputStreamReader(is)); + Script compiledScript = cx.compileReader(scope, reader, + src.getURI(), 1, null); + return compiledScript; + } finally { + is.close(); } } @@ -676,7 +679,7 @@ try { try { setupContext(redirector, context, thrScope); - cocoon = (FOM_Cocoon)thrScope.get("cocoon", thrScope); + cocoon = (FOM_Cocoon) thrScope.get("cocoon", thrScope); // Register the current scope for scripts indirectly called from this function FOM_JavaScriptFlowHelper.setFOM_FlowScope(cocoon.getObjectModel(), thrScope); @@ -705,6 +708,7 @@ if (fun == Scriptable.NOT_FOUND) { throw new ResourceNotFoundException("Function \"javascript:" + funName + "()\" not found"); } + thrScope.setLock(true); ScriptRuntime.call(context, fun, thrScope, funArgs, thrScope); } catch (JavaScriptException ex) {