@Override public void handleControlStart( String uri, String localname, String qName, Attributes attributes, String staticId, final String effectiveId, XFormsSingleNodeControl xformsControl) throws SAXException { final String groupElementName = getContainingElementName(); final String xhtmlPrefix = handlerContext.findXHTMLPrefix(); final String groupElementQName = XMLUtils.buildQName(xhtmlPrefix, groupElementName); final ElementHandlerController controller = handlerContext.getController(); // Get classes // TODO: should use getContainerAttributes() instead? final StringBuilder classes = getInitialClasses(uri, localname, attributes, null); handleMIPClasses(classes, getPrefixedId(), xformsControl); final ContentHandler contentHandler = controller.getOutput(); // Start xhtml:fieldset element if needed if (!handlerContext.isNewXHTMLLayout()) contentHandler.startElement( XMLConstants.XHTML_NAMESPACE_URI, groupElementName, groupElementQName, getAttributes(attributes, classes.toString(), effectiveId)); // Output an xhtml:legend element if and only if there is an xforms:label element. This help // with // styling in particular. final boolean hasLabel = XFormsControl.hasLabel(containingDocument, getPrefixedId()); if (hasLabel) { // Handle label classes reusableAttributes.clear(); reusableAttributes.addAttribute( "", "class", "class", ContentHandlerHelper.CDATA, getLabelClasses(xformsControl)); // The id should never be need on <legend> // reusableAttributes.addAttribute("", "id", "id", ContentHandlerHelper.CDATA, // getLHHACId(effectiveId, LHHAC_CODES.get(LHHAC.LABEL))); // Output xhtml:legend with label content final String legendQName = XMLUtils.buildQName(xhtmlPrefix, "legend"); contentHandler.startElement( XMLConstants.XHTML_NAMESPACE_URI, "legend", legendQName, reusableAttributes); { final String labelValue = getLabelValue(xformsControl); if (StringUtils.isNotEmpty(labelValue)) contentHandler.characters(labelValue.toCharArray(), 0, labelValue.length()); } contentHandler.endElement(XMLConstants.XHTML_NAMESPACE_URI, "legend", legendQName); } }
protected void handleControlStart( String uri, String localname, String qName, Attributes attributes, String effectiveId, XFormsControl control) throws SAXException { final XFormsTriggerControl triggerControl = (XFormsTriggerControl) control; final XMLReceiver xmlReceiver = handlerContext.getController().getOutput(); final AttributesImpl containerAttributes = getEmptyNestedControlAttributesMaybeWithId( uri, localname, attributes, effectiveId, triggerControl, true); // TODO: needs f:url-norewrite="true"? containerAttributes.addAttribute("", "href", "href", XMLReceiverHelper.CDATA, "#"); // xhtml:a final String xhtmlPrefix = handlerContext.findXHTMLPrefix(); final String aQName = XMLUtils.buildQName(xhtmlPrefix, ENCLOSING_ELEMENT_NAME); xmlReceiver.startElement( XMLConstants.XHTML_NAMESPACE_URI, ENCLOSING_ELEMENT_NAME, aQName, containerAttributes); { final String labelValue = getTriggerLabel(triggerControl); final boolean mustOutputHTMLFragment = triggerControl != null && triggerControl.isHTMLLabel(); outputLabelText(xmlReceiver, triggerControl, labelValue, xhtmlPrefix, mustOutputHTMLFragment); } xmlReceiver.endElement(XMLConstants.XHTML_NAMESPACE_URI, ENCLOSING_ELEMENT_NAME, aQName); }
public void outputDelimiter(ContentHandler contentHandler, String classes, String id) throws SAXException { reusableAttributes.clear(); if (id != null) reusableAttributes.addAttribute("", "id", "id", ContentHandlerHelper.CDATA, id); if (classes != null) reusableAttributes.addAttribute("", "class", "class", ContentHandlerHelper.CDATA, classes); final String delimiterQName = XMLUtils.buildQName(delimiterPrefix, delimiterLocalName); contentHandler.startElement( delimiterNamespaceURI, delimiterLocalName, delimiterQName, reusableAttributes); contentHandler.endElement(delimiterNamespaceURI, delimiterLocalName, delimiterQName); }
public static AttributesImpl addOrReplaceAttribute( Attributes attributes, String uri, String prefix, String localname, String value) { final AttributesImpl newAttributes = new AttributesImpl(); boolean replaced = false; for (int i = 0; i < attributes.getLength(); i++) { final String attributeURI = attributes.getURI(i); final String attributeValue = attributes.getValue(i); final String attributeType = attributes.getType(i); final String attributeQName = attributes.getQName(i); final String attributeLocalname = attributes.getLocalName(i); if (uri.equals(attributeURI) && localname.equals(attributeLocalname)) { // Found existing attribute replaced = true; newAttributes.addAttribute( uri, localname, XMLUtils.buildQName(prefix, localname), ContentHandlerHelper.CDATA, value); } else { // Not a matched attribute newAttributes.addAttribute( attributeURI, attributeLocalname, attributeQName, attributeType, attributeValue); } } if (!replaced) { // Attribute did not exist already so add it newAttributes.addAttribute( uri, localname, XMLUtils.buildQName(prefix, localname), ContentHandlerHelper.CDATA, value); } return newAttributes; }
@Override public void handleControlEnd( String uri, String localname, String qName, Attributes attributes, String staticId, String effectiveId, XFormsSingleNodeControl xformsControl) throws SAXException { final ElementHandlerController controller = handlerContext.getController(); // Close xhtml:span final String xhtmlPrefix = handlerContext.findXHTMLPrefix(); final String groupElementName = getContainingElementName(); final String groupElementQName = XMLUtils.buildQName(xhtmlPrefix, groupElementName); if (!handlerContext.isNewXHTMLLayout()) controller .getOutput() .endElement(XMLConstants.XHTML_NAMESPACE_URI, groupElementName, groupElementQName); }
public void handleControlStart( String uri, String localname, String qName, Attributes attributes, final String effectiveId, XFormsControl control) throws SAXException { final String groupElementName = getContainingElementName(); final String xhtmlPrefix = handlerContext.findXHTMLPrefix(); final String groupElementQName = XMLUtils.buildQName(xhtmlPrefix, groupElementName); final ElementHandlerController controller = handlerContext.getController(); // Place interceptor on output // NOTE: Strictly, we should be able to do without the interceptor. We use it here because it // automatically handles ids and element names currentSavedOutput = controller.getOutput(); if (!handlerContext.isNoScript()) { final boolean isMustGenerateBeginEndDelimiters = !handlerContext.isFullUpdateTopLevelControl(effectiveId); // Classes on top-level elements and characters and on the first delimiter final String elementClasses; { final StringBuilder classes = new StringBuilder(); appendControlUserClasses(attributes, control, classes); // NOTE: Could also use getInitialClasses(uri, localname, attributes, control), but then we // get the // xforms-group-appearance-xxforms-separator class. Is that desirable? handleMIPClasses( classes, getPrefixedId(), control); // as of August 2009, actually only need the marker class as well as // xforms-disabled if the group is non-relevant elementClasses = classes.toString(); } outputInterceptor = new OutputInterceptor( currentSavedOutput, groupElementQName, new OutputInterceptor.Listener() { // Classes on first delimiter private final String firstDelimiterClasses; { final StringBuilder classes = new StringBuilder("xforms-group-begin-end"); if (elementClasses.length() > 0) { classes.append(' '); classes.append(elementClasses); } firstDelimiterClasses = classes.toString(); } public void generateFirstDelimiter(OutputInterceptor outputInterceptor) throws SAXException { // Delimiter: begin group if (isMustGenerateBeginEndDelimiters) { outputInterceptor.outputDelimiter( currentSavedOutput, outputInterceptor.getDelimiterNamespaceURI(), outputInterceptor.getDelimiterPrefix(), outputInterceptor.getDelimiterLocalName(), firstDelimiterClasses, "group-begin-" + XFormsUtils.namespaceId(containingDocument, effectiveId)); } } }); controller.setOutput(new DeferredXMLReceiverImpl(outputInterceptor)); // Set control classes outputInterceptor.setAddedClasses(elementClasses); } else if (isNonRelevant(control)) { // In noscript, if the group not visible, set output to a black hole controller.setOutput(new DeferredXMLReceiverAdapter()); } // Don't support label, help, alert, or hint and other appearances, only the content! }
public static void handleItemFull( PipelineContext pipelineContext, HandlerContext handlerContext, ContentHandler contentHandler, AttributesImpl reusableAttributes, Attributes attributes, String xhtmlPrefix, String spanQName, XFormsContainingDocument containingDocument, XFormsValueControl xformsControl, String effectiveId, String itemEffectiveId, boolean isMultiple, String type, Item item, boolean isFirst) throws SAXException { // Whether this is selected boolean isSelected = isSelected(pipelineContext, handlerContext, xformsControl, isMultiple, item); // xhtml:span enclosing input and label final String itemClasses = getItemClasses(item, isSelected ? "xforms-selected" : "xforms-deselected"); final AttributesImpl spanAttributes = getAttributes(reusableAttributes, XMLUtils.EMPTY_ATTRIBUTES, itemClasses, null); // Add item attributes to span addItemAttributes(item, spanAttributes); contentHandler.startElement( XMLConstants.XHTML_NAMESPACE_URI, "span", spanQName, spanAttributes); { { // xhtml:input final String inputQName = XMLUtils.buildQName(xhtmlPrefix, "input"); reusableAttributes.clear(); reusableAttributes.addAttribute( "", "id", "id", ContentHandlerHelper.CDATA, itemEffectiveId); reusableAttributes.addAttribute("", "type", "type", ContentHandlerHelper.CDATA, type); // Get group name from selection control if possible, otherwise use effective id final String name = (!isMultiple && xformsControl instanceof XFormsSelect1Control) ? ((XFormsSelect1Control) xformsControl).getGroupName() : effectiveId; reusableAttributes.addAttribute("", "name", "name", ContentHandlerHelper.CDATA, name); reusableAttributes.addAttribute( "", "value", "value", ContentHandlerHelper.CDATA, item.getExternalValue(pipelineContext)); if (!handlerContext.isTemplate() && xformsControl != null) { if (isSelected) { reusableAttributes.addAttribute( "", "checked", "checked", ContentHandlerHelper.CDATA, "checked"); } if (isFirst) { // Handle accessibility attributes handleAccessibilityAttributes(attributes, reusableAttributes); } } handleDisabledAttribute(reusableAttributes, containingDocument, xformsControl); contentHandler.startElement( XMLConstants.XHTML_NAMESPACE_URI, "input", inputQName, reusableAttributes); contentHandler.endElement(XMLConstants.XHTML_NAMESPACE_URI, "input", inputQName); } // We don't output the label within <input></input>, because XHTML won't display it. final String label = item.getLabel(); if (label != null) { // allow null label to tell not to output the <label> element at all reusableAttributes.clear(); outputLabelFor( handlerContext, reusableAttributes, itemEffectiveId, itemEffectiveId, LHHAC.LABEL, "label", label, false, false); // TODO: may be HTML for full appearance } } contentHandler.endElement(XMLConstants.XHTML_NAMESPACE_URI, "span", spanQName); }
private void outputFull( String uri, String localname, Attributes attributes, String effectiveId, XFormsValueControl xformsControl, Itemset itemset, boolean isMultiple, boolean isBooleanInput) throws SAXException { final ContentHandler contentHandler = handlerContext.getController().getOutput(); final AttributesImpl containerAttributes = getContainerAttributes(uri, localname, attributes, effectiveId, xformsControl, !isFull); final String xhtmlPrefix = handlerContext.findXHTMLPrefix(); final String fullItemType = isMultiple ? "checkbox" : "radio"; // In noscript mode, use <fieldset> // TODO: This really hasn't much to do with noscript; should we always use fieldset, or make // this an // option? Benefit of limiting to noscript is that then no JS change is needed final String containingElementName = handlerContext.isNoScript() ? "fieldset" : "span"; final String containingElementQName = XMLUtils.buildQName(xhtmlPrefix, containingElementName); final String spanQName = XMLUtils.buildQName(xhtmlPrefix, "span"); { // Old layout always output container <span>/<fieldset>, and in new layout we only put it for // select/select1 final boolean outputContainerElement = !isBooleanInput || !handlerContext.isSpanHTMLLayout(); if (outputContainerElement) contentHandler.startElement( XMLConstants.XHTML_NAMESPACE_URI, containingElementName, containingElementQName, containerAttributes); { if (handlerContext.isNoScript()) { // Output <legend> final String legendName = "legend"; final String legendQName = XMLUtils.buildQName(xhtmlPrefix, legendName); reusableAttributes.clear(); // TODO: handle other attributes? xforms-disabled? reusableAttributes.addAttribute( "", "class", "class", ContentHandlerHelper.CDATA, "xforms-label"); contentHandler.startElement( XMLConstants.XHTML_NAMESPACE_URI, legendName, legendQName, reusableAttributes); if (xformsControl != null) { final boolean mustOutputHTMLFragment = xformsControl.isHTMLLabel(pipelineContext); outputLabelText( contentHandler, xformsControl, xformsControl.getLabel(pipelineContext), xhtmlPrefix, mustOutputHTMLFragment); } contentHandler.endElement(XMLConstants.XHTML_NAMESPACE_URI, legendName, legendQName); } if (itemset != null) { int itemIndex = 0; for (Iterator<Item> i = itemset.toList().iterator(); i.hasNext(); itemIndex++) { final Item item = i.next(); final String itemEffectiveId = getItemId(effectiveId, Integer.toString(itemIndex)); handleItemFull( pipelineContext, handlerContext, contentHandler, reusableAttributes, attributes, xhtmlPrefix, spanQName, containingDocument, xformsControl, effectiveId, itemEffectiveId, isMultiple, fullItemType, item, itemIndex == 0); } } } if (outputContainerElement) contentHandler.endElement( XMLConstants.XHTML_NAMESPACE_URI, containingElementName, containingElementQName); } // NOTE: Templates for full items are output globally in XHTMLBodyHandler }
public void outputContent( String uri, String localname, Attributes attributes, String effectiveId, final XFormsValueControl xformsSelect1Control, Itemset itemset, final boolean isMultiple, final boolean isFull, boolean isBooleanInput) throws SAXException { final ContentHandler contentHandler = handlerContext.getController().getOutput(); final AttributesImpl containerAttributes = getContainerAttributes( uri, localname, attributes, effectiveId, xformsSelect1Control, !isFull); final String xhtmlPrefix = handlerContext.findXHTMLPrefix(); if (!isStaticReadonly(xformsSelect1Control)) { if (isFull) { // Full appearance outputFull( uri, localname, attributes, effectiveId, xformsSelect1Control, itemset, isMultiple, isBooleanInput); } else { if (isOpenSelection) { if (isAutocomplete) { // Create xhtml:span final String spanQName = XMLUtils.buildQName(xhtmlPrefix, "span"); contentHandler.startElement( XMLConstants.XHTML_NAMESPACE_URI, "span", spanQName, containerAttributes); { { // Create xhtml:input final String inputQName = XMLUtils.buildQName(xhtmlPrefix, "input"); reusableAttributes.clear(); reusableAttributes.addAttribute( "", "type", "type", ContentHandlerHelper.CDATA, "text"); reusableAttributes.addAttribute( "", "name", "name", ContentHandlerHelper.CDATA, "xforms-select1-open-input-" + effectiveId); reusableAttributes.addAttribute( "", "class", "class", ContentHandlerHelper.CDATA, "xforms-select1-open-input"); reusableAttributes.addAttribute( "", "autocomplete", "autocomplete", ContentHandlerHelper.CDATA, "off"); final String value = (xformsSelect1Control == null) ? null : xformsSelect1Control.getValue(pipelineContext); // NOTE: With open selection, we send all values to the client but not encrypt them // because the client matches on values reusableAttributes.addAttribute( "", "value", "value", ContentHandlerHelper.CDATA, (value == null) ? "" : value); handleDisabledAttribute( reusableAttributes, containingDocument, xformsSelect1Control); contentHandler.startElement( XMLConstants.XHTML_NAMESPACE_URI, "input", inputQName, reusableAttributes); contentHandler.endElement(XMLConstants.XHTML_NAMESPACE_URI, "input", inputQName); } { // Create xhtml:select final String selectQName = XMLUtils.buildQName(xhtmlPrefix, "select"); reusableAttributes.clear(); reusableAttributes.addAttribute( "", "class", "class", ContentHandlerHelper.CDATA, "xforms-select1-open-select"); if (isCompact) reusableAttributes.addAttribute( "", "multiple", "multiple", ContentHandlerHelper.CDATA, "multiple"); // Handle accessibility attributes handleAccessibilityAttributes(attributes, reusableAttributes); contentHandler.startElement( XMLConstants.XHTML_NAMESPACE_URI, "select", selectQName, reusableAttributes); final String optionQName = XMLUtils.buildQName(xhtmlPrefix, "option"); handleItemCompact( contentHandler, optionQName, xformsSelect1Control, isMultiple, EMPTY_TOP_LEVEL_ITEM); if (itemset != null) { for (final Item item : itemset.toList()) { if (item.getValue() != null) handleItemCompact( contentHandler, optionQName, xformsSelect1Control, isMultiple, item); } } contentHandler.endElement(XMLConstants.XHTML_NAMESPACE_URI, "select", selectQName); } } contentHandler.endElement(XMLConstants.XHTML_NAMESPACE_URI, "span", spanQName); } else { // We do not support other appearances or regular open selection for now throw new ValidationException( "Open selection currently only supports the xxforms:autocomplete appearance.", new ExtendedLocationData( handlerContext.getLocationData(), "producing markup for xforms:" + localname + " control", (xformsSelect1Control != null) ? xformsSelect1Control.getControlElement() : null)); } } else if (isTree) { // xxforms:tree appearance // Create xhtml:div with tree info final String divQName = XMLUtils.buildQName(xhtmlPrefix, "div"); handleDisabledAttribute(containerAttributes, containingDocument, xformsSelect1Control); contentHandler.startElement( XMLConstants.XHTML_NAMESPACE_URI, "div", divQName, containerAttributes); if (itemset != null) { // can be null if the control is non-relevant outputJSONTreeInfo(xformsSelect1Control, itemset, isMultiple, contentHandler); } contentHandler.endElement(XMLConstants.XHTML_NAMESPACE_URI, "div", divQName); } else if (isMenu) { // xxforms:menu appearance // Create enclosing xhtml:div final String divQName = XMLUtils.buildQName(xhtmlPrefix, "div"); final String ulQName = XMLUtils.buildQName(xhtmlPrefix, "ul"); final String liQName = XMLUtils.buildQName(xhtmlPrefix, "li"); final String aQName = XMLUtils.buildQName(xhtmlPrefix, "a"); handleDisabledAttribute(containerAttributes, containingDocument, xformsSelect1Control); contentHandler.startElement( XMLConstants.XHTML_NAMESPACE_URI, "div", divQName, containerAttributes); if (itemset != null) { // can be null if the control is non-relevant // Create xhtml:div with initial menu entries { itemset.visit( contentHandler, new ItemsetListener() { private boolean groupJustStarted = false; public void startLevel(ContentHandler contentHandler, Item item) throws SAXException { final boolean isTopLevel = item == null; reusableAttributes.clear(); final String divClasses = isTopLevel ? "yuimenubar" : "yuimenu"; reusableAttributes.addAttribute( "", "class", "class", ContentHandlerHelper.CDATA, divClasses); contentHandler.startElement( XMLConstants.XHTML_NAMESPACE_URI, "div", divQName, reusableAttributes); reusableAttributes.clear(); reusableAttributes.addAttribute( "", "class", "class", ContentHandlerHelper.CDATA, "bd"); contentHandler.startElement( XMLConstants.XHTML_NAMESPACE_URI, "div", divQName, reusableAttributes); reusableAttributes.clear(); // NOTE: We just decide to put item classes on <ul> final String classes = isTopLevel ? "first-of-type" : getItemClasses(item, "first-of-type"); reusableAttributes.addAttribute( "", "class", "class", ContentHandlerHelper.CDATA, classes); contentHandler.startElement( XMLConstants.XHTML_NAMESPACE_URI, "ul", ulQName, reusableAttributes); groupJustStarted = true; } public void endLevel(ContentHandler contentHandler) throws SAXException { contentHandler.endElement(XMLConstants.XHTML_NAMESPACE_URI, "ul", ulQName); contentHandler.endElement(XMLConstants.XHTML_NAMESPACE_URI, "div", divQName); contentHandler.endElement(XMLConstants.XHTML_NAMESPACE_URI, "div", divQName); groupJustStarted = false; } public void startItem(ContentHandler contentHandler, Item item, boolean first) throws SAXException { final String liClasses; { final StringBuilder sb = new StringBuilder(item.isTopLevel() ? "yuimenubaritem" : "yuimenuitem"); if (groupJustStarted) sb.append(" first-of-type"); liClasses = getItemClasses(item, sb.toString()); } reusableAttributes.clear(); reusableAttributes.addAttribute( "", "class", "class", ContentHandlerHelper.CDATA, liClasses); contentHandler.startElement( XMLConstants.XHTML_NAMESPACE_URI, "li", liQName, reusableAttributes); reusableAttributes.clear(); reusableAttributes.addAttribute( "", "href", "href", ContentHandlerHelper.CDATA, "#"); contentHandler.startElement( XMLConstants.XHTML_NAMESPACE_URI, "a", aQName, reusableAttributes); final String text = item.getLabel(); contentHandler.characters(text.toCharArray(), 0, text.length()); contentHandler.endElement(XMLConstants.XHTML_NAMESPACE_URI, "a", aQName); groupJustStarted = false; } public void endItem(ContentHandler contentHandler) throws SAXException { contentHandler.endElement(XMLConstants.XHTML_NAMESPACE_URI, "li", liQName); groupJustStarted = false; } }); } // Create xhtml:div with tree info reusableAttributes.clear(); reusableAttributes.addAttribute( "", "class", "class", ContentHandlerHelper.CDATA, "xforms-initially-hidden"); contentHandler.startElement( XMLConstants.XHTML_NAMESPACE_URI, "div", divQName, reusableAttributes); if (itemset != null) { // can be null if the control is non-relevant outputJSONTreeInfo(xformsSelect1Control, itemset, isMultiple, contentHandler); } contentHandler.endElement(XMLConstants.XHTML_NAMESPACE_URI, "div", divQName); } contentHandler.endElement(XMLConstants.XHTML_NAMESPACE_URI, "div", divQName); } else { // Create xhtml:select final String selectQName = XMLUtils.buildQName(xhtmlPrefix, "select"); containerAttributes.addAttribute( "", "name", "name", ContentHandlerHelper.CDATA, effectiveId); // necessary for noscript mode if (isCompact) containerAttributes.addAttribute( "", "multiple", "multiple", ContentHandlerHelper.CDATA, "multiple"); // Handle accessibility attributes handleAccessibilityAttributes(attributes, containerAttributes); handleDisabledAttribute(containerAttributes, containingDocument, xformsSelect1Control); contentHandler.startElement( XMLConstants.XHTML_NAMESPACE_URI, "select", selectQName, containerAttributes); { final String optionQName = XMLUtils.buildQName(xhtmlPrefix, "option"); final String optGroupQName = XMLUtils.buildQName(xhtmlPrefix, "optgroup"); if (itemset != null) { // Work in progress for in-bounds/out-of-bounds // if (!((XFormsSelect1Control) // xformsControl).isInBounds(items)) { // // Control is out of bounds so add first item with out // of bound value to handle this // handleItemCompact(contentHandler, optionQName, // xformsControl, isMultiple, // new // XFormsItemUtils.Item(XFormsProperties.isEncryptItemValues(containingDocument), // Collections.EMPTY_LIST, "", // xformsControl.getValue(pipelineContext), 1)); // } itemset.visit( contentHandler, new ItemsetListener() { private int optgroupCount = 0; public void startLevel(ContentHandler contentHandler, Item item) throws SAXException {} public void endLevel(ContentHandler contentHandler) throws SAXException { if (optgroupCount-- > 0) { // End xhtml:optgroup contentHandler.endElement( XMLConstants.XHTML_NAMESPACE_URI, "optgroup", optGroupQName); } } public void startItem(ContentHandler contentHandler, Item item, boolean first) throws SAXException { final String label = item.getLabel(); final String value = item.getValue(); if (value == null) { final String itemClasses = getItemClasses(item, null); final AttributesImpl optGroupAttributes = getAttributes(XMLUtils.EMPTY_ATTRIBUTES, itemClasses, null); if (label != null) optGroupAttributes.addAttribute( "", "label", "label", ContentHandlerHelper.CDATA, label); // Start xhtml:optgroup contentHandler.startElement( XMLConstants.XHTML_NAMESPACE_URI, "optgroup", optGroupQName, optGroupAttributes); optgroupCount++; } else { handleItemCompact( contentHandler, optionQName, xformsSelect1Control, isMultiple, item); } } public void endItem(ContentHandler contentHandler) throws SAXException {} }); } } contentHandler.endElement(XMLConstants.XHTML_NAMESPACE_URI, "select", selectQName); } } } else { // Read-only mode final String spanQName = XMLUtils.buildQName(xhtmlPrefix, "span"); contentHandler.startElement( XMLConstants.XHTML_NAMESPACE_URI, "span", spanQName, containerAttributes); if (!handlerContext.isTemplate()) { final String value = (xformsSelect1Control == null || xformsSelect1Control.getValue(pipelineContext) == null) ? "" : xformsSelect1Control.getValue(pipelineContext); final StringBuilder sb = new StringBuilder(); if (itemset != null) { int selectedFound = 0; for (final Item currentItem : itemset.toList()) { if (XFormsItemUtils.isSelected(isMultiple, value, currentItem.getValue())) { if (selectedFound > 0) sb.append(" - "); sb.append(currentItem.getLabel()); selectedFound++; } } } if (sb.length() > 0) { final String result = sb.toString(); contentHandler.characters(result.toCharArray(), 0, result.length()); } } contentHandler.endElement(XMLConstants.XHTML_NAMESPACE_URI, "span", spanQName); } }
@Override protected void handleControlStart( String uri, String localname, String qName, Attributes attributes, String staticId, final String effectiveId, XFormsControl control) throws SAXException { final String xhtmlPrefix = handlerContext.findXHTMLPrefix(); final String spanQName = XMLUtils.buildQName(xhtmlPrefix, "span"); // Determine whether this case is visible final XFormsCaseControl caseControl = (XFormsCaseControl) containingDocument.getControls().getObjectByEffectiveId(effectiveId); if (!handlerContext.isTemplate() && caseControl != null) { // This case is visible if it is selected or if the switch is read-only and we display // read-only as static isVisible = caseControl.isVisible(); } else { isVisible = false; } final ElementHandlerController controller = handlerContext.getController(); currentSavedOutput = controller.getOutput(); // Place interceptor if needed if (!handlerContext.isNoScript()) { final boolean isMustGenerateBeginEndDelimiters = !handlerContext.isFullUpdateTopLevelControl(effectiveId); // Classes on top-level elements and characters and on the first delimiter final String elementClasses; { final StringBuilder classes = new StringBuilder(); appendControlUserClasses(attributes, control, classes); // Don't add MIP classes as they can conflict with classes of nested content if used outside // <tr>, etc. elementClasses = classes.toString(); } currentOutputInterceptor = new OutputInterceptor( currentSavedOutput, spanQName, new OutputInterceptor.Listener() { // Classes on first delimiter private final String firstDelimiterClasses; { final StringBuilder classes = new StringBuilder("xforms-case-begin-end"); if (elementClasses.length() > 0) { classes.append(' '); classes.append(elementClasses); } firstDelimiterClasses = classes.toString(); } public void generateFirstDelimiter(OutputInterceptor outputInterceptor) throws SAXException { if (isMustGenerateBeginEndDelimiters) { // Delimiter: begin case outputInterceptor.outputDelimiter( currentSavedOutput, outputInterceptor.getDelimiterNamespaceURI(), outputInterceptor.getDelimiterPrefix(), outputInterceptor.getDelimiterLocalName(), firstDelimiterClasses, "xforms-case-begin-" + XFormsUtils.namespaceId(containingDocument, effectiveId)); } } }); final String controlClasses; { final StringBuilder classes = new StringBuilder(isVisible ? "xforms-case-selected" : "xforms-case-deselected"); if (elementClasses.length() > 0) { classes.append(' '); classes.append(elementClasses); } controlClasses = classes.toString(); } currentOutputInterceptor.setAddedClasses(controlClasses); controller.setOutput(new DeferredXMLReceiverImpl(currentOutputInterceptor)); } else if (!isVisible) { // Case not visible, set output to a black hole controller.setOutput(new DeferredXMLReceiverAdapter()); } handlerContext.pushCaseContext(isVisible); }