KickJava   Java API By Example, From Geeks To Geeks.

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


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.Iterator JavaDoc;
19
20 import org.apache.avalon.framework.logger.Logger;
21 import org.apache.cocoon.forms.formmodel.Repeater;
22 import org.apache.cocoon.forms.formmodel.Widget;
23 import org.apache.commons.jxpath.JXPathContext;
24 import org.apache.commons.jxpath.Pointer;
25
26 /**
27  * Simple binding for repeaters: on save, first deletes the target data
28  * before recreating it from scratch.
29  * <p>
30  * For a smarter binding that avoids deletion and recreation, consider
31  * {@link org.apache.cocoon.forms.binding.RepeaterJXPathBinding}
32  *
33  * @author <a HREF="http://www.apache.org/~sylvain/">Sylvain Wallez</a>
34  * @version $Id: SimpleRepeaterJXPathBinding.java 289538 2005-09-16 13:46:22Z sylvain $
35  */

36 public class SimpleRepeaterJXPathBinding extends JXPathBindingBase {
37
38     private final String JavaDoc repeaterId;
39     private final String JavaDoc repeaterPath;
40     private final String JavaDoc rowPath;
41     private final boolean clearOnLoad;
42     private final JXPathBindingBase rowBinding;
43     private final boolean deleteIfEmpty;
44
45     public SimpleRepeaterJXPathBinding(
46             JXPathBindingBuilderBase.CommonAttributes commonAtts,
47             String JavaDoc repeaterId, String JavaDoc repeaterPath, String JavaDoc rowPath,
48             boolean clearOnLoad, boolean deleteIfEmpty,
49             JXPathBindingBase rowBinding) {
50         super(commonAtts);
51         this.repeaterId = repeaterId;
52         this.repeaterPath = repeaterPath;
53         this.rowPath = rowPath;
54         this.rowBinding = rowBinding;
55         this.rowBinding.setParent(this);
56         this.clearOnLoad = clearOnLoad;
57         this.deleteIfEmpty = deleteIfEmpty;
58     }
59     
60     public String JavaDoc getId() { return repeaterId; }
61     public String JavaDoc getRepeaterPath() { return repeaterPath; }
62     public String JavaDoc getRowPath() { return rowPath; }
63     public boolean getClearOnLoad() { return clearOnLoad; }
64     public boolean getDeleteIfEmpty() { return deleteIfEmpty; }
65     public JXPathBindingBase[] getChildBindings() { return ((ComposedJXPathBindingBase)rowBinding).getChildBindings(); }
66
67     public void doLoad(Widget frmModel, JXPathContext jctx)
68             throws BindingException {
69         // Find the repeater and clear it
70
Repeater repeater = (Repeater) selectWidget(frmModel, this.repeaterId);
71
72         if (this.clearOnLoad) {
73             repeater.clear();
74         }
75
76         // Move to repeater context
77
Pointer ptr = jctx.getPointer(this.repeaterPath);
78         if (ptr.getNode() != null) {
79             // There are some nodes to load from
80

81             JXPathContext repeaterContext = jctx.getRelativeContext(ptr);
82             // build a jxpath iterator for pointers
83
Iterator JavaDoc rowPointers = repeaterContext.iteratePointers(this.rowPath);
84
85             //iterate through it
86
int rowNum = 0;
87             while (rowPointers.hasNext()) {
88                 // Get a row. It is created if needed (depends on clearOnLoad)
89
Repeater.RepeaterRow thisRow;
90                 if (repeater.getSize() > rowNum) {
91                     thisRow = repeater.getRow(rowNum);
92                 } else {
93                     thisRow = repeater.addRow();
94                 }
95                 rowNum++;
96
97                 // make a jxpath sub context on the iterated element
98
Pointer jxp = (Pointer) rowPointers.next();
99                 JXPathContext rowContext = repeaterContext.getRelativeContext(jxp);
100
101                 this.rowBinding.loadFormFromModel(thisRow, rowContext);
102             }
103         }
104         if (getLogger().isDebugEnabled()) {
105             getLogger().debug("done loading rows " + toString());
106         }
107     }
108
109     public void doSave(Widget frmModel, JXPathContext jctx)
110             throws BindingException {
111         // Find the repeater
112
Repeater repeater = (Repeater)selectWidget(frmModel, this.repeaterId);
113
114         if (repeater.getSize() == 0 && this.deleteIfEmpty) {
115             // Repeater is empty : erase all
116
jctx.removeAll(this.repeaterPath);
117         } else {
118             // Repeater is not empty
119
// Move to repeater context and create the path if needed
120
JXPathContext repeaterContext =
121                 jctx.getRelativeContext(jctx.createPath(this.repeaterPath));
122
123             // Delete all that is already present
124
repeaterContext.removeAll(this.rowPath);
125
126             for (int i = 0; i < repeater.getSize(); i++) {
127                 Pointer rowPtr = repeaterContext.createPath(
128                         this.rowPath + '[' + (i+1) + ']');
129                 JXPathContext rowContext =
130                     repeaterContext.getRelativeContext(rowPtr);
131                 this.rowBinding.saveFormToModel(repeater.getRow(i),
132                         rowContext);
133             }
134         }
135     }
136
137     public String JavaDoc toString() {
138         return this.getClass().getName()+ " [widget=" + this.repeaterId +
139             ", xpath=" + this.repeaterPath + "]";
140     }
141
142     public void enableLogging(Logger logger) {
143         super.enableLogging(logger);
144         this.rowBinding.enableLogging(logger);
145     }
146 }
147
Popular Tags