1 16 package org.apache.cocoon.forms.formmodel; 17 18 import java.util.ArrayList ; 19 import java.util.HashMap ; 20 import java.util.Iterator ; 21 import java.util.List ; 22 import java.util.Map ; 23 24 import org.apache.cocoon.forms.FormsConstants; 25 import org.apache.cocoon.forms.FormContext; 26 import org.apache.cocoon.forms.formmodel.AggregateFieldDefinition.SplitMapping; 27 import org.apache.cocoon.forms.util.I18nMessage; 28 import org.apache.cocoon.forms.validation.ValidationError; 29 import org.apache.excalibur.xml.sax.XMLizable; 30 import org.apache.oro.text.regex.MatchResult; 31 import org.apache.oro.text.regex.PatternMatcher; 32 import org.apache.oro.text.regex.Perl5Matcher; 33 import org.outerj.expression.ExpressionException; 34 35 54 public class AggregateField extends Field implements ContainerWidget { 55 56 private static final String AGGREGATEFIELD_EL = "aggregatefield"; 57 58 61 private List fields = new ArrayList (); 62 63 66 private Map fieldsById = new HashMap (); 67 68 69 public AggregateField(AggregateFieldDefinition definition) { 70 super(definition); 71 } 72 73 public final AggregateFieldDefinition getAggregateFieldDefinition() { 74 return (AggregateFieldDefinition)getDefinition(); 75 } 76 77 public void initialize() { 78 this.selectionList = getAggregateFieldDefinition().getSelectionList(); 79 } 80 81 public void addChild(Widget widget) { 82 if (!(widget instanceof Field)) { 83 throw new IllegalArgumentException ("AggregateField can only contain fields."); 84 } 85 addField((Field)widget); 86 } 87 88 protected void addField(Field field) { 89 field.setParent(this); 90 fields.add(field); 91 fieldsById.put(field.getId(), field); 92 } 93 94 95 public boolean hasChild(String id) { 96 return this.fieldsById.containsKey(id); 97 } 98 99 public Iterator getChildren() { 100 return fields.iterator(); 101 } 102 103 public void readFromRequest(FormContext formContext) { 104 if (!getCombinedState().isAcceptingInputs()) { 105 return; 106 } 107 108 String newEnteredValue = formContext.getRequest().getParameter(getRequestParameterName()); 109 if (newEnteredValue != null) { 110 super.readFromRequest(formContext); 112 if (this.valueState == VALUE_UNPARSED) { 113 setFieldsValues(enteredValue); 114 } 115 } else { 116 for (Iterator i = fields.iterator(); i.hasNext();) { 118 Field field = (Field)i.next(); 119 field.readFromRequest(formContext); 120 if (field.valueState == VALUE_UNPARSED) { 121 this.valueState = VALUE_UNPARSED; 122 } 123 } 124 if (this.valueState == VALUE_UNPARSED) { 125 combineFields(); 126 } 127 } 128 } 129 130 public void setValue(Object newValue) { 131 super.setValue(newValue); 132 if (this.valueState == VALUE_PARSED) { 133 setFieldsValues(enteredValue); 134 } 135 } 136 137 140 private boolean fieldsHaveValues() { 141 for (Iterator i = fields.iterator(); i.hasNext();) { 142 Field field = (Field)i.next(); 143 if (field.getValue() != null) { 144 return true; 145 } 146 } 147 return false; 148 } 149 150 154 private void setFieldsValues(String value) { 155 if (value == null) { 156 resetFieldsValues(); 157 } else { 158 PatternMatcher matcher = new Perl5Matcher(); 159 if (matcher.matches(value, getAggregateFieldDefinition().getSplitPattern())) { 160 MatchResult matchResult = matcher.getMatch(); 161 Iterator iterator = getAggregateFieldDefinition().getSplitMappingsIterator(); 162 while (iterator.hasNext()) { 163 SplitMapping splitMapping = (SplitMapping)iterator.next(); 164 String result = matchResult.group(splitMapping.getGroup()); 165 166 Field field = (Field)fieldsById.get(splitMapping.getFieldId()); 168 field.readFromRequest(result); 169 } 170 } else { 171 resetFieldsValues(); 172 } 173 } 174 } 175 176 public void combineFields() { 177 try { 178 Object value = getAggregateFieldDefinition().getCombineExpression().evaluate(new ExpressionContextImpl(this, true)); 179 super.setValue(value); 180 } catch (CannotYetResolveWarning e) { 181 super.setValue(null); 182 } catch (ExpressionException e) { 183 super.setValue(null); 184 } catch (ClassCastException e) { 185 super.setValue(null); 186 } 187 } 188 189 192 private void resetFieldsValues() { 193 for (Iterator i = fields.iterator(); i.hasNext();) { 194 Field field = (Field)i.next(); 195 field.setValue(null); 196 } 197 } 198 199 public boolean validate() { 200 if (!getCombinedState().isValidatingValues()) { 201 this.wasValid = true; 202 return true; 203 } 204 205 if (enteredValue != null && !fieldsHaveValues()) { 206 XMLizable failMessage = getAggregateFieldDefinition().getSplitFailMessage(); 207 if (failMessage != null) { 208 validationError = new ValidationError(failMessage); 209 } else { 210 validationError = new ValidationError(new I18nMessage("aggregatedfield.split-failed", 211 new String [] { getAggregateFieldDefinition().getSplitRegexp() }, 212 FormsConstants.I18N_CATALOGUE)); 213 } 214 valueState = VALUE_DISPLAY_VALIDATION; 215 this.wasValid = false; 216 return false; 217 } 218 219 boolean valid = true; 221 for (Iterator i = fields.iterator(); i.hasNext();) { 222 Field field = (Field)i.next(); 223 if (!field.validate()) { 224 validationError = field.getValidationError(); 225 valid = false; 226 } 227 } 228 if (!valid) { 229 valueState = VALUE_DISPLAY_VALIDATION; 230 this.wasValid = false; 231 return false; 232 } 233 234 return super.validate(); 235 } 236 237 240 public String getXMLElementName() { 241 return AGGREGATEFIELD_EL; 242 } 243 244 public Widget getChild(String id) { 245 return (Widget)fieldsById.get(id); 246 } 247 } 248 | Popular Tags |