KickJava   Java API By Example, From Geeks To Geeks.

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


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 org.apache.cocoon.forms.util.DomHelper;
19 import org.apache.cocoon.util.location.LocationAttributes;
20 import org.w3c.dom.Element JavaDoc;
21
22 /**
23  * RepeaterJXPathBindingBuilder provides a helper class for the Factory
24  * implemented in {@link JXPathBindingManager} that helps construct the
25  * actual {@link RepeaterJXPathBinding} out of the configuration in the
26  * provided configElement which looks like:
27  * <pre><code>
28  * &lt;fb:repeater
29  * id="contacts"
30  * parent-path="contacts"
31  * row-path="contact"
32  * row-path-insert="new-contact" &gt;
33  *
34  * &lt;fb:identity&gt;
35  * &lt;!-- nested bindings that map the 'identity' of the items --&gt;
36  * &lt;/fb:identity&gt;
37  *
38  * &lt;fb:on-bind&gt;
39  * &lt;!-- nested bindings executed on updates AND right after the insert --&gt;
40  * &lt;/fb:on-bind&gt;
41  *
42  * &lt;fb:on-delete-row&gt;
43  * &lt;!-- nested bindings executed on deletion of row --&gt;
44  * &lt;/fb:on-delete-row&gt;
45  *
46  * &lt;fb:on-insert-row&gt;
47  * &lt;!-- nested bindings executed to prepare the insertion of a row --&gt;
48  * &lt;/fb:on-insert-row&gt;
49  *
50  * &lt;/fb:repeater&gt;
51  * </code></pre>
52  *
53  * @version $Id: RepeaterJXPathBindingBuilder.java 290473 2005-09-20 15:30:48Z sylvain $
54  */

