1 16 package org.apache.cocoon.forms.binding; 17 18 import java.util.ArrayList ; 19 import java.util.Collections ; 20 import java.util.Iterator ; 21 import java.util.LinkedList ; 22 import java.util.List ; 23 import java.util.Locale ; 24 25 import org.apache.avalon.framework.logger.Logger; 26 import org.apache.cocoon.forms.datatype.convertor.Convertor; 27 import org.apache.cocoon.forms.datatype.convertor.ConversionResult; 28 import org.apache.cocoon.forms.formmodel.Widget; 29 import org.apache.commons.jxpath.JXPathContext; 30 import org.apache.commons.jxpath.Pointer; 31 32 38 public class MultiValueJXPathBinding extends JXPathBindingBase { 39 40 private final String multiValueId; 41 private final String multiValuePath; 42 private final String rowPath; 43 private final JXPathBindingBase updateBinding; 44 private final Convertor convertor; 45 private final Locale convertorLocale; 46 47 public MultiValueJXPathBinding( 48 JXPathBindingBuilderBase.CommonAttributes commonAtts, String multiValueId, 49 String multiValuePath, String rowPath, 50 JXPathBindingBase[] updateBindings, Convertor convertor, Locale convertorLocale) { 51 super(commonAtts); 52 this.multiValueId = multiValueId; 53 this.multiValuePath = multiValuePath; 54 this.rowPath = rowPath; 55 this.updateBinding = new ComposedJXPathBindingBase(JXPathBindingBuilderBase.CommonAttributes.DEFAULT, updateBindings); 56 this.convertor = convertor; 57 this.convertorLocale = convertorLocale; 58 } 59 60 public String getId() { return multiValueId; } 61 public String getMultiValuePath() { return multiValuePath; } 62 public String getRowPath() { return rowPath; } 63 public ComposedJXPathBindingBase getUpdateBinding() { return (ComposedJXPathBindingBase)updateBinding; } 64 public Convertor getConvertor() { return convertor; } 65 public Locale getLocale() { return convertorLocale; } 66 67 public void doLoad(Widget frmModel, JXPathContext jctx) throws BindingException { 68 Widget widget = selectWidget(frmModel,this.multiValueId); 69 if (widget == null) { 70 throw new BindingException("The widget with the ID [" + this.multiValueId 71 + "] referenced in the binding does not exist in the form definition."); 72 } 73 74 Pointer ptr = jctx.getPointer(this.multiValuePath); 76 if (ptr.getNode() != null) { 77 79 JXPathContext multiValueContext = jctx.getRelativeContext(ptr); 80 Iterator rowPointers = multiValueContext.iterate(this.rowPath); 82 83 LinkedList list = new LinkedList (); 84 85 while (rowPointers.hasNext()) { 86 Object value = rowPointers.next(); 87 88 if (value != null && convertor != null) { 89 if (value instanceof String ) { 90 ConversionResult conversionResult = convertor.convertFromString((String )value, convertorLocale, null); 91 if (conversionResult.isSuccessful()) 92 value = conversionResult.getResult(); 93 else 94 value = null; 95 } else { 96 getLogger().warn("Convertor ignored on backend-value which isn't of type String."); 97 } 98 } 99 100 list.add(value); 101 } 102 103 widget.setValue(list.toArray()); 104 } 105 106 if (getLogger().isDebugEnabled()) 107 getLogger().debug("done loading values " + toString()); 108 } 109 110 public void doSave(Widget frmModel, JXPathContext jctx) throws BindingException { 111 Widget widget = selectWidget(frmModel,this.multiValueId); 112 Object [] values = (Object [])widget.getValue(); 113 114 JXPathContext multiValueContext = jctx.getRelativeContext(jctx.createPath(this.multiValuePath)); 115 116 118 122 Iterator rowPointers = multiValueContext.iteratePointers(this.rowPath); 123 List l = new ArrayList (); 124 while( rowPointers.hasNext() ) 125 { 126 Pointer p = (Pointer)rowPointers.next(); 127 l.add(p.asPath()); 128 } 129 Collections.sort(l); 130 for( int i = l.size()-1; i >= 0; i-- ) 131 { 132 multiValueContext.removePath((String )l.get(i)); 133 } 134 135 boolean update = false; 136 137 if (values != null) { 138 for (int i = 0; i < values.length; i++) { 140 String path = this.rowPath + '[' + (i+1) + ']'; 141 Pointer rowPtr = multiValueContext.createPath(path); 142 143 Object value = values[i]; 144 if (value != null && convertor != null) { 145 value = convertor.convertToString(value, convertorLocale, null); 146 } 147 148 rowPtr.setValue(value); 149 } 150 151 this.updateBinding.saveFormToModel(frmModel, multiValueContext); 153 154 update = true; 155 } 156 157 158 if (getLogger().isDebugEnabled()) { 159 getLogger().debug("done saving " + toString() + " -- on-update == " + update); 160 } 161 162 163 164 } 165 166 public String toString() { 167 return "MultiValueJXPathBinding [widget=" + this.multiValueId + ", xpath=" + this.multiValuePath + "]"; 168 } 169 170 public void enableLogging(Logger logger) { 171 super.enableLogging(logger); 172 this.updateBinding.enableLogging(logger); 173 } 174 } 175 | Popular Tags |