1 16 package org.apache.cocoon.woody.binding; 17 18 import java.util.Iterator ; 19 import java.util.LinkedList ; 20 import java.util.Locale ; 21 22 import org.apache.avalon.framework.logger.Logger; 23 import org.apache.cocoon.woody.datatype.convertor.Convertor; 24 import org.apache.cocoon.woody.formmodel.Widget; 25 import org.apache.commons.jxpath.JXPathContext; 26 import org.apache.commons.jxpath.Pointer; 27 28 34 public class MultiValueJXPathBinding extends JXPathBindingBase { 35 36 private final String multiValueId; 37 private final String multiValuePath; 38 private final String rowPath; 39 private final JXPathBindingBase updateBinding; 40 private final Convertor convertor; 41 private final Locale convertorLocale; 42 43 public MultiValueJXPathBinding( 44 JXPathBindingBuilderBase.CommonAttributes commonAtts, String multiValueId, 45 String multiValuePath, String rowPath, 46 JXPathBindingBase[] updateBindings, Convertor convertor, Locale convertorLocale) { 47 super(commonAtts); 48 this.multiValueId = multiValueId; 49 this.multiValuePath = multiValuePath; 50 this.rowPath = rowPath; 51 this.updateBinding = new ComposedJXPathBindingBase(JXPathBindingBuilderBase.CommonAttributes.DEFAULT, updateBindings); 52 this.convertor = convertor; 53 this.convertorLocale = convertorLocale; 54 } 55 56 public void doLoad(Widget frmModel, JXPathContext jctx) throws BindingException { 57 Widget widget = frmModel.getWidget(this.multiValueId); 58 if (widget == null) { 59 throw new BindingException("The widget with the ID [" + this.multiValueId 60 + "] referenced in the binding does not exist in the form definition."); 61 } 62 63 Pointer ptr = jctx.getPointer(this.multiValuePath); 65 if (ptr.getNode() != null) { 66 68 JXPathContext multiValueContext = jctx.getRelativeContext(ptr); 69 Iterator rowPointers = multiValueContext.iterate(this.rowPath); 71 72 LinkedList list = new LinkedList (); 73 74 while (rowPointers.hasNext()) { 75 Object value = rowPointers.next(); 76 77 if (value != null && convertor != null) { 78 if (value instanceof String ) { 79 value = convertor.convertFromString((String )value, convertorLocale, null); 80 } else { 81 getLogger().warn("Convertor ignored on backend-value which isn't of type String."); 82 } 83 } 84 85 list.add(value); 86 } 87 88 widget.setValue(list.toArray()); 89 } 90 91 if (getLogger().isDebugEnabled()) 92 getLogger().debug("done loading values " + toString()); 93 } 94 95 public void doSave(Widget frmModel, JXPathContext jctx) throws BindingException { 96 Widget widget = frmModel.getWidget(this.multiValueId); 97 Object [] values = (Object [])widget.getValue(); 98 99 JXPathContext multiValueContext = jctx.getRelativeContext(jctx.createPath(this.multiValuePath)); 100 multiValueContext.removeAll(this.rowPath); 102 103 boolean update = false; 104 105 if (values != null) { 106 for (int i = 0; i < values.length; i++) { 108 String path = this.rowPath + '[' + (i+1) + ']'; 109 Pointer rowPtr = multiValueContext.createPath(path); 110 111 Object value = values[i]; 112 if (value != null && convertor != null) { 113 value = convertor.convertToString(value, convertorLocale, null); 114 } 115 116 rowPtr.setValue(value); 117 } 118 119 this.updateBinding.saveFormToModel(frmModel, multiValueContext); 121 122 update = true; 123 } 124 125 126 if (getLogger().isDebugEnabled()) { 127 getLogger().debug("done saving " + toString() + " -- on-update == " + update); 128 } 129 130 131 132 } 133 134 public String toString() { 135 return "MultiValueJXPathBinding [widget=" + this.multiValueId + ", xpath=" + this.multiValuePath + "]"; 136 } 137 138 public void enableLogging(Logger logger) { 139 super.enableLogging(logger); 140 this.updateBinding.enableLogging(logger); 141 } 142 } 143 | Popular Tags |