You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by sy...@apache.org on 2003/10/03 15:40:41 UTC
cvs commit: cocoon-2.1/src/blocks/woody/java/org/apache/cocoon/woody/util JavaScriptHelper.java
sylvain 2003/10/03 06:40:41
Modified: src/blocks/woody/conf woody-binding.xconf
src/blocks/woody/java/org/apache/cocoon/woody/binding
SimpleRepeaterJXPathBinding.java
SimpleRepeaterJXPathBindingBuilder.java
src/blocks/woody/java/org/apache/cocoon/woody/datatype
EmptySelectionList.java
src/blocks/woody/java/org/apache/cocoon/woody/event/impl
JavaScriptWidgetListener.java
JavaScriptWidgetListenerBuilder.java
Added: src/blocks/woody/java/org/apache/cocoon/woody/binding
JavaScriptJXPathBinding.java
JavaScriptJXPathBindingBuilder.java
src/blocks/woody/java/org/apache/cocoon/woody/util
JavaScriptHelper.java
Log:
New JavaScriptBinding
Revision Changes Path
1.5 +1 -0 cocoon-2.1/src/blocks/woody/conf/woody-binding.xconf
Index: woody-binding.xconf
===================================================================
RCS file: /home/cvs/cocoon-2.1/src/blocks/woody/conf/woody-binding.xconf,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- woody-binding.xconf 8 Sep 2003 20:40:20 -0000 1.4
+++ woody-binding.xconf 3 Oct 2003 13:40:41 -0000 1.5
@@ -13,6 +13,7 @@
<binding name="insert-node" src="org.apache.cocoon.woody.binding.InsertNodeJXPathBindingBuilder"/>
<binding name="delete-node" src="org.apache.cocoon.woody.binding.DeleteNodeJXPathBindingBuilder"/>
<binding name="insert-bean" src="org.apache.cocoon.woody.binding.InsertBeanJXPathBindingBuilder"/>
+ <binding name="javascript" src="org.apache.cocoon.woody.binding.JavaScriptJXPathBindingBuilder"/>
</bindings>
</woody-binding>
1.2 +18 -6 cocoon-2.1/src/blocks/woody/java/org/apache/cocoon/woody/binding/SimpleRepeaterJXPathBinding.java
Index: SimpleRepeaterJXPathBinding.java
===================================================================
RCS file: /home/cvs/cocoon-2.1/src/blocks/woody/java/org/apache/cocoon/woody/binding/SimpleRepeaterJXPathBinding.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- SimpleRepeaterJXPathBinding.java 8 Sep 2003 15:33:27 -0000 1.1
+++ SimpleRepeaterJXPathBinding.java 3 Oct 2003 13:40:41 -0000 1.2
@@ -72,20 +72,25 @@
private final String repeaterId;
private final String repeaterPath;
private final String rowPath;
+ private final boolean clearOnLoad;
private final JXPathBindingBase rowBinding;
public SimpleRepeaterJXPathBinding(
- String repeaterId, String repeaterPath, String rowPath, JXPathBindingBase rowBinding) {
+ String repeaterId, String repeaterPath, String rowPath, boolean clearOnLoad, JXPathBindingBase rowBinding) {
this.repeaterId = repeaterId;
this.repeaterPath = repeaterPath;
this.rowPath = rowPath;
this.rowBinding = rowBinding;
+ this.clearOnLoad = clearOnLoad;
}
public void loadFormFromModel(Widget frmModel, JXPathContext jctx) {
// Find the repeater and clear it
Repeater repeater = (Repeater) frmModel.getWidget(this.repeaterId);
- repeater.removeRows();
+
+ if (this.clearOnLoad) {
+ repeater.removeRows();
+ }
// Move to repeater context
Pointer ptr = jctx.getPointer(this.repeaterPath);
@@ -97,11 +102,18 @@
Iterator rowPointers = repeaterContext.iteratePointers(this.rowPath);
//iterate through it
+ int rowNum = 0;
while (rowPointers.hasNext()) {
- // create a new row, take that as the frmModelSubContext
- Repeater.RepeaterRow thisRow = repeater.addRow();
-
- // make a jxpath ObjectModelSubcontext on the iterated element
+ // Get a row. It is created if needed (depends on clearOnLoad)
+ Repeater.RepeaterRow thisRow;
+ if (repeater.getSize() > rowNum) {
+ thisRow = repeater.getRow(rowNum);
+ } else {
+ thisRow = repeater.addRow();
+ }
+ rowNum++;
+
+ // make a jxpath sub context on the iterated element
Pointer jxp = (Pointer) rowPointers.next();
JXPathContext rowContext = repeaterContext.getRelativeContext(jxp);
1.2 +2 -1 cocoon-2.1/src/blocks/woody/java/org/apache/cocoon/woody/binding/SimpleRepeaterJXPathBindingBuilder.java
Index: SimpleRepeaterJXPathBindingBuilder.java
===================================================================
RCS file: /home/cvs/cocoon-2.1/src/blocks/woody/java/org/apache/cocoon/woody/binding/SimpleRepeaterJXPathBindingBuilder.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- SimpleRepeaterJXPathBindingBuilder.java 8 Sep 2003 15:33:27 -0000 1.1
+++ SimpleRepeaterJXPathBindingBuilder.java 3 Oct 2003 13:40:41 -0000 1.2
@@ -77,10 +77,11 @@
String repeaterId = DomHelper.getAttribute(bindingElem, "id");
String parentPath = DomHelper.getAttribute(bindingElem, "parent-path");
String rowPath = DomHelper.getAttribute(bindingElem, "row-path");
+ boolean clearOnLoad = DomHelper.getAttributeAsBoolean(bindingElem, "clear-before-load", true);
JXPathBindingBase[] childBindings = assistant.makeChildBindings(bindingElem);
- return new SimpleRepeaterJXPathBinding(repeaterId, parentPath, rowPath,
+ return new SimpleRepeaterJXPathBinding(repeaterId, parentPath, rowPath, clearOnLoad,
new ComposedJXPathBindingBase(childBindings));
} catch (BindingException e) {
throw e;
1.1 cocoon-2.1/src/blocks/woody/java/org/apache/cocoon/woody/binding/JavaScriptJXPathBinding.java
Index: JavaScriptJXPathBinding.java
===================================================================
/*
============================================================================
The Apache Software License, Version 1.1
============================================================================
Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without modifica-
tion, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. The end-user documentation included with the redistribution, if any, must
include the following acknowledgment: "This product includes software
developed by the Apache Software Foundation (http://www.apache.org/)."
Alternately, this acknowledgment may appear in the software itself, if
and wherever such third-party acknowledgments normally appear.
4. The names "Apache Cocoon" and "Apache Software Foundation" must not be
used to endorse or promote products derived from this software without
prior written permission. For written permission, please contact
apache@apache.org.
5. Products derived from this software may not be called "Apache", nor may
"Apache" appear in their name, without prior written permission of the
Apache Software Foundation.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This software consists of voluntary contributions made by many individuals
on behalf of the Apache Software Foundation and was originally created by
Stefano Mazzocchi <st...@apache.org>. For more information on the Apache
Software Foundation, please see <http://www.apache.org/>.
*/
package org.apache.cocoon.woody.binding;
import java.util.HashMap;
import java.util.Map;
import org.apache.avalon.framework.CascadingRuntimeException;
import org.apache.cocoon.components.CocoonComponentManager;
import org.apache.cocoon.environment.ObjectModelHelper;
import org.apache.cocoon.environment.Request;
import org.apache.cocoon.woody.formmodel.Widget;
import org.apache.cocoon.woody.util.JavaScriptHelper;
import org.apache.commons.jxpath.JXPathContext;
import org.apache.commons.jxpath.Pointer;
import org.mozilla.javascript.Script;
/**
*
* @author <a href="http://www.apache.org/~sylvain/">Sylvain Wallez</a>
* @version CVS $Id: JavaScriptJXPathBinding.java,v 1.1 2003/10/03 13:40:41 sylvain Exp $
*/
public class JavaScriptJXPathBinding extends JXPathBindingBase {
private final String id;
private final String path;
private final Script loadScript;
private final Script saveScript;
public JavaScriptJXPathBinding(String id, String path, Script loadScript, Script saveScript) {
this.id = id;
this.path = path;
this.loadScript = loadScript;
this.saveScript = saveScript;
}
public void loadFormFromModel(Widget frmModel, JXPathContext jctx) {
if (this.loadScript == null) return;
Widget widget = frmModel.getWidget(this.id);
// Move to widget context
Pointer pointer = jctx.getPointer(this.path);
JXPathContext widgetCtx = jctx.getRelativeContext(pointer);
if (pointer.getNode() != null) {
// There are some nodes to load from
// FIXME: remove this ugly hack and get the request from the Avalon context once
// binding builder are real components
Request request = ObjectModelHelper.getRequest(CocoonComponentManager.getCurrentEnvironment().getObjectModel());
try {
Map values = new HashMap(3);
values.put("widget", widget);
values.put("jxpathContext", widgetCtx);
values.put("jxpathPointer", pointer);
JavaScriptHelper.execScript(this.loadScript, values, request);
} catch(RuntimeException re) {
// rethrow
throw re;
} catch(Exception e) {
throw new CascadingRuntimeException("Error invoking JavaScript event handler", e);
}
}
}
public void saveFormToModel(Widget frmModel, JXPathContext jctx) throws BindingException {
if (this.saveScript == null) return;
Widget widget = frmModel.getWidget(this.id);
// Move to widget context and create the path if needed
Pointer pointer = jctx.createPath(this.path);
JXPathContext widgetCtx = jctx.getRelativeContext(pointer);
try {
// FIXME: remove this ugly hack and get the request from the Avalon context once
// binding builder are real components
Request request = ObjectModelHelper.getRequest(CocoonComponentManager.getCurrentEnvironment().getObjectModel());
Map values = new HashMap();
values.put("widget", widget);
values.put("jxpathContext", widgetCtx);
values.put("jxpathPointer", pointer);
JavaScriptHelper.execScript(this.saveScript, values, request);
} catch(RuntimeException re) {
// rethrow
throw re;
} catch(Exception e) {
throw new CascadingRuntimeException("Error invoking JavaScript event handler", e);
}
}
}
1.1 cocoon-2.1/src/blocks/woody/java/org/apache/cocoon/woody/binding/JavaScriptJXPathBindingBuilder.java
Index: JavaScriptJXPathBindingBuilder.java
===================================================================
/*
============================================================================
The Apache Software License, Version 1.1
============================================================================
Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without modifica-
tion, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. The end-user documentation included with the redistribution, if any, must
include the following acknowledgment: "This product includes software
developed by the Apache Software Foundation (http://www.apache.org/)."
Alternately, this acknowledgment may appear in the software itself, if
and wherever such third-party acknowledgments normally appear.
4. The names "Apache Cocoon" and "Apache Software Foundation" must not be
used to endorse or promote products derived from this software without
prior written permission. For written permission, please contact
apache@apache.org.
5. Products derived from this software may not be called "Apache", nor may
"Apache" appear in their name, without prior written permission of the
Apache Software Foundation.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This software consists of voluntary contributions made by many individuals
on behalf of the Apache Software Foundation and was originally created by
Stefano Mazzocchi <st...@apache.org>. For more information on the Apache
Software Foundation, please see <http://www.apache.org/>.
*/
package org.apache.cocoon.woody.binding;
import org.apache.cocoon.woody.binding.JXPathBindingManager.Assistant;
import org.apache.cocoon.woody.util.DomHelper;
import org.apache.cocoon.woody.util.JavaScriptHelper;
import org.mozilla.javascript.Script;
import org.w3c.dom.Element;
/**
* Builds a {@link Binding} based on two JavaScript snippets, respectively for loading and saving the form.
* <p>
* The syntax for this binding is as follows :
* <pre>
* <wb:javascript id="foo" path="@foo">
* <wb:load-form>
* var appValue = jxpathPointer.getValue();
* var formValue = doLoadConversion(appValue);
* widget.setValue(formValue);
* </wb:load-form>
* <wb:save-form>
* var formValue = widget.getValue();
* var appValue = doSaveConversion(formValue);
* jxpathPointer.setValue(appValue);
* </wb:save-form>
* </wb:javascript>
* </pre>
* This example is rather trivial and could be replaced by a simple <wb:value>, but
* it shows the available variables in the script:
* <ul>
* <li><code>widget</code>: the widget identified by the "id" attribute,
* <li><code>jxpathPointer</code>: the JXPath pointer corresponding to the "path" attribute,
* <li><code>jxpathContext</code> (not shown): the JXPath context corresponding to the "path" attribute
* </ul>
* The <wb:save-form> snippet should be ommitted if the "read-only" attribute is present.
*
* @author <a href="http://www.apache.org/~sylvain/">Sylvain Wallez</a>
* @version CVS $Id: JavaScriptJXPathBindingBuilder.java,v 1.1 2003/10/03 13:40:41 sylvain Exp $
*/
public class JavaScriptJXPathBindingBuilder extends JXpathBindingBuilderBase {
public JXPathBindingBase buildBinding(Element element, Assistant assistant) throws BindingException {
try {
String id = DomHelper.getAttribute(element, "id");
String path = DomHelper.getAttribute(element, "path");
boolean readOnly = DomHelper.getAttributeAsBoolean(element, "read-only", false);
Element loadElem = DomHelper.getChildElement(element, BindingManager.NAMESPACE, "load-form");
Script loadScript = JavaScriptHelper.buildScript(loadElem);
Script saveScript;
if (readOnly) {
saveScript = null;
} else {
Element saveElem = DomHelper.getChildElement(element, BindingManager.NAMESPACE, "save-form");
saveScript = JavaScriptHelper.buildScript(saveElem);
}
return new JavaScriptJXPathBinding(id, path, loadScript, saveScript);
} catch(Exception e) {
throw new BindingException("Cannot build binding at " + DomHelper.getLocation(element), e);
}
}
}
1.2 +1 -2 cocoon-2.1/src/blocks/woody/java/org/apache/cocoon/woody/datatype/EmptySelectionList.java
Index: EmptySelectionList.java
===================================================================
RCS file: /home/cvs/cocoon-2.1/src/blocks/woody/java/org/apache/cocoon/woody/datatype/EmptySelectionList.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- EmptySelectionList.java 26 Sep 2003 14:44:07 -0000 1.1
+++ EmptySelectionList.java 3 Oct 2003 13:40:41 -0000 1.2
@@ -54,7 +54,6 @@
import org.apache.cocoon.transformation.I18nTransformer;
import org.apache.cocoon.woody.Constants;
-import org.apache.cocoon.woody.datatype.typeimpl.StringType;
import org.apache.cocoon.xml.AttributesImpl;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
1.4 +9 -43 cocoon-2.1/src/blocks/woody/java/org/apache/cocoon/woody/event/impl/JavaScriptWidgetListener.java
Index: JavaScriptWidgetListener.java
===================================================================
RCS file: /home/cvs/cocoon-2.1/src/blocks/woody/java/org/apache/cocoon/woody/event/impl/JavaScriptWidgetListener.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- JavaScriptWidgetListener.java 29 Sep 2003 13:01:03 -0000 1.3
+++ JavaScriptWidgetListener.java 3 Oct 2003 13:40:41 -0000 1.4
@@ -50,10 +50,11 @@
*/
package org.apache.cocoon.woody.event.impl;
+import java.util.HashMap;
+
import org.apache.avalon.framework.CascadingRuntimeException;
import org.apache.cocoon.components.CocoonComponentManager;
import org.apache.cocoon.components.flow.FlowHelper;
-import org.apache.cocoon.components.flow.javascript.fom.FOM_JavaScriptFlowHelper;
import org.apache.cocoon.environment.ObjectModelHelper;
import org.apache.cocoon.environment.Request;
import org.apache.cocoon.woody.event.ActionEvent;
@@ -61,84 +62,49 @@
import org.apache.cocoon.woody.event.ValueChangedEvent;
import org.apache.cocoon.woody.event.ValueChangedListener;
import org.apache.cocoon.woody.event.WidgetEvent;
-import org.mozilla.javascript.Context;
+import org.apache.cocoon.woody.util.JavaScriptHelper;
import org.mozilla.javascript.Script;
-import org.mozilla.javascript.Scriptable;
/**
* Listeners built by {@link org.apache.cocoon.woody.event.impl.JavaScriptWidgetListenerBuilder}
*
* @author <a href="http://www.apache.org/~sylvain/">Sylvain Wallez</a>
+ * @version CVS $Id$
*/
public abstract class JavaScriptWidgetListener {
- private static Scriptable _rootScope = null;
-
private Script script;
public JavaScriptWidgetListener(Script script) {
this.script = script;
}
- public static Scriptable getRootScope() {
- if (_rootScope == null) {
- // Create it if never used up to now
- Context ctx = Context.enter();
- try {
- _rootScope = ctx.initStandardObjects(null);
- } finally {
- Context.exit();
- }
- }
-
- return _rootScope;
-
- }
-
- public static Scriptable getParentScope(Request request) {
- // Try to get the flowscript scope
- Scriptable parentScope = (Scriptable)request.getAttribute(FOM_JavaScriptFlowHelper.FOM_SCOPE);
-
- if (parentScope != null) {
- return parentScope;
- } else {
- return getRootScope();
- }
- }
-
/**
* Call the script that implements the event handler
*/
protected void callScript(WidgetEvent event) {
- Context ctx = Context.enter();
try {
+ HashMap values = new HashMap(2);
+ values.put("event", event);
+
// FIXME: remove this ugly hack and get the request from the Avalon context once
// listener builder are real components
Request request = ObjectModelHelper.getRequest(CocoonComponentManager.getCurrentEnvironment().getObjectModel());
-
- Scriptable parentScope = getParentScope(request);
-
- // Create a new local scope for the event listener variables
- Scriptable scope = ctx.newObject(parentScope);
- scope.setPrototype(parentScope);
- scope.put("event", scope, Context.toObject(event, scope));
// Add the biz data that was passed to showForm()
Object viewData = request.getAttribute(FlowHelper.CONTEXT_OBJECT);
if (viewData != null) {
- scope.put("viewData", scope, viewData);
+ values.put("viewData", viewData);
}
- script.exec(ctx, scope);
+ JavaScriptHelper.execScript(this.script, values, request);
} catch(RuntimeException re) {
// rethrow
throw re;
} catch(Exception e) {
throw new CascadingRuntimeException("Error invoking JavaScript event handler", e);
- } finally {
- Context.exit();
}
}
1.2 +11 -23 cocoon-2.1/src/blocks/woody/java/org/apache/cocoon/woody/event/impl/JavaScriptWidgetListenerBuilder.java
Index: JavaScriptWidgetListenerBuilder.java
===================================================================
RCS file: /home/cvs/cocoon-2.1/src/blocks/woody/java/org/apache/cocoon/woody/event/impl/JavaScriptWidgetListenerBuilder.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- JavaScriptWidgetListenerBuilder.java 24 Sep 2003 20:47:06 -0000 1.1
+++ JavaScriptWidgetListenerBuilder.java 3 Oct 2003 13:40:41 -0000 1.2
@@ -50,14 +50,11 @@
*/
package org.apache.cocoon.woody.event.impl;
-import java.io.StringReader;
-
import org.apache.cocoon.woody.event.ActionListener;
+import org.apache.cocoon.woody.event.ValueChangedEvent;
import org.apache.cocoon.woody.event.WidgetListener;
import org.apache.cocoon.woody.event.WidgetListenerBuilder;
-import org.apache.cocoon.woody.event.ValueChangedEvent;
-import org.apache.cocoon.woody.util.DomHelper;
-import org.mozilla.javascript.Context;
+import org.apache.cocoon.woody.util.JavaScriptHelper;
import org.mozilla.javascript.Script;
import org.w3c.dom.Element;
@@ -79,25 +76,16 @@
public class JavaScriptWidgetListenerBuilder implements WidgetListenerBuilder {
public WidgetListener buildListener(Element element, Class listenerClass) throws Exception {
- String jsText = DomHelper.getElementText(element);
- String sourceName = DomHelper.getSystemIdLocation(element);
+ Script script = JavaScriptHelper.buildScript(element);
- Context ctx = Context.enter();
- Script script = ctx.compileReader(
- JavaScriptWidgetListener.getRootScope(), //scope
- new StringReader(jsText), // in
- sourceName == null ? "<unknown>" : sourceName, // sourceName
- DomHelper.getLineLocation(element), // lineNo
- null // securityDomain
- );
-
- if (listenerClass == ActionListener.class) {
- return new JavaScriptWidgetListener.JSActionListener(script);
- } else if (listenerClass == ValueChangedEvent.class) {
- return new JavaScriptWidgetListener.JSValueChangedListener(script);
- } else {
- throw new Exception("Unkonwn event class: " + listenerClass);
- }
+ if (listenerClass == ActionListener.class) {
+ return new JavaScriptWidgetListener.JSActionListener(script);
+ } else if (listenerClass == ValueChangedEvent.class) {
+ return new JavaScriptWidgetListener.JSValueChangedListener(script);
+ } else {
+ throw new Exception("Unkonwn event class: " + listenerClass);
+ }
}
+
}
1.1 cocoon-2.1/src/blocks/woody/java/org/apache/cocoon/woody/util/JavaScriptHelper.java
Index: JavaScriptHelper.java
===================================================================
/*
============================================================================
The Apache Software License, Version 1.1
============================================================================
Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without modifica-
tion, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. The end-user documentation included with the redistribution, if any, must
include the following acknowledgment: "This product includes software
developed by the Apache Software Foundation (http://www.apache.org/)."
Alternately, this acknowledgment may appear in the software itself, if
and wherever such third-party acknowledgments normally appear.
4. The names "Apache Cocoon" and "Apache Software Foundation" must not be
used to endorse or promote products derived from this software without
prior written permission. For written permission, please contact
apache@apache.org.
5. Products derived from this software may not be called "Apache", nor may
"Apache" appear in their name, without prior written permission of the
Apache Software Foundation.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This software consists of voluntary contributions made by many individuals
on behalf of the Apache Software Foundation and was originally created by
Stefano Mazzocchi <st...@apache.org>. For more information on the Apache
Software Foundation, please see <http://www.apache.org/>.
*/
package org.apache.cocoon.woody.util;
import java.io.IOException;
import java.io.StringReader;
import java.util.Iterator;
import java.util.Map;
import org.apache.avalon.framework.CascadingRuntimeException;
import org.apache.cocoon.components.flow.javascript.fom.FOM_JavaScriptFlowHelper;
import org.apache.cocoon.environment.Request;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.JavaScriptException;
import org.mozilla.javascript.Script;
import org.mozilla.javascript.Scriptable;
import org.w3c.dom.Element;
/**
* Helper methods to use JavaScript in various locations of the Woody configuration files
* such as event listeners and bindings.
*
* @author <a href="http://www.apache.org/~sylvain/">Sylvain Wallez</a>
* @version CVS $Id: JavaScriptHelper.java,v 1.1 2003/10/03 13:40:41 sylvain Exp $
*/
public class JavaScriptHelper {
/**
* A shared root scope, avoiding to recreate a new one each time.
*/
private static Scriptable _rootScope = null;
/**
* Build a script with the content of a DOM element.
*
* @param element the element containing the script
* @return the compiled script
* @throws IOException
*/
public static Script buildScript(Element element) throws IOException {
String jsText = DomHelper.getElementText(element);
String sourceName = DomHelper.getSystemIdLocation(element);
Context ctx = Context.enter();
Script script;
try {
script = ctx.compileReader(
getRootScope(), //scope
new StringReader(jsText), // in
sourceName == null ? "<unknown>" : sourceName, // sourceName
DomHelper.getLineLocation(element), // lineNo
null // securityDomain
);
} finally {
Context.exit();
}
return script;
}
/**
* Get a root scope for building child scopes.
*
* @return an appropriate root scope
*/
private static Scriptable getRootScope() {
if (_rootScope == null) {
// Create it if never used up to now
Context ctx = Context.enter();
try {
_rootScope = ctx.initStandardObjects(null);
} finally {
Context.exit();
}
}
return _rootScope;
}
/**
* Get a parent scope for building a child scope. The request is searched for an existing scope
* that can be provided by a flowscript higher in the call stack, giving visibility to flowscript
* functions and global (session) variables.
*
* @param request a request where the flowscript scope will be searched (can be <code>null</code>).
* @return an appropriate parent scope.
*/
public static Scriptable getParentScope(Request request) {
// Try to get the flowscript scope
Scriptable parentScope = null;
if (request != null) {
parentScope = (Scriptable)request.getAttribute(FOM_JavaScriptFlowHelper.FOM_SCOPE);
}
if (parentScope != null) {
return parentScope;
} else {
return getRootScope();
}
}
public static Object execScript(Script script, Map values, Request request) throws JavaScriptException {
Context ctx = Context.enter();
try {
Scriptable parentScope = getParentScope(request);
// Create a new local scope for the event listener variables
Scriptable scope;
try {
scope = ctx.newObject(parentScope);
} catch (Exception e) {
// Should normally not happen
throw new CascadingRuntimeException("Cannont create script scope", e);
}
scope.setPrototype(parentScope);
// Populate the scope
Iterator iter = values.entrySet().iterator();
while(iter.hasNext()) {
Map.Entry entry = (Map.Entry)iter.next();
String key = (String)entry.getKey();
Object value = entry.getValue();
scope.put(key, scope, Context.toObject(value, scope));
}
return script.exec(ctx, scope);
} finally {
Context.exit();
}
}
}