55 public class RepeaterJXPathBindingBuilder extends JXPathBindingBuilderBase {
56     
57     /**
58      * Creates an instance of {@link RepeaterJXPathBinding} according to the
59      * attributes and nested comfiguration elements of the bindingElm.
60      *
61      * @param bindingElm
62      * @param assistant
63      * @return JXPathBindingBase
64      */

65     public JXPathBindingBase buildBinding(Element JavaDoc bindingElm,
66             JXPathBindingManager.Assistant assistant) throws BindingException {
67         
68         if (bindingElm.hasAttribute("unique-row-id")) {
69             throw new BindingException("Attribute 'unique-row-id' is no more supported, use <fb:identity> instead",
70                     LocationAttributes.getLocation(bindingElm));
71         }
72
73         if (bindingElm.hasAttribute("unique-path")) {
74             throw new BindingException("Attribute 'unique-path' is no more supported, use <fb:identity> instead",
75                     LocationAttributes.getLocation(bindingElm));
76         }
77
78         try {
79             CommonAttributes commonAtts =
80                 JXPathBindingBuilderBase.getCommonAttributes(bindingElm);
81
82             String JavaDoc repeaterId = DomHelper.getAttribute(bindingElm, "id", null);
83             String JavaDoc parentPath =
84                 DomHelper.getAttribute(bindingElm, "parent-path", null);
85             String JavaDoc rowPath = DomHelper.getAttribute(bindingElm, "row-path", null);
86             String JavaDoc rowPathForInsert =
87                 DomHelper.getAttribute(bindingElm, "row-path-insert", rowPath);
88             
89 // do inheritance
90
RepeaterJXPathBinding otherBinding = (RepeaterJXPathBinding)assistant.getContext().getSuperBinding();
91             JXPathBindingBase[] existingOnBind = null;
92             JXPathBindingBase[] existingOnDelete = null;
93             JXPathBindingBase[] existingOnInsert = null;
94             JXPathBindingBase[] existingIdentity = null;
95             if(otherBinding!=null) {
96                 commonAtts = JXPathBindingBuilderBase.mergeCommonAttributes(otherBinding.getCommonAtts(),commonAtts);
97                 
98                 if(repeaterId==null)
99                     repeaterId = otherBinding.getId();
100                 if(parentPath==null)
101                     parentPath = otherBinding.getRepeaterPath();
102                 if(rowPath==null)
103                     rowPath = otherBinding.getRowPath();
104                 if(rowPathForInsert==null)
105                     rowPathForInsert = otherBinding.getInsertRowPath();
106                 
107                 if(otherBinding.getRowBinding() != null)
108                     existingOnBind = otherBinding.getRowBinding().getChildBindings();
109                 if(otherBinding.getDeleteRowBinding() != null)
110                     existingOnDelete = otherBinding.getDeleteRowBinding().getChildBindings();
111                 if(otherBinding.getIdentityBinding() != null)
112                     existingIdentity = otherBinding.getIdentityBinding().getChildBindings();
113                 if(otherBinding.getInsertRowBinding() != null)
114                     existingOnInsert = new JXPathBindingBase[] { otherBinding.getInsertRowBinding() };
115             }
116
117             Element JavaDoc childWrapElement =
118                 DomHelper.getChildElement(bindingElm, BindingManager.NAMESPACE, "on-bind");
119             
120             JXPathBindingBase[] childBindings =
121                 assistant.makeChildBindings(childWrapElement,existingOnBind);
122             if(childBindings == null)
123                 childBindings = existingOnBind;
124
125             Element JavaDoc deleteWrapElement = DomHelper.getChildElement(bindingElm,
126                     BindingManager.NAMESPACE, "on-delete-row");
127             JXPathBindingBase[] deleteBindings = null;
128             if (deleteWrapElement != null) {
129                 deleteBindings =
130                     assistant.makeChildBindings(deleteWrapElement,existingOnDelete);
131                 if(deleteBindings == null)
132                     deleteBindings = existingOnDelete;
133             }
134
135             Element JavaDoc insertWrapElement = DomHelper.getChildElement(bindingElm,
136                     BindingManager.NAMESPACE, "on-insert-row");
137             JXPathBindingBase insertBinding = null;
138             if (insertWrapElement != null) {
139                 insertBinding =
140                     assistant.makeChildBindings(insertWrapElement,existingOnInsert)[0];
141                     // TODO: we now safely take only the first element here,
142
// but we should in fact send out a warning to the log
143
// if more were available!
144
if(insertBinding == null && existingOnInsert != null)
145                     insertBinding = existingOnInsert[0];
146             }
147
148             Element JavaDoc identityWrapElement = DomHelper.getChildElement(bindingElm,
149                     BindingManager.NAMESPACE, "identity");
150             JXPathBindingBase[] identityBinding = null;
151             if (identityWrapElement != null) {
152                 // TODO: we can only handle ValueJXPathBinding at the moment:
153
// http://marc.theaimsgroup.com/?l=xml-cocoon-dev&m=107906438632484&w=4
154
identityBinding =
155                     assistant.makeChildBindings(identityWrapElement,existingIdentity);
156                 if (identityBinding != null) {
157                     for (int i = 0; i < identityBinding.length;i++) {
158                         if (!(identityBinding[i] instanceof ValueJXPathBinding)) {
159                             throw new BindingException("Error building repeater binding defined at " +
160                                     DomHelper.getLocation(bindingElm) + ": Only value binding (i.e. fb:value) " +
161                                     "can be used inside fb:identity at the moment. You can read " +
162                                     "http://marc.theaimsgroup.com/?l=xml-cocoon-dev&m=107906438632484&w=4" +
163                                     " if you want to know more on this.");
164                         }
165                     }
166                 } else {
167                     identityBinding = existingIdentity;
168                 }
169             }
170
171             RepeaterJXPathBinding repeaterBinding =
172                 new RepeaterJXPathBinding(commonAtts, repeaterId, parentPath,
173                         rowPath, rowPathForInsert,
174                         childBindings, insertBinding, deleteBindings, identityBinding);
175             return repeaterBinding;
176         } catch (BindingException e) {
177             throw e;
178         } catch (Exception JavaDoc e) {
179             throw new BindingException(
180                     "Error building repeater binding defined at " +
181                     DomHelper.getLocation(bindingElm), e);
182         }
183     }
184 }
185
Popular Tags