1 16 package org.apache.cocoon.woody.formmodel; 17 18 import java.util.ArrayList ; 19 import java.util.Iterator ; 20 import java.util.List ; 21 import java.util.Locale ; 22 23 import org.apache.cocoon.woody.Constants; 24 import org.apache.cocoon.woody.FormContext; 25 import org.apache.cocoon.woody.event.WidgetEvent; 26 import org.apache.cocoon.xml.AttributesImpl; 27 import org.xml.sax.ContentHandler ; 28 import org.xml.sax.SAXException ; 29 30 43 public class Repeater extends AbstractWidget implements ContainerWidget { 44 private RepeaterDefinition repeaterDefinition; 45 private List rows = new ArrayList (); 46 47 public Repeater(RepeaterDefinition repeaterDefinition) { 48 this.repeaterDefinition = repeaterDefinition; 49 super.setDefinition(repeaterDefinition); 50 setLocation(definition.getLocation()); 51 removeRows(); 53 } 54 55 public String getId() { 56 return definition.getId(); 57 } 58 59 public int getSize() { 60 return rows.size(); 61 } 62 63 public void addWidget(Widget widget) { 64 throw new RuntimeException ("Repeater.addWidget(): Please use addRow() instead."); 65 } 66 67 public RepeaterRow addRow() { 68 RepeaterRow repeaterRow = new RepeaterRow(definition); 69 rows.add(repeaterRow); 70 return repeaterRow; 71 } 72 73 public RepeaterRow addRow(int index) { 74 RepeaterRow repeaterRow = new RepeaterRow(definition); 75 if (index >= this.rows.size()) { 76 rows.add(repeaterRow); 77 } else { 78 rows.add(index, repeaterRow); 79 } 80 return repeaterRow; 81 } 82 83 public RepeaterRow getRow(int index) { 84 return (RepeaterRow)rows.get(index); 85 } 86 87 93 public static RepeaterRow getParentRow(Widget widget) { 94 Widget result = widget; 95 while(result != null && ! (result instanceof Repeater.RepeaterRow)) { 96 result = result.getParent(); 97 } 98 99 if (result == null) { 100 throw new RuntimeException ("Could not find a parent row for widget " + widget); 101 102 } else { 103 return (Repeater.RepeaterRow)result; 104 } 105 } 106 107 112 public int indexOf(RepeaterRow row) { 113 return this.rows.indexOf(row); 114 } 115 116 119 public void removeRow(int index) { 120 rows.remove(index); 121 } 122 123 public void moveRowLeft(int index) { 124 if (index == 0 || index >= this.rows.size()) { 125 } else { 127 Object temp = this.rows.get(index-1); 128 this.rows.set(index-1, this.rows.get(index)); 129 this.rows.set(index, temp); 130 } 131 } 132 133 public void moveRowRight(int index) { 134 if (index < 0 || index >= this.rows.size() - 1) { 135 } else { 137 Object temp = this.rows.get(index+1); 138 this.rows.set(index+1, this.rows.get(index)); 139 this.rows.set(index, temp); 140 } 141 } 142 143 146 public void removeRows() { 147 rows.clear(); 148 149 for (int i = 0; i < this.repeaterDefinition.getInitialSize(); i++) { 151 addRow(); 152 } 153 } 154 155 161 public Widget getWidget(int rowIndex, String id) { 162 RepeaterRow row = (RepeaterRow)rows.get(rowIndex); 163 return row.getWidget(id); 164 } 165 166 public boolean hasWidget(String id) { 167 int row; 168 try { 169 row = Integer.parseInt(id); 170 } catch (NumberFormatException e) { 171 throw new RuntimeException ("Repeater: Row id is not a valid integer: " + id); 173 } 174 return row >= 0 && row < rows.size(); 175 } 176 177 public Widget getWidget(String id) { 178 int row; 179 try { 180 row = Integer.parseInt(id); 181 } catch (NumberFormatException e) { 182 throw new RuntimeException ("Repeater: Row id is not a valid integer: " + id); 184 } 185 return (RepeaterRow)rows.get(row); 186 } 187 188 public void readFromRequest(FormContext formContext) { 189 String sizeParameter = formContext.getRequest().getParameter(getFullyQualifiedId() + ".size"); 191 if (sizeParameter != null) { 192 int size = 0; 193 try { 194 size = Integer.parseInt(sizeParameter); 195 } catch (NumberFormatException exc) { 196 } 198 199 if (size > 500) 202 throw new RuntimeException ("Client is not allowed to specify a repeater size larger than 500."); 203 204 int currentSize = getSize(); 205 if (currentSize < size) { 206 for (int i = currentSize; i < size; i++) { 207 addRow(); 208 } 209 } else if (currentSize > size) { 210 for (int i = currentSize - 1; i >= size; i--) { 211 removeRow(i); 212 } 213 } 214 } 215 216 Iterator rowIt = rows.iterator(); 218 while (rowIt.hasNext()) { 219 RepeaterRow row = (RepeaterRow)rowIt.next(); 220 row.readFromRequest(formContext); 221 } 222 } 223 224 public boolean validate(FormContext formContext) { 225 boolean valid = true; 226 Iterator rowIt = rows.iterator(); 227 while (rowIt.hasNext()) { 228 RepeaterRow row = (RepeaterRow)rowIt.next(); 229 valid = valid & row.validate(formContext); 230 } 231 return valid ? super.validate(formContext) : false; 232 } 233 234 private static final String REPEATER_EL = "repeater"; 235 private static final String HEADINGS_EL = "headings"; 236 private static final String HEADING_EL = "heading"; 237 private static final String LABEL_EL = "label"; 238 private static final String REPEATER_SIZE_EL = "repeater-size"; 239 240 public void generateSaxFragment(ContentHandler contentHandler, Locale locale) throws SAXException { 241 AttributesImpl repeaterAttrs = new AttributesImpl(); 242 repeaterAttrs.addCDATAAttribute("id", getFullyQualifiedId()); 243 repeaterAttrs.addCDATAAttribute("size", String.valueOf(getSize())); 244 contentHandler.startElement(Constants.WI_NS, REPEATER_EL, Constants.WI_PREFIX_COLON + REPEATER_EL, repeaterAttrs); 245 246 contentHandler.startElement(Constants.WI_NS, LABEL_EL, Constants.WI_PREFIX_COLON + LABEL_EL, Constants.EMPTY_ATTRS); 248 definition.generateLabel(contentHandler); 249 contentHandler.endElement(Constants.WI_NS, LABEL_EL, Constants.WI_PREFIX_COLON + LABEL_EL); 250 251 contentHandler.startElement(Constants.WI_NS, HEADINGS_EL, Constants.WI_PREFIX_COLON + HEADINGS_EL, Constants.EMPTY_ATTRS); 253 Iterator widgetDefinitionIt = repeaterDefinition.getWidgetDefinitions().iterator(); 254 while (widgetDefinitionIt.hasNext()) { 255 WidgetDefinition widgetDefinition = (WidgetDefinition)widgetDefinitionIt.next(); 256 contentHandler.startElement(Constants.WI_NS, HEADING_EL, Constants.WI_PREFIX_COLON + HEADING_EL, Constants.EMPTY_ATTRS); 257 widgetDefinition.generateLabel(contentHandler); 258 contentHandler.endElement(Constants.WI_NS, HEADING_EL, Constants.WI_PREFIX_COLON + HEADING_EL); 259 } 260 contentHandler.endElement(Constants.WI_NS, HEADINGS_EL, Constants.WI_PREFIX_COLON + HEADINGS_EL); 261 262 Iterator rowIt = rows.iterator(); 264 while (rowIt.hasNext()) { 265 RepeaterRow row = (RepeaterRow)rowIt.next(); 266 row.generateSaxFragment(contentHandler, locale); 267 } 268 contentHandler.endElement(Constants.WI_NS, REPEATER_EL, Constants.WI_PREFIX_COLON + REPEATER_EL); 269 } 270 271 public void generateLabel(ContentHandler contentHandler) throws SAXException { 272 definition.generateLabel(contentHandler); 273 } 274 275 278 public void generateWidgetLabel(String widgetId, ContentHandler contentHandler) throws SAXException { 279 WidgetDefinition widgetDefinition = repeaterDefinition.getWidgetDefinition(widgetId); 280 if (widgetDefinition == null) 281 throw new SAXException ("Repeater \"" + getFullyQualifiedId() + "\" contains no widget with id \"" + widgetId + "\"."); 282 widgetDefinition.generateLabel(contentHandler); 283 } 284 285 288 public void generateSize(ContentHandler contentHandler) throws SAXException { 289 AttributesImpl attrs = new AttributesImpl(); 290 attrs.addCDATAAttribute("id", getFullyQualifiedId()); 291 attrs.addCDATAAttribute("size", String.valueOf(getSize())); 292 contentHandler.startElement(Constants.WI_NS, REPEATER_SIZE_EL, Constants.WI_PREFIX_COLON + REPEATER_SIZE_EL, attrs); 293 contentHandler.endElement(Constants.WI_NS, REPEATER_SIZE_EL, Constants.WI_PREFIX_COLON + REPEATER_SIZE_EL); 294 } 295 296 public class RepeaterRow extends AbstractContainerWidget { 297 298 public RepeaterRow(AbstractWidgetDefinition definition) { 299 super(definition); 300 ((ContainerDefinition)definition).createWidgets(this); 301 } 302 303 public String getLocation() { 304 return Repeater.this.getLocation(); 305 } 306 307 public String getId() { 308 return String.valueOf(rows.indexOf(this)); 310 } 311 312 public Widget getParent() { 313 return Repeater.this; 314 } 315 316 public Form getForm() { 317 return Repeater.this.getForm(); 318 } 319 320 public String getNamespace() { 321 return getParent().getNamespace() + "." + getId(); 322 } 323 324 public String getFullyQualifiedId() { 325 return getParent().getNamespace() + "." + getId(); 326 } 327 328 public void setParent(Widget widget) { 329 throw new RuntimeException ("Parent of RepeaterRow is fixed, and cannot be set."); 330 } 331 332 public boolean validate(FormContext formContext) { 333 return widgets.validate(formContext); 335 } 336 337 private static final String ROW_EL = "repeater-row"; 338 339 public void generateLabel(ContentHandler contentHandler) throws SAXException { 340 } 342 343 public void generateSaxFragment(ContentHandler contentHandler, Locale locale) throws SAXException { 344 AttributesImpl rowAttrs = new AttributesImpl(); 345 rowAttrs.addCDATAAttribute("id", getFullyQualifiedId()); 346 contentHandler.startElement(Constants.WI_NS, ROW_EL, Constants.WI_PREFIX_COLON + ROW_EL, rowAttrs); 347 Iterator widgetIt = widgets.iterator(); 348 while (widgetIt.hasNext()) { 349 Widget widget = (Widget)widgetIt.next(); 350 widget.generateSaxFragment(contentHandler, locale); 351 } 352 contentHandler.endElement(Constants.WI_NS, ROW_EL, Constants.WI_PREFIX_COLON + ROW_EL); 353 } 354 355 public void broadcastEvent(WidgetEvent event) { 356 throw new UnsupportedOperationException ("Widget " + this.getFullyQualifiedId() + " doesn't handle events."); 357 } 358 } 359 360 363 public Iterator getChildren() { 364 return null; 366 } 367 368 369 } 370 | Popular Tags |