1 16 package org.apache.cocoon.forms.formmodel; 17 18 import java.lang.reflect.Array ; 19 import java.util.Locale ; 20 21 import org.apache.cocoon.forms.FormsConstants; 22 import org.apache.cocoon.forms.FormContext; 23 import org.apache.cocoon.forms.datatype.Datatype; 24 import org.apache.cocoon.forms.datatype.SelectionList; 25 import org.apache.cocoon.forms.datatype.convertor.ConversionResult; 26 import org.apache.cocoon.forms.datatype.convertor.Convertor; 27 import org.apache.cocoon.forms.event.ValueChangedEvent; 28 import org.apache.cocoon.forms.event.WidgetEvent; 29 import org.apache.cocoon.forms.util.I18nMessage; 30 import org.apache.cocoon.forms.validation.ValidationError; 31 import org.apache.cocoon.forms.validation.ValidationErrorAware; 32 import org.apache.cocoon.xml.XMLUtils; 33 import org.xml.sax.ContentHandler ; 34 import org.xml.sax.SAXException ; 35 36 53 public class MultiValueField extends AbstractWidget 54 implements ValidationErrorAware, SelectableWidget, DataWidget { 55 56 private static final String MULTIVALUEFIELD_EL = "multivaluefield"; 57 private static final String VALUES_EL = "values"; 58 private static final String VALUE_EL = "value"; 59 private static final String VALIDATION_MSG_EL = "validation-message"; 60 61 private final MultiValueFieldDefinition definition; 62 63 private SelectionList selectionList; 64 private String [] enteredValues; 65 private String invalidEnteredValue; 66 private Object [] values; 67 private ValidationError validationError; 68 69 public MultiValueField(MultiValueFieldDefinition definition) { 70 super(definition); 71 this.definition = definition; 72 } 73 74 public void initialize() { 75 this.selectionList = this.definition.getSelectionList(); 76 super.initialize(); 77 } 78 79 public WidgetDefinition getDefinition() { 80 return definition; 81 } 82 83 public void readFromRequest(FormContext formContext) { 84 if (!getCombinedState().isAcceptingInputs()) 85 return; 86 87 enteredValues = formContext.getRequest().getParameterValues(getRequestParameterName()); 88 invalidEnteredValue = null; 89 validationError = null; 90 values = null; 91 92 boolean conversionFailed = false; 93 if (enteredValues != null) { 94 Object [] tempValues = (Object [])Array.newInstance(getDatatype().getTypeClass(), enteredValues.length); 95 for (int i = 0; i < enteredValues.length; i++) { 96 String param = enteredValues[i]; 97 ConversionResult conversionResult = definition.getDatatype().convertFromString(param, formContext.getLocale()); 98 if (conversionResult.isSuccessful()) { 99 tempValues[i] = conversionResult.getResult(); 100 } else { 101 conversionFailed = true; 102 invalidEnteredValue = param; 103 break; 104 } 105 } 106 107 if (!conversionFailed) 108 values = tempValues; 109 else 110 values = null; 111 } else { 112 values = new Object [0]; 113 } 114 } 115 116 public boolean validate() { 117 if (!getCombinedState().isValidatingValues()) { 118 this.wasValid = true; 119 return true; 120 } 121 122 if (values != null) { 123 validationError = definition.getDatatype().validate(values, new ExpressionContextImpl(this)); 124 } else if (invalidEnteredValue != null) { 125 validationError = new ValidationError(new I18nMessage("multivaluefield.conversionfailed", new String [] {invalidEnteredValue}, FormsConstants.I18N_CATALOGUE)); 126 } 127 128 this.wasValid = validationError == null ? super.validate() : false; 129 return this.wasValid; 130 } 131 132 135 public String getXMLElementName() { 136 return MULTIVALUEFIELD_EL; 137 } 138 139 public void generateItemSaxFragment(ContentHandler contentHandler, Locale locale) throws SAXException { 140 contentHandler.startElement(FormsConstants.INSTANCE_NS, VALUES_EL, FormsConstants.INSTANCE_PREFIX_COLON + VALUES_EL, XMLUtils.EMPTY_ATTRIBUTES); 141 Convertor convertor = definition.getDatatype().getConvertor(); 142 if (values != null) { 143 for (int i = 0; i < values.length; i++) { 144 contentHandler.startElement(FormsConstants.INSTANCE_NS, VALUE_EL, FormsConstants.INSTANCE_PREFIX_COLON + VALUE_EL, XMLUtils.EMPTY_ATTRIBUTES); 145 String value = convertor.convertToString(values[i], locale, null); 146 contentHandler.characters(value.toCharArray(), 0, value.length()); 147 contentHandler.endElement(FormsConstants.INSTANCE_NS, VALUE_EL, FormsConstants.INSTANCE_PREFIX_COLON + VALUE_EL); 148 } 149 } else if (enteredValues != null) { 150 for (int i = 0; i < enteredValues.length; i++) { 151 contentHandler.startElement(FormsConstants.INSTANCE_NS, VALUE_EL, FormsConstants.INSTANCE_PREFIX_COLON + VALUE_EL, XMLUtils.EMPTY_ATTRIBUTES); 152 String value = enteredValues[i]; 153 contentHandler.characters(value.toCharArray(), 0, value.length()); 154 contentHandler.endElement(FormsConstants.INSTANCE_NS, VALUE_EL, FormsConstants.INSTANCE_PREFIX_COLON + VALUE_EL); 155 } 156 } 157 contentHandler.endElement(FormsConstants.INSTANCE_NS, VALUES_EL, FormsConstants.INSTANCE_PREFIX_COLON + VALUES_EL); 158 159 if (this.selectionList != null) 161 this.selectionList.generateSaxFragment(contentHandler, locale); 162 163 if (validationError != null) { 165 contentHandler.startElement(FormsConstants.INSTANCE_NS, VALIDATION_MSG_EL, FormsConstants.INSTANCE_PREFIX_COLON + VALIDATION_MSG_EL, XMLUtils.EMPTY_ATTRIBUTES); 166 validationError.generateSaxFragment(contentHandler); 167 contentHandler.endElement(FormsConstants.INSTANCE_NS, VALIDATION_MSG_EL, FormsConstants.INSTANCE_PREFIX_COLON + VALIDATION_MSG_EL); 168 } 169 } 170 171 172 public Object getValue() { 173 return values; 174 } 175 176 public void setValue(Object value) { 177 if (value == null) { 178 setValues(new Object [0]); 179 } else if (value.getClass().isArray()) { 180 setValues((Object [])value); 181 } else { 182 throw new RuntimeException ("Cannot set value of field \"" + getRequestParameterName() + "\" with an object of type " + value.getClass().getName()); 183 } 184 getForm().addWidgetUpdate(this); 185 } 186 187 public void setValues(Object [] values) { 188 for (int i = 0; i < values.length; i++) { 190 if (!definition.getDatatype().getTypeClass().isAssignableFrom(values[i].getClass())) 191 throw new RuntimeException ("Cannot set value of field \"" + getRequestParameterName() + "\" with an object of type " + values[i].getClass().getName()); 192 } 193 this.values = values; 194 getForm().addWidgetUpdate(this); 195 } 196 197 201 public void setSelectionList(SelectionList selectionList) { 202 if (selectionList == null) { 203 throw new IllegalArgumentException ("An MultiValueField's selection list cannot be null."); 204 } 205 206 if (selectionList.getDatatype() != null && 207 selectionList.getDatatype() != definition.getDatatype()) { 208 209 throw new RuntimeException ("Tried to assign a SelectionList that is not associated with this widget's datatype."); 210 } 211 this.selectionList = selectionList; 212 getForm().addWidgetUpdate(this); 213 } 214 215 224 public void setSelectionList(String uri) { 225 setSelectionList(this.definition.buildSelectionList(uri)); 226 } 227 228 244 public void setSelectionList(Object model, String valuePath, String labelPath) { 245 setSelectionList(this.definition.buildSelectionListFromModel(model, valuePath, labelPath)); 246 } 247 248 public void broadcastEvent(WidgetEvent event) { 249 if (event instanceof ValueChangedEvent) { 250 this.definition.fireValueChangedEvent((ValueChangedEvent)event); 251 } else { 252 super.broadcastEvent(event); 254 } 255 } 256 257 public ValidationError getValidationError() { 258 return this.validationError; 259 } 260 261 public void setValidationError(ValidationError error) { 262 this.validationError = error; 263 getForm().addWidgetUpdate(this); 264 } 265 266 public Datatype getDatatype() { 267 return definition.getDatatype(); 268 } 269 } 270 | Popular Tags |