001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.cocoon.forms.binding;
018:
019: import java.util.Iterator;
020: import java.util.Map;
021:
022: import org.apache.avalon.framework.CascadingRuntimeException;
023: import org.apache.avalon.framework.context.Context;
024:
025: import org.apache.cocoon.components.ContextHelper;
026: import org.apache.cocoon.components.flow.javascript.ScriptableMap;
027: import org.apache.cocoon.forms.formmodel.Widget;
028: import org.apache.cocoon.forms.util.JavaScriptHelper;
029:
030: import org.apache.commons.jxpath.JXPathContext;
031: import org.apache.commons.jxpath.Pointer;
032: import org.mozilla.javascript.Function;
033: import org.mozilla.javascript.Scriptable;
034:
035: /**
036: *
037: * @version $Id: JavaScriptJXPathBinding.java 517733 2007-03-13 15:37:22Z vgritsenko $
038: */
039: public class JavaScriptJXPathBinding extends JXPathBindingBase {
040:
041: final static String[] LOAD_PARAMS = { "widget", "jxpathPointer",
042: "jxpathContext", "childBindings" };
043: final static String[] SAVE_PARAMS = { "widget", "jxpathPointer",
044: "jxpathContext", "childBindings" };
045:
046: private final Context avalonContext;
047: private final String id;
048: private final String path;
049: private final Function loadScript;
050: private final Function saveScript;
051: private final Scriptable childBindings;
052: private final Map childBindingsMap;
053:
054: public JavaScriptJXPathBinding(Context context,
055: JXPathBindingBuilderBase.CommonAttributes commonAtts,
056: String id, String path, Function loadScript,
057: Function saveScript, Map childBindings) {
058: super (commonAtts);
059: this .id = id;
060: this .path = path;
061: this .loadScript = loadScript;
062: this .saveScript = saveScript;
063: this .avalonContext = context;
064:
065: // Set parent on child bindings
066: for (Iterator i = childBindings.values().iterator(); i
067: .hasNext();) {
068: ((Binding) i.next()).setParent(this );
069: }
070:
071: this .childBindingsMap = childBindings;
072: this .childBindings = new ScriptableMap(childBindings);
073: }
074:
075: public String getPath() {
076: return path;
077: }
078:
079: public String getId() {
080: return id;
081: }
082:
083: public Context getContext() {
084: return avalonContext;
085: }
086:
087: public Function getLoadScript() {
088: return loadScript;
089: }
090:
091: public Function getSaveScript() {
092: return saveScript;
093: }
094:
095: public Map getChildBindingsMap() {
096: return childBindingsMap;
097: }
098:
099: public void doLoad(Widget frmModel, JXPathContext jctx) {
100: if (this .loadScript != null) {
101: Widget widget = selectWidget(frmModel, this .id);
102:
103: // Move to widget context
104: Pointer pointer = jctx.getPointer(this .path);
105:
106: Map objectModel = ContextHelper
107: .getObjectModel(this .avalonContext);
108:
109: try {
110: JXPathContext newCtx = pointer.getNode() == null ? null
111: : jctx.getRelativeContext(pointer);
112:
113: JavaScriptHelper.callFunction(this .loadScript, widget,
114: new Object[] { widget, pointer, newCtx,
115: this .childBindings }, objectModel);
116:
117: } catch (RuntimeException re) {
118: // rethrow
119: throw re;
120: } catch (Exception e) {
121: throw new CascadingRuntimeException(
122: "Error invoking JavaScript event handler", e);
123: }
124: } else {
125: if (getLogger().isInfoEnabled()) {
126: getLogger().info(
127: "[Javascript Binding] - loadForm: No javascript code available. Widget id="
128: + this .getId());
129: }
130: }
131: }
132:
133: public void doSave(Widget frmModel, JXPathContext jctx)
134: throws BindingException {
135: if (this .saveScript != null) {
136: Widget widget = selectWidget(frmModel, this .id);
137:
138: // Move to widget context and create the path if needed
139: Pointer pointer = jctx.createPath(this .path);
140: JXPathContext widgetCtx = jctx.getRelativeContext(pointer);
141: try {
142: Map objectModel = ContextHelper
143: .getObjectModel(this .avalonContext);
144:
145: JavaScriptHelper.callFunction(this .saveScript, widget,
146: new Object[] { widget, pointer, widgetCtx,
147: this .childBindings }, objectModel);
148:
149: } catch (RuntimeException re) {
150: // rethrow
151: throw re;
152: } catch (Exception e) {
153: throw new CascadingRuntimeException(
154: "Error invoking JavaScript event handler", e);
155: }
156: } else {
157: if (getLogger().isInfoEnabled()) {
158: getLogger()
159: .info(
160: "[Javascript Binding] - saveForm: No code available on the javascript binding with id '"
161: + getId() + "'");
162: }
163: }
164: }
165: }
|