1 16 package org.apache.cocoon.forms.transformation; 17 18 import org.apache.avalon.excalibur.pool.Recyclable; 19 20 import org.apache.cocoon.forms.FormsConstants; 21 import org.apache.cocoon.forms.formmodel.AggregateField; 22 import org.apache.cocoon.forms.formmodel.DataWidget; 23 import org.apache.cocoon.forms.formmodel.Group; 24 import org.apache.cocoon.forms.formmodel.Repeater; 25 import org.apache.cocoon.forms.formmodel.Struct; 26 import org.apache.cocoon.forms.formmodel.Union; 27 import org.apache.cocoon.forms.formmodel.Widget; 28 import org.apache.cocoon.forms.validation.ValidationError; 29 import org.apache.cocoon.forms.validation.ValidationErrorAware; 30 import org.apache.cocoon.i18n.I18nUtils; 31 import org.apache.cocoon.xml.AbstractXMLPipe; 32 import org.apache.cocoon.xml.SaxBuffer; 33 import org.apache.cocoon.xml.XMLUtils; 34 35 import org.apache.commons.jxpath.JXPathException; 36 import org.xml.sax.Attributes ; 37 import org.xml.sax.ContentHandler ; 38 import org.xml.sax.SAXException ; 39 import org.xml.sax.ext.LexicalHandler ; 40 import org.xml.sax.helpers.AttributesImpl ; 41 42 import java.util.ArrayList ; 43 import java.util.HashMap ; 44 import java.util.LinkedList ; 45 import java.util.List ; 46 import java.util.Locale ; 47 import java.util.Map ; 48 49 64 public class EffectWidgetReplacingPipe extends EffectPipe { 65 66 72 private static final String LOCATION = "location"; 73 74 private static final String AGGREGATE_WIDGET = "aggregate-widget"; 75 private static final String CHOOSE = "choose"; 76 private static final String CLASS = "class"; 77 private static final String CONTINUATION_ID = "continuation-id"; 78 private static final String FORM_TEMPLATE_EL = "form-template"; 79 private static final String GROUP = "group"; 80 private static final String NEW = "new"; 81 private static final String REPEATER = "repeater"; 82 private static final String REPEATER_ROWS = "repeater-rows"; 83 private static final String REPEATER_SIZE = "repeater-size"; 84 private static final String REPEATER_WIDGET = "repeater-widget"; 85 private static final String REPEATER_WIDGET_LABEL = "repeater-widget-label"; 86 private static final String STRUCT = "struct"; 87 private static final String STYLING_EL = "styling"; 88 private static final String UNION = "union"; 89 private static final String VALIDATION_ERROR = "validation-error"; 90 private static final String WIDGET = "widget"; 91 private static final String WIDGET_LABEL = "widget-label"; 92 93 private final AggregateWidgetHandler hAggregate = new AggregateWidgetHandler(); 94 private final ChooseHandler hChoose = new ChooseHandler(); 95 private final ChoosePassThruHandler hChoosePassThru = new ChoosePassThruHandler(); 96 private final ClassHandler hClass = new ClassHandler(); 97 private final ContinuationIdHandler hContinuationId = new ContinuationIdHandler(); 98 private final DocHandler hDocument = new DocHandler(); 99 private final FormHandler hForm = new FormHandler(); 100 private final GroupHandler hGroup = new GroupHandler(); 101 private final NestedHandler hNested = new NestedHandler(); 102 private final NewHandler hNew = new NewHandler(); 103 private final RepeaterSizeHandler hRepeaterSize = new RepeaterSizeHandler(); 104 private final RepeaterHandler hRepeater = new RepeaterHandler(); 105 private final RepeaterRowsHandler hRepeaterRows = new RepeaterRowsHandler(); 106 private final RepeaterWidgetHandler hRepeaterWidget = new RepeaterWidgetHandler(); 107 private final RepeaterWidgetLabelHandler hRepeaterWidgetLabel = new RepeaterWidgetLabelHandler(); 108 private final SkipHandler hSkip = new SkipHandler(); 109 private final StructHandler hStruct = new StructHandler(); 110 private final StylingContentHandler hStyling = new StylingContentHandler(); 111 private final UnionHandler hUnion = new UnionHandler(); 112 private final UnionPassThruHandler hUnionPassThru = new UnionPassThruHandler(); 113 private final ValidationErrorHandler hValidationError = new ValidationErrorHandler(); 114 private final WidgetHandler hWidget = new WidgetHandler(); 115 private final WidgetLabelHandler hWidgetLabel = new WidgetLabelHandler(); 116 117 120 protected final Map templates; 121 122 protected FormsPipelineConfig pipeContext; 123 124 127 private final List namespaces; 128 129 133 private boolean hasInstanceNamespace; 134 135 protected Widget contextWidget; 136 protected LinkedList contextWidgets; 137 protected LinkedList chooseWidgets; 138 protected Widget widget; 139 protected Map classes; 140 141 142 public EffectWidgetReplacingPipe() { 143 namespaces = new ArrayList (5); 144 templates = new HashMap (); 146 templates.put(AGGREGATE_WIDGET, hAggregate); 147 templates.put(CHOOSE, hChoose); 148 templates.put(CLASS, hClass); 149 templates.put(CONTINUATION_ID, hContinuationId); 150 templates.put(GROUP, hGroup); 151 templates.put(NEW, hNew); 152 templates.put(REPEATER, hRepeater); 153 templates.put(REPEATER_ROWS, hRepeaterRows); 154 templates.put(REPEATER_SIZE, hRepeaterSize); 155 templates.put(REPEATER_WIDGET, hRepeaterWidget); 156 templates.put(REPEATER_WIDGET_LABEL, hRepeaterWidgetLabel); 157 templates.put(STRUCT, hStruct); 158 templates.put(UNION, hUnion); 159 templates.put(VALIDATION_ERROR, hValidationError); 160 templates.put(WIDGET, hWidget); 161 templates.put(WIDGET_LABEL, hWidgetLabel); 162 } 163 164 public void init(Widget contextWidget, FormsPipelineConfig pipeContext) { 165 super.init(hDocument); 167 this.pipeContext = pipeContext; 168 169 this.contextWidgets = new LinkedList (); 171 this.chooseWidgets = new LinkedList (); 172 this.classes = new HashMap (); 173 } 174 175 public void recycle() { 176 super.recycle(); 177 this.contextWidget = null; 178 this.widget = null; 179 this.pipeContext = null; 180 this.namespaces.clear(); 181 this.hasInstanceNamespace = false; 182 } 183 184 187 protected String getAttributeValue(String loc, Attributes attrs, String name) throws SAXException { 188 String value = attrs.getValue(name); 189 if (value == null) { 190 throw new SAXException ("Element '" + loc + "' missing required '" + name + "' attribute, " + 191 "at " + getLocation()); 192 } 193 return value; 194 } 195 196 199 protected String getRequiredAttributeValue(String loc, Attributes attrs, String name) throws SAXException { 200 String value = attrs.getValue(name); 201 if (value == null || value.equals("")) { 202 throw new SAXException ("Element '" + loc + "' missing required '" + name + "' attribute, " + 203 "at " + getLocation()); 204 } 205 return value; 206 } 207 208 211 protected void setWidget(String loc, Attributes attrs) throws SAXException { 212 setWidget(loc, getRequiredAttributeValue(loc, attrs, "id")); 213 } 214 215 218 protected void setWidget(String loc, String path) throws SAXException { 219 widget = contextWidget.lookupWidget(path); 220 if (widget == null) { 221 if (contextWidget.getRequestParameterName().equals("")) { 222 throw new SAXException ("Element '" + loc + "' refers to unexistent widget path '" + path + "', " + 223 "relative to the form container, at " + getLocation()); 224 } else { 225 throw new SAXException ("Element '" + loc + "' refers to unexistent widget path '" + path + "', " + 226 "relative to the '" + contextWidget.getRequestParameterName() + "', " + 227 "at " + getLocation()); 228 } 229 } 230 } 231 232 235 protected void setTypedWidget(String loc, Attributes attrs, Class wclass, String wname) throws SAXException { 236 setWidget(loc, attrs); 237 if (!wclass.isInstance(widget)) { 238 throw new SAXException ("Element '" + loc + "' can only be used with " + wname + " widgets, " + 239 "at " + getLocation()); 240 } 241 } 242 243 protected boolean isVisible(Widget widget) { 244 return widget.getCombinedState().isDisplayingValues(); 245 } 246 247 251 private ContentHandler getContentHandler() { 252 return this.contentHandler; 253 } 254 255 259 private LexicalHandler getLexicalHandler() { 260 return this.lexicalHandler; 261 } 262 263 264 268 public void startPrefixMapping(String prefix, String uri) 269 throws SAXException { 270 if (prefix != null) { 271 this.namespaces.add(new String [] {prefix, uri}); 272 } 273 274 if (!FormsConstants.TEMPLATE_NS.equals(uri)) { 276 super.startPrefixMapping(prefix, uri); 277 } 278 } 279 280 284 public void endPrefixMapping(String prefix) 285 throws SAXException { 286 String uri = null; 287 288 if (prefix != null) { 289 boolean found = false; 291 for (int i = this.namespaces.size() - 1; i >= 0; i--) { 292 final String [] prefixAndUri = (String []) this.namespaces.get(i); 293 if (prefixAndUri[0].equals(prefix)) { 294 uri = prefixAndUri[1]; 295 this.namespaces.remove(i); 296 found = true; 297 break; 298 } 299 } 300 if (!found) { 301 throw new SAXException ("Namespace for prefix '" + prefix + "' not found."); 302 } 303 } 304 305 if (!FormsConstants.TEMPLATE_NS.equals(uri)) { 307 super.endPrefixMapping(prefix); 308 } 309 } 310 311 314 protected boolean hasPrefixMapping(String uri, String prefix) { 315 final int l = this.namespaces.size(); 316 for (int i = 0; i < l; i++) { 317 String [] prefixAndUri = (String []) this.namespaces.get(i); 318 if (prefixAndUri[0].equals(prefix) && prefixAndUri[1].equals(uri)) { 319 return true; 320 } 321 } 322 323 return false; 324 } 325 326 330 protected class NestedHandler extends CopyHandler { 331 public Handler nestedElement(String uri, String loc, String raw, Attributes attrs) 332 throws SAXException { 333 if (!FormsConstants.TEMPLATE_NS.equals(uri)) { 335 return hNested; 336 } 337 338 Handler handler = (Handler ) templates.get(loc); 339 if (handler == null) { 340 throw new SAXException ("Element '" + loc + "' was not recognized, " + 341 "at " + getLocation()); 342 } 343 344 return handler; 345 } 346 } 347 348 351 protected class DocHandler extends CopyHandler { 352 public Handler nestedElement(String uri, String loc, String raw, Attributes attrs) 353 throws SAXException { 354 if (FormsConstants.TEMPLATE_NS.equals(uri)) { 355 if (!FORM_TEMPLATE_EL.equals(loc)) { 356 throw new SAXException ("Element '" + loc + "' is not permitted outside of " + 357 "'form-template', at " + getLocation()); 358 } 359 360 return hForm; 361 } 362 363 return super.nestedElement(uri, loc, raw, attrs); 364 } 365 } 366 367 375 protected class FormHandler extends NestedHandler { 376 public Handler startElement(String uri, String loc, String raw, Attributes attrs) 377 throws SAXException { 378 if (contextWidget != null) { 379 throw new SAXException ("Element 'form-template' can not be nested, " + 380 "at " + getLocation()); 381 } 382 383 AttributesImpl newAttrs = attrs == null || attrs.getLength() == 0? 384 new AttributesImpl (): 385 new AttributesImpl (attrs); 386 387 String formLocation = attrs.getValue(LOCATION); 389 if (formLocation != null) { 390 newAttrs.removeAttribute(newAttrs.getIndex(LOCATION)); 392 } 393 contextWidget = pipeContext.findForm(formLocation); 394 395 if (!isVisible(contextWidget)) { 397 return hNull; 398 } 399 400 String localeAttr = attrs.getValue("locale"); 403 if (localeAttr != null) { localeAttr = pipeContext.translateText(localeAttr); 405 pipeContext.setLocale(I18nUtils.parseLocale(localeAttr)); 406 } else if (pipeContext.getLocaleParameter() != null) { pipeContext.setLocale(pipeContext.getLocaleParameter()); 408 } else { 409 Object locale = null; 411 try { 412 locale = pipeContext.evaluateExpression("/locale"); 413 } catch (JXPathException e) {} 414 if (locale != null) { 415 pipeContext.setLocale((Locale )locale); 416 } else { 417 pipeContext.setLocale(Locale.getDefault()); 419 } 420 } 421 422 pipeContext.addFormAttributes(newAttrs); 425 String [] namesToTranslate = {"action"}; 426 Attributes transAttrs = null; 427 try { 428 transAttrs = translateAttributes(newAttrs, namesToTranslate); 429 } catch (RuntimeException e) { 430 throw new SAXException ( e.getMessage() + " " +getLocation()); 431 } 432 433 hasInstanceNamespace = hasPrefixMapping(FormsConstants.INSTANCE_NS, FormsConstants.INSTANCE_PREFIX); 434 if (!hasInstanceNamespace) { 435 getContentHandler().startPrefixMapping(FormsConstants.INSTANCE_PREFIX, FormsConstants.INSTANCE_NS); 436 } 437 getContentHandler().startElement(FormsConstants.INSTANCE_NS, "form-template", FormsConstants.INSTANCE_PREFIX_COLON + "form-template", transAttrs); 438 return this; 439 } 440 441 public void endElement(String uri, String loc, String raw) 442 throws SAXException { 443 getContentHandler().endElement(FormsConstants.INSTANCE_NS, "form-template", FormsConstants.INSTANCE_PREFIX_COLON + "form-template"); 444 if (!hasInstanceNamespace) { 445 getContentHandler().endPrefixMapping(FormsConstants.INSTANCE_PREFIX); 446 } 447 contextWidget = null; 448 } 449 } 450 451 454 protected class SkipHandler extends NestedHandler { 455 public Handler startElement(String uri, String loc, String raw, Attributes attrs) 456 throws SAXException { 457 return this; 458 } 459 460 public void endElement(String uri, String loc, String raw) 461 throws SAXException { 462 } 463 } 464 465 469 472 protected class WidgetLabelHandler extends ErrorHandler { 473 public Handler startElement(String uri, String loc, String raw, Attributes attrs) 474 throws SAXException { 475 setWidget(loc, attrs); 476 widget.generateLabel(getContentHandler()); 477 return this; 478 } 479 480 public void endElement(String uri, String loc, String raw) 481 throws SAXException { 482 } 483 } 484 485 488 protected class WidgetHandler extends NullHandler { 489 private boolean hasStyling; 491 492 public Handler startElement(String uri, String loc, String raw, Attributes attrs) 493 throws SAXException { 494 setWidget(loc, attrs); 495 if (!isVisible(widget)) { 496 return hNull; 497 } 498 499 hasStyling = false; 500 return this; 501 } 502 503 public Handler nestedElement(String uri, String loc, String raw, Attributes attrs) 504 throws SAXException { 505 if (FormsConstants.INSTANCE_NS.equals(uri)) { 506 if (!STYLING_EL.equals(loc)) { 507 throw new SAXException ("Element '" + loc + "' is not permitted within 'widget', " + 508 "at " + getLocation()); 509 } 510 hasStyling = true; 511 beginBuffer(); 512 return hBuffer; 514 } 515 return hNull; 516 } 517 518 public void endElement(String uri, String loc, String raw) 519 throws SAXException { 520 if (hasStyling) { 521 hasStyling = false; 524 hStyling.recycle(); 525 hStyling.setSaxFragment(endBuffer()); 526 hStyling.setContentHandler(getContentHandler()); 527 hStyling.setLexicalHandler(getLexicalHandler()); 528 widget.generateSaxFragment(hStyling, pipeContext.getLocale()); 529 } else { 530 widget.generateSaxFragment(getContentHandler(), pipeContext.getLocale()); 532 } 533 widget = null; 534 } 535 } 536 537 541 544 protected class RepeaterSizeHandler extends ErrorHandler { 545 public Handler startElement(String uri, String loc, String raw, Attributes attrs) 546 throws SAXException { 547 setTypedWidget(loc, attrs, Repeater.class, "repeater"); 548 ((Repeater) widget).generateSize(getContentHandler()); 549 widget = null; 550 return this; 551 } 552 553 public void endElement(String uri, String loc, String raw) 554 throws SAXException { 555 } 556 } 557 558 561 protected class RepeaterWidgetLabelHandler extends ErrorHandler { 562 public Handler startElement(String uri, String loc, String raw, Attributes attrs) 563 throws SAXException { 564 Repeater repeater; 565 if (contextWidget instanceof Repeater) { 566 repeater = (Repeater)contextWidget; 567 } else { 568 setTypedWidget(loc, attrs, Repeater.class, "repeater"); 569 repeater = (Repeater)widget; 570 widget = null; 571 } 572 String path = getRequiredAttributeValue(loc, attrs, "widget-id"); 573 repeater.generateWidgetLabel(path, getContentHandler()); 574 return this; 575 } 576 577 public void endElement(String uri, String loc, String raw) 578 throws SAXException { 579 } 580 } 581 582 585 protected class RepeaterHandler extends NestedHandler { 586 protected Class getWidgetClass() { 587 return Repeater.class; 588 } 589 590 protected String getWidgetName() { 591 return "repeater"; 592 } 593 594 public Handler startElement(String uri, String loc, String raw, Attributes attrs) 595 throws SAXException { 596 setTypedWidget(loc, attrs, getWidgetClass(), getWidgetName()); 597 if (!isVisible(widget)) { 598 return hNull; 599 } 600 601 contextWidgets.addFirst(contextWidget); 602 contextWidget = widget; 603 return this; 604 } 605 606 public void endElement(String uri, String loc, String raw) 607 throws SAXException { 608 contextWidget = (Widget) contextWidgets.removeFirst(); 609 } 610 } 611 612 615 protected class RepeaterRowsHandler extends BufferHandler { 616 public Handler startElement(String uri, String loc, String raw, Attributes attrs) 617 throws SAXException { 618 if (!(contextWidget instanceof Repeater)) { 619 throw new SAXException ("<repeater-rows> cannot be used with " + contextWidget + ", at " + getLocation()); 620 } 621 beginBuffer(); 622 return this; 623 } 624 625 public Handler nestedElement(String uri, String loc, String raw, Attributes attrs) 626 throws SAXException { 627 return hBuffer; 628 } 629 630 public void endElement(String uri, String loc, String raw) 631 throws SAXException { 632 SaxBuffer buffer = endBuffer(); 633 final Repeater repeater = (Repeater) contextWidget; 634 final int rowCount = repeater.getSize(); 635 pushHandler(hNested); 636 contextWidgets.addFirst(contextWidget); 637 for (int i = 0; i < rowCount; i++) { 638 contextWidget = repeater.getRow(i); 639 if (isVisible(contextWidget)) { 640 buffer.toSAX(EffectWidgetReplacingPipe.this); 641 } 642 } 643 contextWidget = (Widget) contextWidgets.removeFirst(); 644 popHandler(); 645 widget = null; 646 } 647 } 648 649 652 protected class RepeaterWidgetHandler extends BufferHandler { 653 public Handler startElement(String uri, String loc, String raw, Attributes attrs) 654 throws SAXException { 655 setTypedWidget(loc, attrs, Repeater.class, "repeater"); 656 if (isVisible(widget)) { 657 beginBuffer(); 658 return this; 659 } 660 return hNull; 661 } 662 663 public Handler nestedElement(String uri, String loc, String raw, Attributes attrs) 664 throws SAXException { 665 return hBuffer; 666 } 667 668 public void endElement(String uri, String loc, String raw) 669 throws SAXException { 670 SaxBuffer buffer = endBuffer(); 671 final Repeater repeater = (Repeater) widget; 672 final int rowCount = repeater.getSize(); 673 pushHandler(hNested); 674 contextWidgets.addFirst(contextWidget); 675 for (int i = 0; i < rowCount; i++) { 676 contextWidget = repeater.getRow(i); 677 if (isVisible(contextWidget)) { 678 buffer.toSAX(EffectWidgetReplacingPipe.this); 679 } 680 } 681 contextWidget = (Widget) contextWidgets.removeFirst(); 682 popHandler(); 683 widget = null; 684 } 685 } 686 687 691 694 protected class GroupHandler extends NestedHandler { 695 protected Class getWidgetClass() { 696 return Group.class; 697 } 698 699 protected String getWidgetName() { 700 return "group"; 701 } 702 703 public Handler startElement(String uri, String loc, String raw, Attributes attrs) 704 throws SAXException { 705 setTypedWidget(loc, attrs, getWidgetClass(), getWidgetName()); 706 if (!isVisible(widget)) { 707 return hNull; 708 } 709 710 contextWidgets.addFirst(contextWidget); 711 contextWidget = widget; 712 return this; 713 } 714 715 public void endElement(String uri, String loc, String raw) 716 throws SAXException { 717 contextWidget = (Widget) contextWidgets.removeFirst(); 718 } 719 } 720 721 724 protected class AggregateWidgetHandler extends GroupHandler { 725 protected Class getWidgetClass() { 726 return AggregateField.class; 727 } 728 729 protected String getWidgetName() { 730 return "aggregate"; 731 } 732 } 733 734 737 protected class ChooseHandler extends CopyHandler { 738 public Handler startElement(String uri, String loc, String raw, Attributes attrs) throws SAXException { 739 setWidget(loc, getRequiredAttributeValue(loc, attrs, "path")); 740 if (!(widget instanceof DataWidget)) { 742 throw new SAXException ("Element '" + loc + "' can only be used with DataWidget widgets, " + 743 "at " + getLocation()); 744 } 745 chooseWidgets.addFirst(widget); 747 return this; 748 } 749 750 public Handler nestedElement(String uri, String loc, String raw, Attributes attrs) throws SAXException { 751 if (FormsConstants.TEMPLATE_NS.equals(uri)) { 752 if ("when".equals(loc)) { 753 String testValue = getAttributeValue(loc, attrs, "value"); 754 String value = (String ) ((Widget) chooseWidgets.get(0)).getValue(); 755 return testValue.equals(value) ? hSkip : hNull; 756 } 757 throw new SAXException ("Element '" + loc + "' is not permitted within 'choose', " + 758 "at " + getLocation()); 759 } 760 return hChoosePassThru; 761 } 762 763 public void endElement(String uri, String loc, String raw) throws SAXException { 764 chooseWidgets.removeFirst(); 765 } 766 } 767 768 771 protected class ChoosePassThruHandler extends CopyHandler { 772 public Handler nestedElement(String uri, String loc, String raw, Attributes attrs) throws SAXException { 773 if (FormsConstants.TEMPLATE_NS.equals(uri)) { 774 if ("when".equals(loc)) { 775 String testValue = getAttributeValue(loc, attrs, "value"); 776 String value = (String ) ((Widget) chooseWidgets.get(0)).getValue(); 777 return testValue.equals(value)? hSkip: hNull; 778 } 779 throw new SAXException ("Element '" + loc + "' is not permitted within 'choose', " + 780 "at " + getLocation()); 781 } 782 return this; 783 } 784 } 785 786 789 protected class StructHandler extends GroupHandler { 790 protected Class getWidgetClass() { 791 return Struct.class; 792 } 793 794 protected String getWidgetName() { 795 return "struct"; 796 } 797 } 798 799 802 protected class UnionHandler extends GroupHandler { 803 protected Class getWidgetClass() { 804 return Union.class; 805 } 806 807 protected String getWidgetName() { 808 return "union"; 809 } 810 811 public Handler nestedElement(String uri, String loc, String raw, Attributes attrs) 812 throws SAXException { 813 if (FormsConstants.TEMPLATE_NS.equals(uri)) { 814 if ("case".equals(loc)) { 815 String id = getAttributeValue(loc, attrs, "id"); 816 String value = (String ) contextWidget.getValue(); 817 if (id.equals(value != null ? value : "")) { 818 return hSkip; 819 } 820 return hNull; 821 } 822 throw new SAXException ("Element '" + loc + "' is not permitted within 'union', " + 823 "at " + getLocation()); 824 } 825 return hUnionPassThru; 826 } 827 } 828 829 832 protected class UnionPassThruHandler extends CopyHandler { 833 public Handler nestedElement(String uri, String loc, String raw, Attributes attrs) 834 throws SAXException { 835 if (FormsConstants.TEMPLATE_NS.equals(uri)) { 836 if ("case".equals(loc)) { 837 if (contextWidget.getValue().equals(attrs.getValue("id"))) { 838 return hSkip; 839 } 840 return hNull; 841 } 842 throw new SAXException ("Element '" + loc + "' is not permitted within 'union', " + 843 "at " + getLocation()); 844 } 845 return this; 846 } 847 } 848 849 852 protected class NewHandler extends CopyHandler { 853 public Handler startElement(String uri, String loc, String raw, Attributes attrs) 854 throws SAXException { 855 String id = getRequiredAttributeValue(loc, attrs, "id"); 856 SaxBuffer buffer = (SaxBuffer) classes.get(id); 857 if (buffer == null) { 858 throw new SAXException ("New: Class '" + id + "' does not exist, " + 859 "at " + getLocation()); 860 } 861 pushHandler(hNested); 862 buffer.toSAX(EffectWidgetReplacingPipe.this); 863 popHandler(); 864 return this; 865 } 866 867 public Handler nestedElement(String uri, String loc, String raw, Attributes attrs) 868 throws SAXException { 869 return hNull; 870 } 871 872 public void endElement(String uri, String loc, String raw) 873 throws SAXException { 874 } 875 } 876 877 885 protected class ClassHandler extends BufferHandler { 886 private String widgetPath; 888 889 public Handler startElement(String uri, String loc, String raw, Attributes attrs) 890 throws SAXException { 891 widgetPath = getRequiredAttributeValue(loc, attrs, "id"); 892 beginBuffer(); 893 return this; 894 } 895 896 public Handler nestedElement(String uri, String loc, String raw, Attributes attrs) 897 throws SAXException { 898 return hBuffer; 899 } 900 901 public void endElement(String uri, String loc, String raw) throws SAXException { 902 classes.put(widgetPath, endBuffer()); 903 } 904 } 905 906 912 protected class ContinuationIdHandler extends ErrorHandler { 913 protected String getName() { 914 return "continuation-id"; 915 } 916 917 public Handler startElement(String uri, String loc, String raw, Attributes attrs) 918 throws SAXException { 919 Object idObj = pipeContext.evaluateExpression("$cocoon/continuation/id"); 922 if (idObj == null) { 923 throw new SAXException ("No continuation found"); 924 } 925 926 String id = idObj.toString(); 927 getContentHandler().startElement(FormsConstants.INSTANCE_NS, "continuation-id", FormsConstants.INSTANCE_PREFIX_COLON + "continuation-id", attrs); 928 getContentHandler().characters(id.toCharArray(), 0, id.length()); 929 getContentHandler().endElement(FormsConstants.INSTANCE_NS, "continuation-id", FormsConstants.INSTANCE_PREFIX_COLON + "continuation-id"); 930 return this; 931 } 932 933 public void endElement(String uri, String loc, String raw) throws SAXException { 934 } 935 } 936 937 941 protected class StylingContentHandler extends AbstractXMLPipe 942 implements Recyclable { 943 944 private int elementNesting; 945 private SaxBuffer styling; 946 947 public void setSaxFragment(SaxBuffer saxFragment) { 948 styling = saxFragment; 949 } 950 951 public void recycle() { 952 super.recycle(); 953 elementNesting = 0; 954 styling = null; 955 } 956 957 public void startElement(String uri, String loc, String raw, Attributes a) 958 throws SAXException { 959 elementNesting++; 960 super.startElement(uri, loc, raw, a); 961 } 962 963 public void endElement(String uri, String loc, String raw) 964 throws SAXException { 965 elementNesting--; 966 if (elementNesting == 0) { 967 styling.toSAX(getContentHandler()); 968 } 969 super.endElement(uri, loc, raw); 970 } 971 } 972 973 976 protected class ValidationErrorHandler extends NullHandler { 977 public Handler startElement(String uri, String loc, String raw, Attributes attrs) 978 throws SAXException { 979 setWidget(loc, attrs); 980 return this; 981 } 982 983 public Handler nestedElement(String uri, String loc, String raw, Attributes attrs) 984 throws SAXException { 985 return hNull; 986 } 987 988 public void endElement(String uri, String loc, String raw) 989 throws SAXException { 990 if (widget instanceof ValidationErrorAware) { 991 ValidationError error = ((ValidationErrorAware)widget).getValidationError(); 992 if (error != null) { 993 getContentHandler().startElement(FormsConstants.INSTANCE_NS, VALIDATION_ERROR, FormsConstants.INSTANCE_PREFIX_COLON + VALIDATION_ERROR, XMLUtils.EMPTY_ATTRIBUTES); 994 error.generateSaxFragment(hStyling); 995 getContentHandler().endElement(FormsConstants.INSTANCE_NS, VALIDATION_ERROR, FormsConstants.INSTANCE_PREFIX_COLON + VALIDATION_ERROR); 996 } 997 } 998 widget = null; 999 } 1000 } 1001 1002 1003 1004 private Attributes translateAttributes(Attributes attributes, String [] names) { 1005 AttributesImpl newAtts = new AttributesImpl (attributes); 1006 if (names!= null) { 1007 for (int i = 0; i < names.length; i++) { 1008 String name = names[i]; 1009 int position = newAtts.getIndex(name); 1010 String newValue = pipeContext.translateText(newAtts.getValue(position)); 1011 if(position>-1) 1012 newAtts.setValue(position, newValue); 1013 else 1014 throw new RuntimeException ("Attribute \""+name+"\" not present!"); 1015 } 1016 } 1017 return newAtts; 1018 } 1019} 1020 | Popular Tags |