KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cocoon > forms > binding > JavaScriptJXPathBindingBuilder


1 /*
2  * Copyright 1999-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.apache.cocoon.forms.binding;
17
18 import java.util.Collections JavaDoc;
19 import java.util.HashMap JavaDoc;
20 import java.util.Iterator JavaDoc;
21 import java.util.Map JavaDoc;
22
23 import org.apache.avalon.framework.context.Context;
24 import org.apache.avalon.framework.context.ContextException;
25 import org.apache.avalon.framework.context.Contextualizable;
26 import org.apache.cocoon.forms.binding.JXPathBindingManager.Assistant;
27 import org.apache.cocoon.forms.util.DomHelper;
28 import org.apache.cocoon.forms.util.JavaScriptHelper;
29 import org.mozilla.javascript.Function;
30 import org.w3c.dom.Element JavaDoc;
31
32 /**
33  * Builds a {@link Binding} based on two JavaScript snippets, respectively for loading and saving the form.
34  * This binding also optionally accepts named child bindings, which are useful when the bound widget is a container.
35  * <p>
36  * The syntax for this binding is as follows:
37  * <pre>
38  * &lt;fb:javascript id="foo" path="@foo"&gt;
39  * &lt;fb:load-form&gt;
40  * var appValue = jxpathPointer.getValue();
41  * var formValue = doLoadConversion(appValue);
42  * widget.setValue(formValue);
43  * childBindings["foo"].loadFormFromModel(widget, jxpathContext);
44  * &lt;/fb:load-form&gt;
45  * &lt;fb:save-form&gt;
46  * var formValue = widget.getValue();
47  * var appValue = doSaveConversion(formValue);
48  * jxpathPointer.setValue(appValue);
49  * childBindings["foo"].saveFormToModel(widget, jxpathContext);
50  * &lt;/fb:save-form&gt;
51  * &lt;fb:child-binding name="foo"&gt;
52  * &lt;fb:value id="bar" path="baz"/&gt;
53  * &lt;/fb:child-binding&gt;
54  * &lt;/fb:javascript&gt;
55  * </pre>
56  * This example is rather trivial and could be replaced by a simple &lt;fb:value&gt;, but
57  * it shows the available variables in the script:
58  * <ul>
59  * <li><code>widget</code>: the widget identified by the "id" attribute,
60  * <li><code>jxpathPointer</code>: the JXPath pointer corresponding to the "path" attribute,
61  * <li><code>jxpathContext</code> (not shown): the JXPath context corresponding to the "path" attribute
62  * </ul>
63  * <b>Notes:</b><ul>
64  * <li>The &lt;fb:save-form&gt; snippet should be ommitted if the "direction" attribute is set to "load".</li>
65  * <li>The &lt;fb:load-form&gt; snippet should be ommitted if the "direction" attribute is set to "save".</li>
66  * </ul>
67  *
68  * @author <a HREF="http://www.apache.org/~sylvain/">Sylvain Wallez</a>
69  * @version $Id: JavaScriptJXPathBindingBuilder.java 289538 2005-09-16 13:46:22Z sylvain $
70  */

71 public class JavaScriptJXPathBindingBuilder extends JXPathBindingBuilderBase implements Contextualizable {
72
73     private Context avalonContext;
74
75     public void contextualize(Context context) throws ContextException {
76         this.avalonContext = context;
77     }
78
79     public JXPathBindingBase buildBinding(Element JavaDoc element, Assistant assistant) throws BindingException {
80         try {
81             CommonAttributes commonAtts = JXPathBindingBuilderBase.getCommonAttributes(element);
82
83             String JavaDoc id = DomHelper.getAttribute(element, "id", null);
84             String JavaDoc path = DomHelper.getAttribute(element, "path", null);
85
86             JavaScriptJXPathBinding otherBinding = (JavaScriptJXPathBinding)assistant.getContext().getSuperBinding();
87             
88             if(otherBinding!=null) {
89                 commonAtts = JXPathBindingBuilderBase.mergeCommonAttributes(otherBinding.getCommonAtts(),commonAtts);
90                 
91                 if(id==null)
92                     id=otherBinding.getId();
93                 if(path==null)
94                     path=otherBinding.getPath();
95             }
96             
97             // Build load script
98
Function loadScript = null;
99             if (commonAtts.loadEnabled) {
100                 if (otherBinding != null)
101                     loadScript = otherBinding.getLoadScript();
102                 
103                 Element JavaDoc loadElem = DomHelper.getChildElement(element, BindingManager.NAMESPACE, "load-form");
104                 if (loadElem != null) {
105                     loadScript = JavaScriptHelper.buildFunction(loadElem, "loadForm", JavaScriptJXPathBinding.LOAD_PARAMS);
106                 }
107             }
108
109             // Build save script
110
Function saveScript = null;
111             if (commonAtts.saveEnabled) {
112                 if (otherBinding != null)
113                     saveScript = otherBinding.getSaveScript();
114                 
115                 Element JavaDoc saveElem = DomHelper.getChildElement(element, BindingManager.NAMESPACE, "save-form");
116                 if (saveElem != null) {
117                     saveScript = JavaScriptHelper.buildFunction(saveElem, "saveForm", JavaScriptJXPathBinding.SAVE_PARAMS);
118                 }
119             }
120
121             // Build child bindings
122
Map JavaDoc childBindings = new HashMap JavaDoc();
123             
124             if (otherBinding != null) {
125                 Map JavaDoc otherChildren = otherBinding.getChildBindingsMap();
126                 Iterator JavaDoc it = otherChildren.entrySet().iterator();
127                 while(it.hasNext()) {
128                     Map.Entry JavaDoc entry = (Map.Entry JavaDoc)it.next();
129                     childBindings.put(entry.getKey(),entry.getValue());
130                 }
131             }
132             
133             Element JavaDoc[] children = DomHelper.getChildElements(element, BindingManager.NAMESPACE, "child-binding");
134             if (children.length != 0) {
135                 for (int i = 0; i < children.length; i++) {
136                     Element JavaDoc child = children[i];
137
138                     // Get the binding name and check its uniqueness
139
String JavaDoc name = DomHelper.getAttribute(child, "name");
140                     
141                     JXPathBindingBase[] otherBindings = null;
142                     if (childBindings.containsKey(name)) {
143                         //throw new BindingException("Duplicate name '" + name + "' at " + DomHelper.getLocation(child));
144
otherBindings = ((ComposedJXPathBindingBase)childBindings.get(name)).getChildBindings();
145                     }
146                     
147                     // Build the child binding
148
JXPathBindingBase[] bindings = assistant.makeChildBindings(child,otherBindings);
149                     if (bindings == null) {
150                         bindings = new JXPathBindingBase[0];
151                     }
152
153                     ComposedJXPathBindingBase composedBinding = new ComposedJXPathBindingBase(commonAtts, bindings);
154                     composedBinding.enableLogging(getLogger());
155                     childBindings.put(name, composedBinding);
156                 }
157             }
158
159             JXPathBindingBase result = new JavaScriptJXPathBinding(this.avalonContext, commonAtts, id, path, loadScript, saveScript,
160                 Collections.unmodifiableMap(childBindings));
161             result.enableLogging(getLogger());
162             return result;
163
164         } catch(BindingException be) {
165             throw be;
166         } catch(Exception JavaDoc e) {
167             throw new BindingException("Cannot build binding at " + DomHelper.getLocation(element), e);
168         }
169     }
170 }
171
Popular Tags