1 16 package org.apache.cocoon.woody.binding; 17 18 import java.util.Iterator ; 19 20 import org.apache.avalon.framework.logger.Logger; 21 import org.apache.cocoon.woody.formmodel.Repeater; 22 import org.apache.cocoon.woody.formmodel.Widget; 23 import org.apache.commons.jxpath.JXPathContext; 24 import org.apache.commons.jxpath.Pointer; 25 import org.w3c.dom.Node ; 26 import org.w3c.dom.NodeList ; 27 28 39 public class TempRepeaterJXPathBinding extends JXPathBindingBase { 40 41 private final String repeaterId; 42 private final String repeaterPath; 43 private final String rowPath; 44 private final String rowPathInsert; 45 private final boolean clearOnLoad; 46 private final JXPathBindingBase rowBinding; 47 private final JXPathBindingBase insertRowBinding; 48 private final boolean deleteIfEmpty; 49 private final boolean virtualRows; 50 51 public TempRepeaterJXPathBinding( 52 JXPathBindingBuilderBase.CommonAttributes commonAtts, 53 String repeaterId, String repeaterPath, 54 String rowPath, String rowPathInsert, 55 boolean virtualRows, boolean clearOnLoad, boolean deleteIfEmpty, 56 JXPathBindingBase rowBinding, JXPathBindingBase insertBinding) { 57 super(commonAtts); 58 this.repeaterId = repeaterId; 59 this.repeaterPath = repeaterPath; 60 this.rowPath = rowPath; 61 this.rowPathInsert = rowPathInsert; 62 this.rowBinding = rowBinding; 63 this.rowBinding.setParent(this); 64 this.insertRowBinding = insertBinding; 65 this.insertRowBinding.setParent(this); 66 this.virtualRows = virtualRows; 67 this.clearOnLoad = clearOnLoad; 68 this.deleteIfEmpty = deleteIfEmpty; 69 } 70 71 public void doLoad(Widget frmModel, JXPathContext jctx) throws BindingException { 72 Repeater repeater = (Repeater) frmModel.getWidget(this.repeaterId); 76 if (repeater == null) { 77 String fullId = frmModel.getFullyQualifiedId(); 78 if (fullId == null || fullId.length() == 0) { 79 fullId = ""; 80 } else { 81 fullId = fullId + "."; 82 } 83 throw new RuntimeException ( 84 "TempRepeaterJXPathBinding: Repeater \"" + fullId + this.repeaterId + 85 "\" does not exist (" + frmModel.getLocation() + ")"); 86 } 87 88 if (this.clearOnLoad) { 90 repeater.removeRows(); 91 } 92 93 Pointer repeaterPointer = jctx.getPointer(this.repeaterPath); 95 96 if (repeaterPointer != null) { 101 102 JXPathContext repeaterContext = jctx.getRelativeContext(repeaterPointer); 104 105 Iterator rowPointers = repeaterContext.iteratePointers(this.rowPath); 107 108 int rowNum = 0; 110 while (rowPointers.hasNext()) { 111 112 Repeater.RepeaterRow thisRow; 114 if (repeater.getSize() > rowNum) { 115 thisRow = repeater.getRow(rowNum); 116 } else { 117 thisRow = repeater.addRow(); 118 } 119 rowNum++; 120 121 Pointer rowPointer = (Pointer) rowPointers.next(); 123 JXPathContext rowContext = repeaterContext.getRelativeContext(rowPointer); 124 125 135 if (virtualRows == true) { 136 Node repeaterNode = (Node )repeaterPointer.getNode(); 137 Node virtualNode = repeaterNode.getOwnerDocument().createElementNS(null, "virtual"); 138 Node clone = ((Node )rowPointer.getNode()).cloneNode(true); 139 virtualNode.appendChild(clone); 140 rowContext = JXPathContext.newContext(repeaterContext, virtualNode); 141 } 142 143 this.rowBinding.loadFormFromModel(thisRow, rowContext); 145 } 146 } 147 148 if (getLogger().isDebugEnabled()) 149 getLogger().debug("done loading rows " + toString()); 150 } 151 152 public void doSave(Widget frmModel, JXPathContext jctx) throws BindingException { 153 Repeater repeater = (Repeater) frmModel.getWidget(this.repeaterId); 155 156 if (repeater.getSize() == 0 && this.deleteIfEmpty) { 159 jctx.removeAll(this.repeaterPath); 161 162 } else { 164 165 JXPathContext repeaterContext = jctx.getRelativeContext(jctx.createPath(this.repeaterPath)); 167 168 repeaterContext.removeAll(this.rowPath); 170 171 if(repeater.getSize() > 0) { 173 if (this.insertRowBinding != null) { 174 175 178 for (int i = 0; i < repeater.getSize(); i++) { 180 181 Pointer rowPointer = repeaterContext.getPointer(this.rowPathInsert); 183 JXPathContext rowContext = repeaterContext.getRelativeContext(rowPointer); 184 185 Node rowNode = null; 188 Node virtualNode = null; 189 190 if (virtualRows == true) { 193 rowNode = (Node )rowContext.getContextBean(); 194 virtualNode = rowNode.getOwnerDocument().createElementNS(null, "virtual"); 195 rowContext = JXPathContext.newContext(repeaterContext, virtualNode); 196 } 197 198 this.insertRowBinding.saveFormToModel(repeater, rowContext); 200 201 this.rowBinding.saveFormToModel(repeater.getRow(i), rowContext); 203 204 if (virtualRows == true) { 207 NodeList list = virtualNode.getChildNodes(); 208 int count = list.getLength(); 209 for (int j = 0; j < count; j++) { 210 rowNode.appendChild(list.item(0)); 213 } 214 } 215 getLogger().debug("bound new row"); 216 } 217 } else { 218 getLogger().warn("TempRepeaterBinding has detected rows to insert, " + 219 "but misses the <on-insert-row> binding to do it."); 220 } 221 } 222 } 223 } 224 225 public String toString() { 226 return "TempRepeaterJXPathBinding [widget=" + this.repeaterId + ", xpath=" + this.repeaterPath + "]"; 227 } 228 229 public void enableLogging(Logger logger) { 230 super.enableLogging(logger); 231 if (this.insertRowBinding != null) { 232 this.insertRowBinding.enableLogging(logger); 233 } 234 this.rowBinding.enableLogging(logger); 235 } 236 } 237 | Popular Tags |