1 16 package org.apache.cocoon.forms.util; 17 18 import java.util.Iterator ; 19 import java.util.Locale ; 20 21 import org.apache.cocoon.xml.AbstractXMLConsumer; 22 import org.apache.cocoon.forms.datatype.Datatype; 23 import org.apache.cocoon.forms.datatype.convertor.ConversionResult; 24 import org.apache.cocoon.forms.formmodel.Action; 25 import org.apache.cocoon.forms.formmodel.AggregateField; 26 import org.apache.cocoon.forms.formmodel.BooleanField; 27 import org.apache.cocoon.forms.formmodel.ContainerWidget; 28 import org.apache.cocoon.forms.formmodel.DataWidget; 29 import org.apache.cocoon.forms.formmodel.Form; 30 import org.apache.cocoon.forms.formmodel.MultiValueField; 31 import org.apache.cocoon.forms.formmodel.Repeater; 32 import org.apache.cocoon.forms.formmodel.Widget; 33 import org.apache.excalibur.xml.sax.XMLizable; 34 import org.xml.sax.Attributes ; 35 import org.xml.sax.ContentHandler ; 36 import org.xml.sax.SAXException ; 37 import org.xml.sax.helpers.AttributesImpl ; 38 39 61 public class XMLAdapter extends AbstractXMLConsumer implements XMLizable { 62 63 64 private final static String ITEM = "item"; 65 66 private final static String UNKNOWN = "unknown"; 67 68 private final static String POSITION = "position"; 69 70 private final static String PREFIX = ""; 71 72 private final static String URI = ""; 73 74 private ContentHandler contentHandler; 75 76 private Widget widget; 77 78 private Widget currentWidget = null; 79 80 private Locale locale; 81 82 private boolean isMultiValueItem = false; 83 84 private StringBuffer textBuffer; 85 86 87 91 public XMLAdapter(Widget widget) { 92 this.widget = widget; 93 this.locale = Locale.US; 94 } 95 96 99 public void setLocale(Locale locale) { 100 this.locale = locale; 101 } 102 103 106 public Locale getLocale() { 107 return this.locale; 108 } 109 110 111 112 122 123 136 public void startElement(String uri, String loc, String raw, Attributes a) 137 throws SAXException { 138 handleText(); 139 if (this.currentWidget == null) { 140 this.currentWidget = this.widget; 142 return; 143 } else if (this.currentWidget instanceof ContainerWidget) { 144 Widget child = ((ContainerWidget)this.currentWidget).getChild(loc); 145 if (child != null) 146 this.currentWidget = child; 147 else 148 throw new SAXException ("There is no widget with id: " + loc + 149 " as child to: " + this.currentWidget.getId()); 150 } else if (this.currentWidget instanceof Repeater) { 151 if (ITEM.equals(loc)) { 154 Repeater repeater = (Repeater)currentWidget; 155 currentWidget = repeater.addRow(); 156 } else 157 throw new SAXException ("The element: " + loc + 158 " is not allowed as a direct child of a Repeater"); 159 } else if (this.currentWidget instanceof MultiValueField) { 160 this.isMultiValueItem = true; 161 if (!ITEM.equals(loc)) 162 throw new SAXException ("The element: " + loc + 163 " is not allowed as a direct child of a MultiValueField"); 164 } 165 } 166 167 168 179 public void endElement(String uri, String loc, String raw) 180 throws SAXException { 181 handleText(); 182 if (this.currentWidget == null) 183 throw new SAXException ("Wrong state"); 184 185 String id = this.currentWidget.getId(); 186 187 if (this.currentWidget instanceof Form) { 188 this.currentWidget = null; 189 return; 190 } else if (this.currentWidget instanceof AggregateField) { 191 ((AggregateField)this.currentWidget).combineFields(); 192 } else if (this.currentWidget instanceof Repeater.RepeaterRow) { 193 id = ITEM; 194 } else if (this.currentWidget instanceof MultiValueField && loc.equals(ITEM)) { 195 this.isMultiValueItem = false; 196 return; 197 } 198 199 if (loc.equals(id)) 200 this.currentWidget = this.currentWidget.getParent(); 201 else 202 throw new SAXException ("Unexpected element, was: " + loc + 203 " expected: " + id); 204 } 205 206 213 public void characters(char ch[], int start, int len) 214 throws SAXException { 215 if (this.textBuffer == null) { 217 this.textBuffer = new StringBuffer (); 218 } 219 this.textBuffer.append(ch, start, len); 220 } 221 222 228 private void handleText() throws SAXException { 229 if (this.textBuffer == null) 230 return; 231 232 String input = this.textBuffer.toString().trim(); 233 this.textBuffer = null; if (input.length() == 0) 235 return; 236 237 if (this.currentWidget instanceof MultiValueField && isMultiValueItem) { 238 MultiValueField field = (MultiValueField)this.currentWidget; 239 Datatype type = field.getDatatype(); 240 ConversionResult conv = 241 type.convertFromString(input, this.locale); 242 if (conv.isSuccessful()) { 243 Object [] values = (Object [])field.getValue(); 244 int valLen = values == null ? 0 : values.length; 245 Object [] newValues = new Object [valLen + 1]; 246 for (int i = 0; i < valLen; i++) 247 newValues[i] = values[i]; 248 newValues[valLen] = conv.getResult(); 249 field.setValues(newValues); 250 } else 251 throw new SAXException ("Could not convert: " + input + 252 " to " + type.getTypeClass()); 253 } else if (this.currentWidget instanceof DataWidget) { 254 DataWidget data = (DataWidget)this.currentWidget; 255 Datatype type = data.getDatatype(); 256 ConversionResult conv = 257 type.convertFromString(input, this.locale); 258 if (conv.isSuccessful()) { 259 data.setValue(conv.getResult()); 260 } else 261 throw new SAXException ("Could not convert: " + input + 262 " to " + type.getTypeClass()); 263 } else if (this.currentWidget instanceof BooleanField) { 264 if ("true".equals(input)) 267 this.currentWidget.setValue(Boolean.TRUE); 268 else if ("false".equals(input)) 269 this.currentWidget.setValue(Boolean.FALSE); 270 else 271 throw new SAXException ("Unkown boolean: " + input); 272 } else { 273 throw new SAXException ("Unknown widget type: " + this.currentWidget); 274 } 275 } 276 277 278 279 280 284 285 288 public void toSAX( ContentHandler handler ) throws SAXException { 289 this.contentHandler = handler; 290 291 this.contentHandler.startDocument(); 292 this.contentHandler.startPrefixMapping(PREFIX, URI); 293 294 generateSAX(this.widget); 295 296 this.contentHandler.endPrefixMapping(PREFIX); 297 this.contentHandler.endDocument(); 298 } 299 300 303 private void generateSAX(Widget widget) 304 throws SAXException { 305 generateSAX(widget, null); 306 } 307 308 private void generateSAX(Widget widget, String id) 309 throws SAXException { 310 311 if (widget instanceof Action) 313 return; 314 315 if (id == null) 316 id = widget.getId() == "" ? UNKNOWN : widget.getId(); 317 318 final AttributesImpl attr = new AttributesImpl (); 319 if (widget instanceof Repeater.RepeaterRow) 320 attribute(attr, POSITION, widget.getId()); 321 322 start(id, attr); 323 if (widget instanceof MultiValueField) { 326 Datatype datatype = ((MultiValueField)widget).getDatatype(); 327 Object [] values = (Object [])widget.getValue(); 328 if (values != null) 329 for (int i = 0; i < values.length; i++) { 330 start(ITEM, attr); 331 data(datatype.convertToString(values[i], this.locale)); 332 end(ITEM); 333 } 334 } else if (widget instanceof DataWidget) { 335 Datatype datatype = ((DataWidget)widget).getDatatype(); 336 if (widget.getValue() != null) 337 data(datatype.convertToString(widget.getValue(), this.locale)); 338 } else if (widget instanceof BooleanField) { 339 if (widget.getValue() != null) { 342 data(widget.getValue().toString()); 343 } 344 } else if (widget instanceof ContainerWidget) { 345 Iterator children = ((ContainerWidget)widget).getChildren(); 346 while (children.hasNext()) 347 generateSAX((Widget)children.next()); 348 } else if (widget instanceof Repeater) { 349 Repeater repeater = (Repeater)widget; 350 for (int i = 0; i < repeater.getSize(); i++) 351 generateSAX(repeater.getRow(i), ITEM); 352 } 353 end(id); 354 } 355 356 private void attribute(AttributesImpl attr, String name, String value) { 357 attr.addAttribute("", name, name, "CDATA", value); 358 } 359 360 private void start(String name, AttributesImpl attr) 361 throws SAXException { 362 String qName = PREFIX == "" ? name : PREFIX + ":" + name; 363 this.contentHandler.startElement(URI, name, qName, attr); 364 attr.clear(); 365 } 366 367 private void end(String name) 368 throws SAXException { 369 String qName = PREFIX == "" ? name : PREFIX + ":" + name; 370 this.contentHandler.endElement(URI, name, qName); 371 } 372 373 private void data(String data) 374 throws SAXException { 375 this.contentHandler.characters(data.toCharArray(), 0, data.length()); 376 } 377 } 378 | Popular Tags |