coliver 2003/03/15 01:56:04
Modified: src/java/org/apache/cocoon/components/flow/javascript
JSCocoon.java JSErrorReporter.java
JavaScriptInterpreter.java
ScriptableConnection.java
Removed: src/java/org/apache/cocoon/components/flow/javascript
ListInputStream.java SourceInfo.java
Log:
fixed error handling and the cocoon.load() function
Revision Changes Path
1.2 +336 -325
cocoon-2.1/src/java/org/apache/cocoon/components/flow/javascript/JSCocoon.java
Index: JSCocoon.java
===================================================================
RCS file:
/home/cvs/cocoon-2.1/src/java/org/apache/cocoon/components/flow/javascript/JSCocoon.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- JSCocoon.java 9 Mar 2003 00:08:50 -0000 1.1
+++ JSCocoon.java 15 Mar 2003 09:56:04 -0000 1.2
@@ -55,6 +55,9 @@
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptRuntime;
import org.mozilla.javascript.NativeArray;
+import org.mozilla.javascript.Script;
+import org.mozilla.javascript.JavaScriptException;
+
import org.apache.cocoon.sitemap.SitemapRedirector;
import org.apache.cocoon.environment.SourceResolver;
import org.apache.cocoon.environment.Session;
@@ -88,362 +91,370 @@
*/
public class JSCocoon extends ScriptableObject
{
- protected static String OBJECT_SOURCE_RESOLVER = "source-resolver";
- protected JavaScriptInterpreter interpreter;
- protected Scriptable scope;
- protected NativeArray parameters;
- protected Environment environment;
- protected ComponentManager manager;
-
- public JSCocoon() {}
-
- public String getClassName()
- {
- return "Cocoon";
- }
-
- public void setScope(Scriptable scope)
- {
- this.scope = scope;
- }
-
- public Scriptable getScope()
- {
- return scope;
- }
-
- public void setParameters(NativeArray parameters)
- {
- this.parameters = parameters;
- }
-
- public void setInterpreter(JavaScriptInterpreter interpreter)
- {
- this.interpreter = interpreter;
- }
-
- public void setContext(ComponentManager manager, Environment environment)
- {
- this.manager = manager;
- this.environment = environment;
- }
-
- public void invalidateContext()
- {
- manager = null;
- environment = null;
- }
-
- public NativeArray jsGet_parameters()
- {
- return parameters;
- }
-
- public JavaScriptInterpreter jsGet_interpreter()
- {
- return interpreter;
- }
-
- public Environment jsGet_environment()
- {
- return environment;
- }
-
- public Request jsGet_request()
- {
- if (environment == null) {
- // context has been invalidated
- return null;
- }
- Map objectModel = environment.getObjectModel();
- return ObjectModelHelper.getRequest(objectModel);
- }
-
- public Response jsGet_response()
- {
- if (environment == null) {
- // context has been invalidated
- return null;
- }
- Map objectModel = environment.getObjectModel();
- return ObjectModelHelper.getResponse(objectModel);
- }
-
- public Session jsGet_session()
- {
- if (environment == null) {
- // context has been invalidated
- return null;
- }
- return jsGet_request().getSession();
- }
-
- public Context jsGet_context()
- {
- if (environment == null) {
- // context has been invalidated
- return null;
- }
- Map objectModel = environment.getObjectModel();
- return ObjectModelHelper.getContext(objectModel);
- }
-
- public ComponentManager jsGet_componentManager()
- {
- return manager;
- }
-
-
-
- /**
- * Load the file specified as argument. Registers the file with the
- * interpreter and then forces its loading by calling [EMAIL PROTECTED]
- * JavaScriptInterpreter#checkForModifiedScripts}.
- *
- * @param filename a <code>String</code> value
- * @return an <code>Object</code> value
- * @exception Exception if an error occurs
- */
- public Object jsFunction_load(String filename)
- throws Exception
- {
- try {
- interpreter.register(filename);
- interpreter.checkForModifiedScripts(environment);
- }
- catch (Exception ex) {
- ex.printStackTrace();
- throw ex;
- }
- return null;
- }
-
- public String jsFunction_toString()
- {
- return "[object " + toString() + "]";
- }
-
- public void jsFunction_forwardTo(String uri, Object bizData, Object cont)
- throws Exception
- {
- bizData = jsobjectToObject(bizData);
-
- WebContinuation kont = null;
-
- if (cont != null)
- kont = ((JSWebContinuation)cont).getWebContinuation();
-
- if (bizData != null) System.err.println("FWD:" + bizData.getClass().getName());
-
- interpreter.forwardTo(uri, bizData, kont, environment);
- }
-
- /**
- * Call the Cocoon sitemap for the given URI, sending the output of the
- * eventually matched pipeline to the specified outputstream.
- *
- * @param uri The URI for which the request should be generated.
- * @param biz Extra data associated with the subrequest.
- * @param out An OutputStream where the output should be written to.
- * @return Whatever the Cocoon processor returns (????).
- * @exception Exception If an error occurs.
- */
- public boolean jsFunction_process(String uri, Object biz, Object out)
- throws Exception
- {
- out = jsobjectToObject(out);
- biz = jsobjectToObject(biz);
- if (biz != null) System.err.println("PRC:"+biz.getClass().getName());
- return interpreter.process(uri, biz, (OutputStream)out, environment);
- }
-
- /**
- Set the Scope object in the session object of the current
- user. This effectively means that at the next invocation from the
- sitemap of a JavaScript function (using the <map:call
- function="...">), will obtain the same scope as the current
- one.
- */
- public void jsFunction_createSession()
- {
- interpreter.setSessionScope(environment, scope);
- }
-
- /**
- Remove the Scope object from the session object of the current
- user.
- */
- public void jsFunction_removeSession()
- {
- interpreter.removeSessionScope(environment);
- }
-
- public void jsFunction_diplayAllContinuations()
- throws ComponentException
- {
- ContinuationsManager continuationsMgr
- = (ContinuationsManager)manager.lookup(ContinuationsManager.ROLE);
-
- try {
- if (continuationsMgr instanceof ContinuationsManagerImpl)
- ((ContinuationsManagerImpl)continuationsMgr).displayAllContinuations();
- }
- finally {
- manager.release((Component)continuationsMgr);
- }
- }
-
- // All right, this breaks the encapsulation, but I couldn't find any
- // better way to obtain the ComponentManager for a
- // JSWebContinuation.
- ComponentManager getComponentManager()
- {
- return manager;
- }
-
-
- public static Map jsobjectToMap(Scriptable jsobject)
- {
- HashMap hash = new HashMap();
- Object[] ids = jsobject.getIds();
- for (int i = 0; i < ids.length; i++) {
- String key = ScriptRuntime.toString(ids[i]);
- Object value = jsobject.get(key, jsobject);
- if (value == Undefined.instance)
- value = null;
- else
- value = jsobjectToObject(value);
- hash.put(key, value);
- }
- return hash;
- }
-
- public static Object jsobjectToObject(Object obj)
- {
- // unwrap Scriptable wrappers of real Java objects
- if (obj instanceof Wrapper) {
- obj = ((Wrapper) obj).unwrap();
- } else if (obj == Undefined.instance) {
- obj = null;
+ protected static String OBJECT_SOURCE_RESOLVER = "source-resolver";
+ protected JavaScriptInterpreter interpreter;
+ protected Scriptable scope;
+ protected NativeArray parameters;
+ protected Environment environment;
+ protected ComponentManager manager;
+
+ public JSCocoon() {}
+
+ public String getClassName()
+ {
+ return "Cocoon";
+ }
+
+ public void setScope(Scriptable scope)
+ {
+ this.scope = scope;
+ }
+
+ public Scriptable getScope()
+ {
+ return scope;
+ }
+
+ public void setParameters(NativeArray parameters)
+ {
+ this.parameters = parameters;
+ }
+
+ public void setInterpreter(JavaScriptInterpreter interpreter)
+ {
+ this.interpreter = interpreter;
+ }
+
+ public void setContext(ComponentManager manager, Environment environment)
+ {
+ this.manager = manager;
+ this.environment = environment;
+ }
+
+ public void invalidateContext()
+ {
+ manager = null;
+ environment = null;
+ }
+
+ public NativeArray jsGet_parameters()
+ {
+ return parameters;
+ }
+
+ public JavaScriptInterpreter jsGet_interpreter()
+ {
+ return interpreter;
+ }
+
+ public Environment jsGet_environment()
+ {
+ return environment;
+ }
+
+ public Request jsGet_request()
+ {
+ if (environment == null) {
+ // context has been invalidated
+ return null;
+ }
+ Map objectModel = environment.getObjectModel();
+ return ObjectModelHelper.getRequest(objectModel);
+ }
+
+ public Response jsGet_response()
+ {
+ if (environment == null) {
+ // context has been invalidated
+ return null;
+ }
+ Map objectModel = environment.getObjectModel();
+ return ObjectModelHelper.getResponse(objectModel);
+ }
+
+ public Session jsGet_session()
+ {
+ if (environment == null) {
+ // context has been invalidated
+ return null;
+ }
+ return jsGet_request().getSession();
+ }
+
+ public Context jsGet_context()
+ {
+ if (environment == null) {
+ // context has been invalidated
+ return null;
+ }
+ Map objectModel = environment.getObjectModel();
+ return ObjectModelHelper.getContext(objectModel);
+ }
+
+ public ComponentManager jsGet_componentManager()
+ {
+ return manager;
+ }
+
+
+
+ /**
+ * Load the file specified as argument. Registers the file with the
+ * interpreter and then forces its loading by calling [EMAIL PROTECTED]
+ * JavaScriptInterpreter#checkForModifiedScripts}.
+ *
+ * @param filename a <code>String</code> value
+ * @return an <code>Object</code> value
+ * @exception Exception if an error occurs
+ */
+ public Object jsFunction_load(String filename) throws JavaScriptException
+ {
+ org.mozilla.javascript.Context cx =
+ org.mozilla.javascript.Context.getCurrentContext();
+ try {
+ Script script = interpreter.compileScript(cx, environment, filename);
+ return script.exec(cx, ScriptableObject.getTopLevelScope(this));
+ } catch (JavaScriptException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new JavaScriptException(e);
+ }
+ }
+
+ public String jsFunction_toString()
+ {
+ return "[object " + toString() + "]";
+ }
+
+ public void jsFunction_forwardTo(String uri, Object bizData, Object cont)
+ throws JavaScriptException
+ {
+ try {
+ bizData = jsobjectToObject(bizData);
+
+ WebContinuation kont = null;
+
+ if (cont != null)
+ kont = ((JSWebContinuation)cont).getWebContinuation();
+
+ interpreter.forwardTo(uri, bizData, kont, environment);
+ } catch (JavaScriptException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new JavaScriptException(e);
+ }
+ }
+
+ /**
+ * Call the Cocoon sitemap for the given URI, sending the output of the
+ * eventually matched pipeline to the specified outputstream.
+ *
+ * @param uri The URI for which the request should be generated.
+ * @param biz Extra data associated with the subrequest.
+ * @param out An OutputStream where the output should be written to.
+ * @return Whatever the Cocoon processor returns (????).
+ */
+ public boolean jsFunction_process(String uri, Object biz, Object out)
+ throws JavaScriptException
+ {
+ try {
+ out = jsobjectToObject(out);
+ biz = jsobjectToObject(biz);
+ return interpreter.process(uri, biz, (OutputStream)out, environment);
+ } catch (JavaScriptException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new JavaScriptException(e);
+ }
+ }
+
+ /**
+ Set the Scope object in the session object of the current
+ user. This effectively means that at the next invocation from the
+ sitemap of a JavaScript function (using the <map:call
+ function="...">), will obtain the same scope as the current
+ one.
+ */
+ public void jsFunction_createSession()
+ {
+ interpreter.setSessionScope(environment, scope);
+ }
+
+ /**
+ Remove the Scope object from the session object of the current
+ user.
+ */
+ public void jsFunction_removeSession()
+ {
+ interpreter.removeSessionScope(environment);
+ }
+
+ public void jsFunction_diplayAllContinuations()
+ throws ComponentException
+ {
+ ContinuationsManager continuationsMgr
+ = (ContinuationsManager)manager.lookup(ContinuationsManager.ROLE);
+
+ try {
+ if (continuationsMgr instanceof ContinuationsManagerImpl)
+
((ContinuationsManagerImpl)continuationsMgr).displayAllContinuations();
+ }
+ finally {
+ manager.release((Component)continuationsMgr);
+ }
+ }
+
+ // All right, this breaks the encapsulation, but I couldn't find any
+ // better way to obtain the ComponentManager for a
+ // JSWebContinuation.
+ ComponentManager getComponentManager()
+ {
+ return manager;
+ }
+
+
+ public static Map jsobjectToMap(Scriptable jsobject)
+ {
+ HashMap hash = new HashMap();
+ Object[] ids = jsobject.getIds();
+ for (int i = 0; i < ids.length; i++) {
+ String key = ScriptRuntime.toString(ids[i]);
+ Object value = jsobject.get(key, jsobject);
+ if (value == Undefined.instance)
+ value = null;
+ else
+ value = jsobjectToObject(value);
+ hash.put(key, value);
+ }
+ return hash;
+ }
+
+ public static Object jsobjectToObject(Object obj)
+ {
+ // unwrap Scriptable wrappers of real Java objects
+ if (obj instanceof Wrapper) {
+ obj = ((Wrapper) obj).unwrap();
+ } else if (obj == Undefined.instance) {
+ obj = null;
+ }
+ return obj;
}
- return obj;
- }
public Scriptable jsFunction_callAction(String type,
String source,
Scriptable parameters)
throws Exception
{
- Redirector redirector = new SitemapRedirector(this.environment);
- SourceResolver resolver = (SourceResolver)this.environment.getObjectModel()
- .get(OBJECT_SOURCE_RESOLVER);
- ComponentManager sitemapManager =
CocoonComponentManager.getSitemapComponentManager();
- ComponentSelector actionSelector
- = (ComponentSelector)sitemapManager.lookup(Action.ROLE + "Selector");
- Action action = (Action)actionSelector.select(type);
- Map result = null;
- try {
- result = action.act(redirector,
- resolver,
- this.environment.getObjectModel(),
- source,
- jsobjectToParameters(parameters));
- }
- finally {
- actionSelector.release(action);
- }
-
- // what should be done with the redirector ??
- // ignore it or call sendPage with it?
- return (result!=null? new ScriptableMap(result) : null);
+ Redirector redirector = new SitemapRedirector(this.environment);
+ SourceResolver resolver = (SourceResolver)this.environment.getObjectModel()
+ .get(OBJECT_SOURCE_RESOLVER);
+ ComponentManager sitemapManager =
CocoonComponentManager.getSitemapComponentManager();
+ ComponentSelector actionSelector
+ = (ComponentSelector)sitemapManager.lookup(Action.ROLE + "Selector");
+ Action action = (Action)actionSelector.select(type);
+ Map result = null;
+ try {
+ result = action.act(redirector,
+ resolver,
+ this.environment.getObjectModel(),
+ source,
+ jsobjectToParameters(parameters));
+ }
+ finally {
+ actionSelector.release(action);
+ }
+
+ // what should be done with the redirector ??
+ // ignore it or call sendPage with it?
+ return (result!=null? new ScriptableMap(result) : null);
}
public static Parameters jsobjectToParameters(Scriptable jsobject)
{
- Parameters params = new Parameters();
- Object[] ids = jsobject.getIds();
- for (int i = 0; i < ids.length; i++) {
- String key = ScriptRuntime.toString(ids[i]);
- Object value = jsobject.get(key, jsobject);
- if (value == Undefined.instance)
- value = null;
- else
- value = ScriptRuntime.toString(value);
- params.setParameter(key, (String) value);
- }
- return params;
+ Parameters params = new Parameters();
+ Object[] ids = jsobject.getIds();
+ for (int i = 0; i < ids.length; i++) {
+ String key = ScriptRuntime.toString(ids[i]);
+ Object value = jsobject.get(key, jsobject);
+ if (value == Undefined.instance)
+ value = null;
+ else
+ value = ScriptRuntime.toString(value);
+ params.setParameter(key, (String) value);
+ }
+ return params;
}
public Object jsFunction_inputModuleGetAttribute(String type, String attribute)
throws Exception
{
- // since no new components can be declared on sitemap we could
- // very well use the 'other' one here. Anyway, since it's there...
- ComponentManager sitemapManager =
CocoonComponentManager.getSitemapComponentManager();
- ComponentSelector inputSelector = (ComponentSelector)sitemapManager
- .lookup(InputModule.ROLE + "Selector");
- InputModule input = (InputModule) inputSelector.select(type);
- Object result = null;
- try {
- result = input.getAttribute(attribute, null,
- this.environment.getObjectModel());
- }
- finally {
- inputSelector.release(input);
- }
- return result;
+ // since no new components can be declared on sitemap we could
+ // very well use the 'other' one here. Anyway, since it's there...
+ ComponentManager sitemapManager =
CocoonComponentManager.getSitemapComponentManager();
+ ComponentSelector inputSelector = (ComponentSelector)sitemapManager
+ .lookup(InputModule.ROLE + "Selector");
+ InputModule input = (InputModule) inputSelector.select(type);
+ Object result = null;
+ try {
+ result = input.getAttribute(attribute, null,
+ this.environment.getObjectModel());
+ }
+ finally {
+ inputSelector.release(input);
+ }
+ return result;
}
public void jsFunction_outputModuleSetAttribute(String type, String attribute,
Object value)
throws Exception
{
- // since no new components can be declared on sitemap we could
- // very well use the 'other' one here. Anyway, since it's there...
- ComponentManager sitemapManager =
CocoonComponentManager.getSitemapComponentManager();
- ComponentSelector outputSelector = (ComponentSelector)sitemapManager
- .lookup(OutputModule.ROLE + "Selector");
- OutputModule output = (OutputModule) outputSelector.select(type);
- try {
- output.setAttribute(null, this.environment.getObjectModel(), attribute,
- jsobjectToObject(value));
- }
- finally {
- outputSelector.release(output);
- }
+ // since no new components can be declared on sitemap we could
+ // very well use the 'other' one here. Anyway, since it's there...
+ ComponentManager sitemapManager =
CocoonComponentManager.getSitemapComponentManager();
+ ComponentSelector outputSelector = (ComponentSelector)sitemapManager
+ .lookup(OutputModule.ROLE + "Selector");
+ OutputModule output = (OutputModule) outputSelector.select(type);
+ try {
+ output.setAttribute(null, this.environment.getObjectModel(), attribute,
+ jsobjectToObject(value));
+ }
+ finally {
+ outputSelector.release(output);
+ }
}
public void jsFunction_outputModuleCommit(String type)
throws Exception
{
- // since no new components can be declared on sitemap we could
- // very well use the 'other' one here. Anyway, since it's there...
- ComponentManager sitemapManager =
CocoonComponentManager.getSitemapComponentManager();
- ComponentSelector outputSelector = (ComponentSelector)sitemapManager
- .lookup(OutputModule.ROLE + "Selector");
- OutputModule output = (OutputModule) outputSelector.select(type);
- try {
- output.commit(null, this.environment.getObjectModel());
- }
- finally {
- outputSelector.release(output);
- }
+ // since no new components can be declared on sitemap we could
+ // very well use the 'other' one here. Anyway, since it's there...
+ ComponentManager sitemapManager =
CocoonComponentManager.getSitemapComponentManager();
+ ComponentSelector outputSelector = (ComponentSelector)sitemapManager
+ .lookup(OutputModule.ROLE + "Selector");
+ OutputModule output = (OutputModule) outputSelector.select(type);
+ try {
+ output.commit(null, this.environment.getObjectModel());
+ }
+ finally {
+ outputSelector.release(output);
+ }
}
public void jsFunction_outputModuleRollback(String type)
throws Exception
{
- // since no new components can be declared on sitemap we could
- // very well use the 'other' one here. Anyway, since it's there...
- ComponentManager sitemapManager =
CocoonComponentManager.getSitemapComponentManager();
- ComponentSelector outputSelector = (ComponentSelector)sitemapManager
- .lookup(OutputModule.ROLE + "Selector");
- OutputModule output = (OutputModule) outputSelector.select(type);
- try {
- output.rollback(null, this.environment.getObjectModel(), null);
- }
- finally {
- outputSelector.release(output);
- }
+ // since no new components can be declared on sitemap we could
+ // very well use the 'other' one here. Anyway, since it's there...
+ ComponentManager sitemapManager =
CocoonComponentManager.getSitemapComponentManager();
+ ComponentSelector outputSelector = (ComponentSelector)sitemapManager
+ .lookup(OutputModule.ROLE + "Selector");
+ OutputModule output = (OutputModule) outputSelector.select(type);
+ try {
+ output.rollback(null, this.environment.getObjectModel(), null);
+ }
+ finally {
+ outputSelector.release(output);
+ }
}
}
1.2 +37 -76
cocoon-2.1/src/java/org/apache/cocoon/components/flow/javascript/JSErrorReporter.java
Index: JSErrorReporter.java
===================================================================
RCS file:
/home/cvs/cocoon-2.1/src/java/org/apache/cocoon/components/flow/javascript/JSErrorReporter.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- JSErrorReporter.java 9 Mar 2003 00:08:50 -0000 1.1
+++ JSErrorReporter.java 15 Mar 2003 09:56:04 -0000 1.2
@@ -2,64 +2,53 @@
import org.mozilla.javascript.ErrorReporter;
import org.mozilla.javascript.EvaluatorException;
-
-import java.util.List;
+import org.mozilla.javascript.tools.ToolErrorReporter;
+import org.apache.avalon.framework.logger.Logger;
/**
* Implements a Rhino JavaScript [EMAIL PROTECTED]
- * org.mozilla.javascript.ErrorReporter}. This is used to explicitly
- * refer to the error in the original source files, rather than the
- * combined file as presented for parsing by [EMAIL PROTECTED] ListInputStream}
- * in [EMAIL PROTECTED] JavaScriptInterpreter#readScripts}.
- *
- * <p>When an error is reported, either during the parsing of the
- * JavaScript files, or at runtime, an instance of this class is
- * invoked. This class maintains a list of [EMAIL PROTECTED] SourceInfo} objects,
- * which contain the original [EMAIL PROTECTED]
- * org.apache.cocoon.environment.Source} object and the line numbers
- * in it. When the error happens, the reporter matches the aggregated
- * line number to the actual source of the error.
- *
- * @author <a href="mailto:[EMAIL PROTECTED]">Ovidiu Predescu</a>
- * @since August 15, 2002
+ * org.mozilla.javascript.ErrorReporter}.
+ * Like ToolErrorReporter but logs to supplied logger instead of stdout
*/
public class JSErrorReporter implements ErrorReporter
{
- /**
- * List of [EMAIL PROTECTED] SourceInfo} objects.
- */
- protected List sourcesInfo;
+ private Logger logger;
- public JSErrorReporter(List sourcesInfo)
+ public JSErrorReporter(Logger logger)
{
- this.sourcesInfo = sourcesInfo;
+ this.logger = logger;
}
public void error(String message,
String sourceName, int line,
String lineSrc, int column)
{
- String errMsg = getErrorMessage("ERROR: ", message, line, lineSrc, column);
- System.out.print(errMsg);
+ String errMsg = getErrorMessage("msg.error", message,
+ sourceName, line, lineSrc, column);
+ System.err.println(errMsg);
+ logger.error(errMsg);
}
public void warning(String message, String sourceName, int line,
- String lineSrc, int column)
+ String lineSrc, int column)
{
- System.out.print(getErrorMessage("WARNING: ", message, line, lineSrc, column));
+ String errMsg = getErrorMessage("msg.warning", message,
+ sourceName, line, lineSrc, column);
+ System.err.println(errMsg);
+ logger.warn(errMsg);
}
public EvaluatorException runtimeError(String message, String sourceName,
int line, String lineSrc,
int column)
{
- String errMsg = getErrorMessage("", message, line, lineSrc, column);
- return new EvaluatorException(errMsg);
+ return new EvaluatorException(getErrorMessage("msg.error", message,
+ sourceName, line,
+ lineSrc, column));
}
/**
- * Identifies the real location of the error in the file given the
- * information stored in <code>sourcesInfo</code>.
+ * Formats error message
*
* @param type a <code>String</code> value, indicating the error
* type (error or warning)
@@ -75,50 +64,22 @@
* message, with the source file and line number adjusted to the
* real values
*/
- protected String getErrorMessage(String type,
- String message,
- int line,
- String lineSource, int column)
- {
- int i = 0, size = sourcesInfo.size();
- int accLines = 0;
-
- // Find the file which contains the line number indicated by the error
- SourceInfo source;
- do {
- source = (SourceInfo)sourcesInfo.get(i);
- accLines += source.getLineNumbers();
- i++;
- } while (accLines < line && i < size);
-
- String errorMsg;
-
- if (i == size && line > accLines) {
- errorMsg = "ERROR: Line number " + line + " out of bounds!";
- return errorMsg;
- }
-
- String systemId = source.getSystemId();
- int realLineNo = line - (accLines - source.getLineNumbers());
-
- errorMsg = systemId + ":" + realLineNo;
-
- // If line source information is provided, make use of that to
- // print a more descriptive error message.
- if (lineSource != null) {
- errorMsg += "\n\n" + lineSource + "\n";
-
- StringBuffer blanks = new StringBuffer(column);
- for (i = 1; i < column; i++)
- blanks.append(" ");
-
- errorMsg += blanks + "^" + "\n\n";
+ String getErrorMessage(String type,
+ String message,
+ String sourceName, int line,
+ String lineSource, int column)
+ {
+ if (line > 0) {
+ if (sourceName != null) {
+ Object[] errArgs = { sourceName, new Integer(line), message };
+ return ToolErrorReporter.getMessage("msg.format3", errArgs);
+ } else {
+ Object[] errArgs = { new Integer(line), message };
+ return ToolErrorReporter.getMessage("msg.format2", errArgs);
+ }
+ } else {
+ Object[] errArgs = { message };
+ return ToolErrorReporter.getMessage("msg.format1", errArgs);
+ }
}
- else
- errorMsg += ": ";
-
- errorMsg += type + message + "\n\n";
-
- return errorMsg;
- }
}
1.2 +521 -537
cocoon-2.1/src/java/org/apache/cocoon/components/flow/javascript/JavaScriptInterpreter.java
Index: JavaScriptInterpreter.java
===================================================================
RCS file:
/home/cvs/cocoon-2.1/src/java/org/apache/cocoon/components/flow/javascript/JavaScriptInterpreter.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- JavaScriptInterpreter.java 9 Mar 2003 00:08:50 -0000 1.1
+++ JavaScriptInterpreter.java 15 Mar 2003 09:56:04 -0000 1.2
@@ -49,6 +49,7 @@
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
+import java.util.Collections;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
@@ -66,11 +67,13 @@
import org.apache.cocoon.environment.ObjectModelHelper;
import org.apache.cocoon.environment.Request;
import org.apache.cocoon.environment.Session;
+import org.apache.cocoon.ResourceNotFoundException;
import org.apache.commons.jxpath.JXPathIntrospector;
import org.apache.commons.jxpath.ri.JXPathContextReferenceImpl;
import org.apache.excalibur.source.Source;
import org.mozilla.javascript.*;
import org.mozilla.javascript.tools.debugger.ScopeProvider;
+import org.mozilla.javascript.tools.ToolErrorReporter;
/**
* Interface with the JavaScript interpreter.
@@ -80,546 +83,527 @@
* @since March 25, 2002
*/
public class JavaScriptInterpreter extends AbstractInterpreter
- implements Configurable, Initializable
+ implements Configurable, Initializable
{
- public static final String USER_GLOBAL_SCOPE = "JavaScript GLOBAL SCOPE";
+ public static final String USER_GLOBAL_SCOPE = "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;
-
- /**
- * List of <code>Source</code> objects that represent files to be
- * read in by the JavaScript interpreter.
- */
- protected List scripts = new ArrayList();
-
- /**
- * When was the last time we checked for script modifications. Used
- * only if [EMAIL PROTECTED] #reloadScripts} is true.
- */
- protected long lastTimeCheck = 0;
- JSGlobal scope;
- List compiledScripts = new ArrayList();
- JSErrorReporter errorReporter;
- boolean enableDebugger = false;
- org.mozilla.javascript.tools.debugger.Main debugger;
-
- public void configure(Configuration config)
- throws ConfigurationException
- {
- super.configure(config);
-
- String loadOnStartup
- = config.getChild("load-on-startup", true).getValue(null);
- if (loadOnStartup != null) {
- register(loadOnStartup);
- }
-
- String debugger
- = config.getChild("debugger").getValue(null);
- if ("enabled".equalsIgnoreCase(debugger)) {
- enableDebugger = true;
- }
- }
-
- public void initialize()
- throws Exception
- {
- if (enableDebugger) {
-
- if (getLogger().isDebugEnabled()) {
- getLogger().debug("Flow debugger enabled, creating");
- }
-
- final org.mozilla.javascript.tools.debugger.Main db
- = new org.mozilla.javascript.tools.debugger.Main("Cocoon Flow Debugger");
- db.pack();
- db.setSize(600,460);
- db.setExitAction(
- new Runnable() { public void run() { db.setVisible(false); } }
- );
- db.setVisible(true);
- debugger = db;
- Context.addContextListener(debugger);
- debugger.doBreak();
- }
-
- Context context = Context.enter();
- context.setOptimizationLevel(OPTIMIZATION_LEVEL);
- context.setGeneratingDebug(true);
- // add support for Rhino objects to JXPath
- JXPathIntrospector.registerDynamicClass(org.mozilla.javascript.Scriptable.class,
- ScriptablePropertyHandler.class);
- JXPathContextReferenceImpl.addNodePointerFactory(new
ScriptablePointerFactory());
-
- try {
- scope = new JSGlobal(context);
-
- // Register some handy classes with JavaScript, so we can make
- // use of them from the flow layer.
-
- // Access to the Cocoon log
- ScriptableObject.defineClass(scope, JSLog.class);
-
- // Access to Cocoon internal objects
- ScriptableObject.defineClass(scope, JSCocoon.class);
-
- // Wrapper for WebContinuation
- ScriptableObject.defineClass(scope, JSWebContinuation.class);
-
- // Define some functions on the top level scope
- String[] names = { "print" };
- try {
- ((ScriptableObject)scope)
- .defineFunctionProperties(names, JSGlobal.class,
- ScriptableObject.DONTENUM);
- }
- catch (PropertyException e) {
- throw new Error(e.getMessage());
- }
-
- // Define some global variables in JavaScript
- Object args[] = {};
- Scriptable log = context.newObject(scope, "Log", args);
- ((JSLog)log).enableLogging(getLogger());
- scope.put("log", scope, log);
- }
- catch (Exception e) {
- Context.exit();
- e.printStackTrace();
- throw e;
- }
- }
-
- /**
- * Returns the JavaScript scope, a Scriptable object, from the user
- * session instance. Each URI prefix, as returned by the [EMAIL PROTECTED]
- * org.apache.cocoon.environment.Environment#getURIPrefix} method,
- * can have a scope associated with it.
- *
- * @param environment an <code>Environment</code> value
- * @param createSession a <code>boolean</code> value
- * @return a <code>Scriptable</code> value
- */
- public Scriptable getSessionScope(Environment environment)
- {
- Map objectModel = environment.getObjectModel();
- Request request = ObjectModelHelper.getRequest(objectModel);
- Session session = request.getSession(false);
-
- if (session == null) {
- return null;
- }
-
- Scriptable scope;
- HashMap userScopes = (HashMap)session.getAttribute(USER_GLOBAL_SCOPE);
-
- if (userScopes == null) {
- return null;
- }
-
- scope = (Scriptable)userScopes.get(environment.getURIPrefix());
-
- return scope;
- }
-
- /**
- * Associates a JavaScript scope, a Scriptable object, with the URI
- * prefix of the current sitemap, as returned by the [EMAIL PROTECTED]
- * org.apache.cocoon.environment.Environment#getURIPrefix} method.
- *
- * @param environment an <code>Environment</code> value
- * @param scope a <code>Scriptable</code> value
- */
- public void setSessionScope(Environment environment, Scriptable scope)
- {
- Map objectModel = environment.getObjectModel();
- Request request = ObjectModelHelper.getRequest(objectModel);
- Session session = request.getSession(true);
-
- HashMap userScopes = (HashMap)session.getAttribute(USER_GLOBAL_SCOPE);
- if (userScopes == null) {
- userScopes = new HashMap();
- session.setAttribute(USER_GLOBAL_SCOPE, userScopes);
- }
-
- userScopes.put(environment.getURIPrefix(), scope);
- }
-
- public void removeSessionScope(Environment environment)
- {
- Map objectModel = environment.getObjectModel();
- Request request = ObjectModelHelper.getRequest(objectModel);
- Session session = request.getSession(true);
-
- HashMap userScopes = (HashMap)session.getAttribute(USER_GLOBAL_SCOPE);
- if (userScopes == null)
- return;
-
- userScopes.remove(environment.getURIPrefix());
- }
-
- /**
- * Returns a new Scriptable object to be used as the global scope
- * when running the JavaScript scripts in the context of a request.
- *
- * <p>If you want to maintain the state of global variables across
- * multiple invocations of <code><map:call
- * function="..."></code>, you need to invoke from the JavaScript
- * script <code>cocoon.createSession()</code>. This will place the
- * newly create Scriptable object in the user's session, where it
- * will be retrieved from at the next invocation of
- * callFunction().</p>
- *
- * @param environment an <code>Environment</code> value
- * @param createNew a <code>boolean</code> value
- * @return a <code>Scriptable</code> value
- * @exception Exception if an error occurs
- */
- protected Scriptable enterContext(Environment environment)
- throws Exception
- {
- Context context = Context.enter();
- context.setOptimizationLevel(OPTIMIZATION_LEVEL);
- context.setGeneratingDebug(true);
- context.setCompileFunctionsWithDynamicScope(true);
- context.setErrorReporter(errorReporter);
- Scriptable thrScope = null;
-
- // 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.
- //
- // When a user script "creates" a session using
- // cocoon.createSession() in JavaScript, the thrScope is placed in
- // the session object, where it's later retrieved from here. This
- // behaviour allows multiple JavaScript functions to share the
- // same global scope.
- thrScope = getSessionScope(environment);
-
- // The Cocoon object exported to JavaScript needs to be setup here
- JSCocoon cocoon;
-
- if (thrScope == null) {
- thrScope = context.newObject(scope);
-
- 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
- // JSCocoon for more details.
- Object args[] = {};
- cocoon = (JSCocoon)context.newObject(scope, "Cocoon", args);
- ((JSCocoon)cocoon).setInterpreter(this);
- ((JSCocoon)cocoon).setScope(thrScope);
- thrScope.put("cocoon", thrScope, cocoon);
-
- Iterator iter = compiledScripts.iterator();
- while (iter.hasNext()) {
- Script compiledScript = (Script)iter.next();
- compiledScript.exec(context, thrScope);
- }
- } else {
- cocoon = (JSCocoon)thrScope.get("cocoon", thrScope);
- }
-
- // We need to setup the JSCocoon object according to the current
- // request. Everything else remains the same.
- cocoon.setContext(manager, environment);
-
- return thrScope;
- }
-
- /**
- * Remove the Cocoon object from the JavaScript thread scope so it
- * can be garbage collected, together with all the objects it
- * contains.
- */
- protected void exitContext(Scriptable thrScope)
- {
- // thrScope may be null if an exception occurred compiling a script
- if (thrScope != null) {
- JSCocoon cocoon = (JSCocoon)thrScope.get("cocoon", thrScope);
- cocoon.invalidateContext();
- }
- Context.exit();
- }
-
- public void readScripts(Environment environment, List sources)
- throws Exception
- {
- Scriptable thrScope = null;
-
- if (getLogger().isDebugEnabled()) {
- getLogger().debug("Reading scripts");
- }
-
- try {
- thrScope = enterContext(environment);
- Iterator iter = sources.iterator();
- while (iter.hasNext()) {
- Source src = (Source)iter.next();
- InputStream is = src.getInputStream();
- Reader reader = new BufferedReader(new InputStreamReader(is));
- Context context = Context.getCurrentContext();
- Script compiledScript = context.compileReader(thrScope, reader,
- src.getURI(),
- 1, null);
- compiledScripts.add(compiledScript);
- }
- }
- catch (JavaScriptException ex) {
- Object value = ex.getValue();
- while (value instanceof Wrapper) {
- value = ((Wrapper)value).unwrap();
- }
- if (value instanceof Exception) {
- Exception e = (Exception)value;
- e.printStackTrace();
- throw e;
- } else if (value instanceof Error) {
- throw (Error)value;
- }
- throw ex;
- } catch (Exception ex) {
- ex.printStackTrace();
- throw ex;
- }
- finally {
- exitContext(thrScope);
- }
- }
-
- /**
- * Reloads any modified script files.
- *
- * <p>It checks to see if any of the files already read in (those
- * present in the <code>scripts</code> hash map) have been
- * modified.
- *
- * <p>It also checks to see if any script files have been registered
- * with the interpreter since the last call to
- * <code>checkForModifiedScripts</code>. These files are stored in
- * the temporary array <code>needResolve</code>. If any such files
- * are found, they are read in.
- *
- * @param environment an <code>Environment</code> value
- */
- public void checkForModifiedScripts(Environment environment)
- throws Exception
- {
- boolean needsRefresh = false;
-
- if (reloadScripts
- && System.currentTimeMillis() >= lastTimeCheck + checkTime) {
- // FIXME: should we worry about synchronization?
- for (int i = 0, size = scripts.size(); i < size; i++) {
- Source src = (Source)scripts.get(i);
- src.refresh();
- getLogger().debug("Checking " + src.getURI()
- + ", source " + src
- + ", last modified " + src.getLastModified()
- + ", last time check " + lastTimeCheck);
- if (src.getLastModified() > lastTimeCheck) {
- needsRefresh = true;
- break;
- }
- }
- }
-
- // FIXME: remove the need for synchronization
- synchronized (this) {
- int size = needResolve.size();
-
- // If there's no need to re-read any file, and no files
- // have been requested to be read since the last time,
- // don't do anything.
- if (!needsRefresh && size == 0) {
+ // This is the only optimization level that supports continuations
+ // in the Christoper Oliver's Rhino JavaScript implementation
+ static int OPTIMIZATION_LEVEL = -2;
+
+ /**
+ * List of <code>Source</code> objects that represent files to be
+ * read in by the JavaScript interpreter.
+ */
+ protected List scripts = new ArrayList();
+
+ /**
+ * When was the last time we checked for script modifications. Used
+ * only if [EMAIL PROTECTED] #reloadScripts} is true.
+ */
+ protected long lastTimeCheck = 0;
+ JSGlobal scope;
+ List compiledScripts = Collections.synchronizedList(new ArrayList());
+ JSErrorReporter errorReporter;
+ boolean enableDebugger = false;
+ org.mozilla.javascript.tools.debugger.Main debugger;
+
+ public void configure(Configuration config)
+ throws ConfigurationException
+ {
+ super.configure(config);
+
+ String loadOnStartup
+ = config.getChild("load-on-startup", true).getValue(null);
+ if (loadOnStartup != null) {
+ register(loadOnStartup);
+ }
+
+ String debugger
+ = config.getChild("debugger").getValue(null);
+ if ("enabled".equalsIgnoreCase(debugger)) {
+ enableDebugger = true;
+ }
+ }
+
+ public void initialize()
+ throws Exception
+ {
+ if (enableDebugger) {
+
+ if (getLogger().isDebugEnabled()) {
+ getLogger().debug("Flow debugger enabled, creating");
+ }
+
+ final org.mozilla.javascript.tools.debugger.Main db
+ = new org.mozilla.javascript.tools.debugger.Main("Cocoon Flow
Debugger");
+ db.pack();
+ db.setSize(600,460);
+ db.setExitAction(new Runnable() {
+ public void run() {
+ db.setVisible(false);
+ }
+ });
+ db.setVisible(true);
+ debugger = db;
+ Context.addContextListener(debugger);
+ debugger.doBreak();
+ }
+
+ Context context = Context.enter();
+ context.setOptimizationLevel(OPTIMIZATION_LEVEL);
+ context.setGeneratingDebug(true);
+ // add support for Rhino objects to JXPath
+
JXPathIntrospector.registerDynamicClass(org.mozilla.javascript.Scriptable.class,
+ ScriptablePropertyHandler.class);
+ JXPathContextReferenceImpl.addNodePointerFactory(new
ScriptablePointerFactory());
+
+ try {
+ scope = new JSGlobal(context);
+
+ // Register some handy classes with JavaScript, so we can make
+ // use of them from the flow layer.
+
+ // Access to the Cocoon log
+ ScriptableObject.defineClass(scope, JSLog.class);
+
+ // Access to Cocoon internal objects
+ ScriptableObject.defineClass(scope, JSCocoon.class);
+
+ // Wrapper for WebContinuation
+ ScriptableObject.defineClass(scope, JSWebContinuation.class);
+
+ // Define some functions on the top level scope
+ String[] names = { "print" };
+ try {
+ ((ScriptableObject)scope)
+ .defineFunctionProperties(names, JSGlobal.class,
+ ScriptableObject.DONTENUM);
+ }
+ catch (PropertyException e) {
+ throw new Error(e.getMessage());
+ }
+
+ // Define some global variables in JavaScript
+ Object args[] = {};
+ Scriptable log = context.newObject(scope, "Log", args);
+ ((JSLog)log).enableLogging(getLogger());
+ scope.put("log", scope, log);
+ errorReporter = new JSErrorReporter(getLogger());
+ }
+ catch (Exception e) {
+ Context.exit();
+ e.printStackTrace();
+ throw e;
+ }
+ }
+
+ /**
+ * Returns the JavaScript scope, a Scriptable object, from the user
+ * session instance. Each URI prefix, as returned by the [EMAIL PROTECTED]
+ * org.apache.cocoon.environment.Environment#getURIPrefix} method,
+ * can have a scope associated with it.
+ *
+ * @param environment an <code>Environment</code> value
+ * @param createSession a <code>boolean</code> value
+ * @return a <code>Scriptable</code> value
+ */
+ public Scriptable getSessionScope(Environment environment)
+ {
+ Map objectModel = environment.getObjectModel();
+ Request request = ObjectModelHelper.getRequest(objectModel);
+ Session session = request.getSession(false);
+
+ if (session == null) {
+ return null;
+ }
+
+ Scriptable scope;
+ HashMap userScopes = (HashMap)session.getAttribute(USER_GLOBAL_SCOPE);
+
+ if (userScopes == null) {
+ return null;
+ }
+
+ scope = (Scriptable)userScopes.get(environment.getURIPrefix());
+
+ return scope;
+ }
+
+ /**
+ * Associates a JavaScript scope, a Scriptable object, with the URI
+ * prefix of the current sitemap, as returned by the [EMAIL PROTECTED]
+ * org.apache.cocoon.environment.Environment#getURIPrefix} method.
+ *
+ * @param environment an <code>Environment</code> value
+ * @param scope a <code>Scriptable</code> value
+ */
+ public void setSessionScope(Environment environment, Scriptable scope)
+ {
+ Map objectModel = environment.getObjectModel();
+ Request request = ObjectModelHelper.getRequest(objectModel);
+ Session session = request.getSession(true);
+
+ HashMap userScopes = (HashMap)session.getAttribute(USER_GLOBAL_SCOPE);
+ if (userScopes == null) {
+ userScopes = new HashMap();
+ session.setAttribute(USER_GLOBAL_SCOPE, userScopes);
+ }
+
+ userScopes.put(environment.getURIPrefix(), scope);
+ }
+
+ public void removeSessionScope(Environment environment)
+ {
+ Map objectModel = environment.getObjectModel();
+ Request request = ObjectModelHelper.getRequest(objectModel);
+ Session session = request.getSession(true);
+
+ HashMap userScopes = (HashMap)session.getAttribute(USER_GLOBAL_SCOPE);
+ if (userScopes == null)
+ return;
+
+ userScopes.remove(environment.getURIPrefix());
+ }
+
+ /**
+ * Returns a new Scriptable object to be used as the global scope
+ * when running the JavaScript scripts in the context of a request.
+ *
+ * <p>If you want to maintain the state of global variables across
+ * multiple invocations of <code><map:call
+ * function="..."></code>, you need to invoke from the JavaScript
+ * script <code>cocoon.createSession()</code>. This will place the
+ * newly create Scriptable object in the user's session, where it
+ * will be retrieved from at the next invocation of
+ * callFunction().</p>
+ *
+ * @param environment an <code>Environment</code> value
+ * @param createNew a <code>boolean</code> value
+ * @param sourcesToBeCompiled list of Source's to compile
+ * @return a <code>Scriptable</code> value
+ * @exception Exception if an error occurs
+ */
+ protected Scriptable enterContext(Environment environment,
+ boolean needsExec,
+ List sourcesToBeCompiled)
+ throws Exception
+ {
+ Context context = Context.enter();
+ context.setOptimizationLevel(OPTIMIZATION_LEVEL);
+ context.setGeneratingDebug(true);
+ context.setCompileFunctionsWithDynamicScope(true);
+ context.setErrorReporter(errorReporter);
+ Scriptable thrScope = null;
+
+ compileScripts(context, environment, sourcesToBeCompiled);
+
+ // 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.
+ //
+ // When a user script "creates" a session using
+ // cocoon.createSession() in JavaScript, the thrScope is placed in
+ // the session object, where it's later retrieved from here. This
+ // behaviour allows multiple JavaScript functions to share the
+ // same global scope.
+ thrScope = getSessionScope(environment);
+
+ // The Cocoon object exported to JavaScript needs to be setup here
+ JSCocoon cocoon;
+ if (thrScope == null) {
+ thrScope = context.newObject(scope);
+
+ 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
+ // JSCocoon for more details.
+ Object args[] = {};
+ cocoon = (JSCocoon)context.newObject(scope, "Cocoon", args);
+ ((JSCocoon)cocoon).setInterpreter(this);
+ ((JSCocoon)cocoon).setScope(thrScope);
+ thrScope.put("cocoon", thrScope, cocoon);
+ needsExec = true;
+ } else {
+ cocoon = (JSCocoon)thrScope.get("cocoon", thrScope);
+ }
+ // We need to setup the JSCocoon object according to the current
+ // request. Everything else remains the same.
+ cocoon.setContext(manager, environment);
+
+ if (needsExec) {
+ for (int i = 0; i < compiledScripts.size(); i++) {
+ Script compiledScript = (Script)compiledScripts.get(i);
+ compiledScript.exec(context, thrScope);
+ }
+ }
+
+
+ return thrScope;
+ }
+
+ /**
+ * Remove the Cocoon object from the JavaScript thread scope so it
+ * can be garbage collected, together with all the objects it
+ * contains.
+ */
+ protected void exitContext(Scriptable thrScope)
+ {
+ // thrScope may be null if an exception occurred compiling a script
+ if (thrScope != null) {
+ JSCocoon cocoon = (JSCocoon)thrScope.get("cocoon", thrScope);
+ cocoon.invalidateContext();
+ }
+ Context.exit();
+ }
+
+ private void compileScripts(Context cx, Environment environment, List sources)
+ throws Exception
+ {
+ if (getLogger().isDebugEnabled()) {
+ getLogger().debug("Reading scripts");
+ }
+ Iterator iter = sources.iterator();
+ while (iter.hasNext()) {
+ Source src = (Source)iter.next();
+ compileScript(cx, src);
+ }
+ }
+
+ /**
+ * Compile filename as JavaScript code
+ * @param cx Rhino context
+ * @param environment source resolver
+ * @param fileName resource uri
+ * @return compiled script
+ */
+
+ public Script compileScript(Context cx,
+ Environment environment,
+ String fileName) throws Exception {
+ Source src = environment.resolveURI(fileName);
+ if (src == null) {
+ throw new ResourceNotFoundException(fileName + ": not found");
+ }
+ return compileScript(cx, src);
+ }
+
+ private Script compileScript(Context cx, Source src) throws Exception {
+ InputStream is = src.getInputStream();
+ Reader reader = new BufferedReader(new InputStreamReader(is));
+ Script compiledScript = cx.compileReader(scope, reader,
+ src.getURI(),
+ 1, null);
+ compiledScripts.add(compiledScript);
+ return compiledScript;
+ }
+
+ /**
+ * Reloads any modified script files.
+ *
+ * <p>It checks to see if any of the files already read in (those
+ * present in the <code>scripts</code> hash map) have been
+ * modified.
+ *
+ * <p>It also checks to see if any script files have been registered
+ * with the interpreter since the last call to
+ * <code>checkForModifiedScripts</code>. These files are stored in
+ * the temporary array <code>needResolve</code>. If any such files
+ * are found, they are read in.
+ *
+ * @param environment an <code>Environment</code> value
+ * @param toBeCompiled output parameter: the list of <code>Source</code>
objects to be compiled
+ * @return true if any existing Source script has changed
+ */
+ public boolean checkForModifiedScripts(Environment environment,
+ List toBeCompiled)
+ throws Exception
+ {
+ boolean needsRefresh = false;
+ if (reloadScripts
+ && System.currentTimeMillis() >= lastTimeCheck + checkTime) {
+ // FIXME: should we worry about synchronization?
+ for (int i = 0, size = scripts.size(); i < size; i++) {
+ Source src = (Source)scripts.get(i);
+ src.refresh();
+ getLogger().debug("Checking " + src.getURI()
+ + ", source " + src
+ + ", last modified " + src.getLastModified()
+ + ", last time check " + lastTimeCheck);
+ if (src.getLastModified() > lastTimeCheck) {
+ needsRefresh = true;
+ break;
+ }
+ }
+ }
+
+ // FIXME: remove the need for synchronization
+ synchronized (this) {
+ int size = needResolve.size();
+
+ // If there's no need to re-read any file, and no files
+ // have been requested to be read since the last time,
+ // don't do anything.
+ if (!needsRefresh && size == 0) {
+ lastTimeCheck = System.currentTimeMillis();
+ return false;
+ }
+
+ for (int i = 0; i < size; i++) {
+ String source = (String)needResolve.get(i);
+ Source src = environment.resolveURI(source);
+ scripts.add(src);
+ toBeCompiled.add(src);
+ }
+ needResolve.clear();
+ }
+
+ // Update the time of the last check. If an exception occurs, this
+ // is not executed, so the next request will force a reparse of
+ // the script files because of an old time stamp.
lastTimeCheck = System.currentTimeMillis();
- return;
- }
+ return needsRefresh;
+ }
+
+ /**
+ * Calls a JavaScript function, passing <code>params</code> as its
+ * arguments. In addition to this, it makes available the parameters
+ * through the <code>cocoon.parameters</code> JavaScript array
+ * (indexed by the parameter names).
+ *
+ * @param funName a <code>String</code> value
+ * @param params a <code>List</code> value
+ * @param environment an <code>Environment</code> value
+ * @exception Exception if an error occurs
+ */
+ public void callFunction(String funName, List params,
+ Environment environment)
+ throws Exception
+ {
+ Scriptable thrScope = null;
+ List toBeCompiled = new ArrayList();
+ boolean needsRefresh = checkForModifiedScripts(environment, toBeCompiled);
+ try {
+ thrScope = enterContext(environment, needsRefresh, toBeCompiled);
+
+ Context context = Context.getCurrentContext();
+ JSCocoon cocoon = (JSCocoon)thrScope.get("cocoon", thrScope);
+
+ if (enableDebugger) {
+ final Scriptable s = thrScope;
+ debugger.setScopeProvider(
+ new ScopeProvider()
+ { public Scriptable getScope()
{return s;} }
+ );
+ if (!debugger.isVisible())
+ debugger.setVisible(true);
+ }
+
+ Object callFunction = thrScope.get("callFunction", thrScope);
+ if (callFunction == Scriptable.NOT_FOUND)
+ throw new RuntimeException("Cannot find 'callFunction' "
+ + "(system.js not loaded?)");
+
+ Object fun = thrScope.get(funName, thrScope);
+ if (fun == Scriptable.NOT_FOUND)
+ throw new RuntimeException("'" + funName + "' is undefined!");
+ if (!(fun instanceof Function))
+ throw new RuntimeException("'" + funName + "' is not a function!");
+
+ int size = (params != null ? params.size() : 0);
+ Object[] funArgs = new Object[size];
+ NativeArray parameters = new NativeArray(size);
+ if (size != 0) {
+ for (int i = 0; i < size; i++) {
+ Interpreter.Argument arg = (Interpreter.Argument)params.get(i);
+ funArgs[i] = arg.value;
+ parameters.put(arg.name, parameters, arg.value);
+ }
+ }
+ cocoon.setParameters(parameters);
+ NativeArray funArgsArray = new NativeArray(funArgs);
+ Object callFunArgs[] = { fun, funArgsArray };
+ ((Function) callFunction).call(context, thrScope, thrScope,
callFunArgs);
+ }
+ catch (JavaScriptException ex) {
+
Context.reportError(ToolErrorReporter.getMessage("msg.uncaughtJSException",
+ ex.getMessage()));
+ throw ex;
+ }
+ finally {
+ exitContext(thrScope);
+ }
+ }
+
+ public void handleContinuation(String id, List params,
+ Environment environment)
+ throws Exception
+ {
+ WebContinuation wk = continuationsMgr.lookupWebContinuation(id);
+
+ if (wk == null) {
+ List p = new ArrayList();
+ p.add(new Interpreter.Argument("kontId", id));
+ callFunction("handleInvalidContinuation", p, environment);
+ return;
+ }
- for (int i = 0; i < size; i++) {
- String source = (String)needResolve.get(i);
- Source src = environment.resolveURI(source);
- scripts.add(src);
- }
- needResolve.clear();
- //ListInputStream is = new ListInputStream(scripts);
- //errorReporter = new JSErrorReporter(is.getSourceInfo());
- readScripts(environment, scripts);
- }
-
- // Update the time of the last check. If an exception occurs, this
- // is not executed, so the next request will force a reparse of
- // the script files because of an old time stamp.
- lastTimeCheck = System.currentTimeMillis();
- }
-
- /**
- * Calls a JavaScript function, passing <code>params</code> as its
- * arguments. In addition to this, it makes available the parameters
- * through the <code>cocoon.parameters</code> JavaScript array
- * (indexed by the parameter names).
- *
- * @param funName a <code>String</code> value
- * @param params a <code>List</code> value
- * @param environment an <code>Environment</code> value
- * @exception Exception if an error occurs
- */
- public void callFunction(String funName, List params,
- Environment environment)
- throws Exception
- {
- Scriptable thrScope = null;
-
- checkForModifiedScripts(environment);
-
- try {
- thrScope = enterContext(environment);
- Context context = Context.getCurrentContext();
- JSCocoon cocoon = (JSCocoon)thrScope.get("cocoon", thrScope);
-
- if (enableDebugger) {
- final Scriptable s = thrScope;
- debugger.setScopeProvider(
- new ScopeProvider()
- { public Scriptable getScope() {return s;} }
- );
- if (!debugger.isVisible())
- debugger.setVisible(true);
- }
-
- Object callFunction = thrScope.get("callFunction", thrScope);
- if (callFunction == Scriptable.NOT_FOUND)
- throw new RuntimeException("Cannot find 'callFunction' "
- + "(system.js not loaded?)");
-
- Object fun = thrScope.get(funName, thrScope);
- if (fun == Scriptable.NOT_FOUND)
- throw new RuntimeException("'" + funName + "' is undefined!");
- if (!(fun instanceof Function))
- throw new RuntimeException("'" + funName + "' is not a function!");
-
- int size = (params != null ? params.size() : 0);
- Object[] funArgs = new Object[size];
- NativeArray parameters = new NativeArray(size);
- if (size != 0) {
- for (int i = 0; i < size; i++) {
- Interpreter.Argument arg = (Interpreter.Argument)params.get(i);
- funArgs[i] = arg.value;
- parameters.put(arg.name, parameters, arg.value);
- }
- }
- cocoon.setParameters(parameters);
- NativeArray funArgsArray = new NativeArray(funArgs);
- Object callFunArgs[] = { fun, funArgsArray };
- ((Function) callFunction).call(context, thrScope, thrScope, callFunArgs);
- }
- catch (JavaScriptException ex) {
- Object value = ex.getValue();
- while (value instanceof Wrapper) {
- value = ((Wrapper)value).unwrap();
- }
- if (value instanceof Exception) {
- Exception e = (Exception)value;
- e.printStackTrace();
- throw e;
- } else if (value instanceof Error) {
- throw (Error)value;
- }
- throw ex;
- }
- catch (Exception ex) {
- ex.printStackTrace();
- throw ex;
- }
- finally {
- exitContext(thrScope);
- }
- }
-
- public void handleContinuation(String id, List params,
- Environment environment)
- throws Exception
- {
- WebContinuation wk = continuationsMgr.lookupWebContinuation(id);
-
- if (wk == null) {
- List p = new ArrayList();
- p.add(new Interpreter.Argument("kontId", id));
- callFunction("handleInvalidContinuation", p, environment);
- return;
- }
-
- Context context = Context.enter();
- context.setOptimizationLevel(OPTIMIZATION_LEVEL);
- context.setGeneratingDebug(true);
- context.setCompileFunctionsWithDynamicScope(true);
-
- // Obtain the JS continuation object from it, and setup the
- // JSCocoon object associated in the dynamic scope of the saved
- // continuation with the environment and context objects.
- JSWebContinuation jswk = (JSWebContinuation)wk.getUserObject();
- JSCocoon cocoon = jswk.getJSCocoon();
- cocoon.setContext(manager, environment);
- final Scriptable kScope = cocoon.getScope();
-
- if (enableDebugger) {
- debugger.setScopeProvider(
- new ScopeProvider()
- { public Scriptable getScope() {return kScope;} }
- );
- if (!debugger.isVisible())
- debugger.setVisible(true);
- }
-
- // We can now resume the processing from the state saved by the
- // continuation object. Setup the JavaScript Context object.
- Object handleContFunction = kScope.get("handleContinuation", kScope);
- if (handleContFunction == Scriptable.NOT_FOUND)
- throw new RuntimeException("Cannot find 'handleContinuation' "
- + "(system.js not loaded?)");
-
- Object args[] = { jswk };
-
- int size = (params != null ? params.size() : 0);
- NativeArray parameters = new NativeArray(size);
-
- if (size != 0) {
- for (int i = 0; i < size; i++) {
- Interpreter.Argument arg = (Interpreter.Argument)params.get(i);
- parameters.put(arg.name, parameters, arg.value);
- }
- }
-
- cocoon.setParameters(parameters);
-
- try {
- ((Function)handleContFunction).call(context, kScope, kScope, args);
- } catch (JavaScriptException ex) {
- Object value = ex.getValue();
- while (value instanceof Wrapper) {
- value = ((Wrapper)value).unwrap();
- }
- if (value instanceof Exception) {
- Exception e = (Exception)value;
- e.printStackTrace();
- throw e;
- } else if (value instanceof Error) {
- throw (Error)value;
- }
- throw ex;
- } catch (Exception ex) {
- ex.printStackTrace();
- throw ex;
- } finally {
- Context.exit();
+ Context context = Context.enter();
+ context.setOptimizationLevel(OPTIMIZATION_LEVEL);
+ context.setGeneratingDebug(true);
+ context.setCompileFunctionsWithDynamicScope(true);
+
+ // Obtain the JS continuation object from it, and setup the
+ // JSCocoon object associated in the dynamic scope of the saved
+ // continuation with the environment and context objects.
+ JSWebContinuation jswk = (JSWebContinuation)wk.getUserObject();
+ JSCocoon cocoon = jswk.getJSCocoon();
+ cocoon.setContext(manager, environment);
+ final Scriptable kScope = cocoon.getScope();
+
+ if (enableDebugger) {
+ debugger.setScopeProvider(
+ new ScopeProvider()
+ { public Scriptable getScope() {return
kScope;} }
+ );
+ if (!debugger.isVisible())
+ debugger.setVisible(true);
+ }
+
+ // We can now resume the processing from the state saved by the
+ // continuation object. Setup the JavaScript Context object.
+ Object handleContFunction = kScope.get("handleContinuation", kScope);
+ if (handleContFunction == Scriptable.NOT_FOUND)
+ throw new RuntimeException("Cannot find 'handleContinuation' "
+ + "(system.js not loaded?)");
+
+ Object args[] = { jswk };
+
+ int size = (params != null ? params.size() : 0);
+ NativeArray parameters = new NativeArray(size);
+
+ if (size != 0) {
+ for (int i = 0; i < size; i++) {
+ Interpreter.Argument arg = (Interpreter.Argument)params.get(i);
+ parameters.put(arg.name, parameters, arg.value);
+ }
+ }
+
+ cocoon.setParameters(parameters);
+
+ try {
+ ((Function)handleContFunction).call(context, kScope, kScope, args);
+ } catch (JavaScriptException ex) {
+
Context.reportError(ToolErrorReporter.getMessage("msg.uncaughtJSException",
+ ex.getMessage()));
+ throw ex;
+ } finally {
+ Context.exit();
+ }
}
- }
}
1.2 +24 -15
cocoon-2.1/src/java/org/apache/cocoon/components/flow/javascript/ScriptableConnection.java
Index: ScriptableConnection.java
===================================================================
RCS file:
/home/cvs/cocoon-2.1/src/java/org/apache/cocoon/components/flow/javascript/ScriptableConnection.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ScriptableConnection.java 9 Mar 2003 00:08:50 -0000 1.1
+++ ScriptableConnection.java 15 Mar 2003 09:56:04 -0000 1.2
@@ -123,7 +123,6 @@
return fun.has(index, start);
}
-
public void put(String name, Scriptable start, Object value) {
fun.put(name, start, value);
}
@@ -208,23 +207,33 @@
public Object jsFunction_query(String sql,
int startRow,
- int maxRows) throws Exception {
- Statement stmt = connection.createStatement();
- ResultSet rs = stmt.executeQuery(sql);
- if (maxRows == 0) {
- maxRows = -1;
+ int maxRows)
+ throws JavaScriptException {
+ try {
+ Statement stmt = connection.createStatement();
+ ResultSet rs = stmt.executeQuery(sql);
+ if (maxRows == 0) {
+ maxRows = -1;
+ }
+ ScriptableResult s = new ScriptableResult(this, rs,
+ startRow, maxRows);
+ s.setParentScope(getTopLevelScope(this));
+ s.setPrototype(getClassPrototype(this, s.getClassName()));
+ return s;
+ } catch (Exception e) {
+ throw new JavaScriptException(e);
}
- ScriptableResult s = new ScriptableResult(this, rs,
- startRow, maxRows);
- s.setParentScope(getTopLevelScope(this));
- s.setPrototype(getClassPrototype(this, s.getClassName()));
- return s;
}
- public int jsFunction_update(String sql) throws Exception {
- Statement stmt = connection.createStatement();
- stmt.execute(sql);
- return stmt.getUpdateCount();
+ public int jsFunction_update(String sql)
+ throws JavaScriptException {
+ try {
+ Statement stmt = connection.createStatement();
+ stmt.execute(sql);
+ return stmt.getUpdateCount();
+ } catch (Exception e) {
+ throw new JavaScriptException(e);
+ }
}
public Object get(String name, Scriptable start) {