@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); } }
@Override protected void handleControlEnd( String uri, String localname, String qName, Attributes attributes, String staticId, String effectiveId, XFormsControl control) throws SAXException { handlerContext.popCaseContext(); final ElementHandlerController controller = handlerContext.getController(); if (!handlerContext.isNoScript()) { currentOutputInterceptor.flushCharacters(true, true); // Restore output controller.setOutput(currentSavedOutput); final boolean isMustGenerateBeginEndDelimiters = !handlerContext.isFullUpdateTopLevelControl(effectiveId); if (isMustGenerateBeginEndDelimiters) { if (currentOutputInterceptor.getDelimiterNamespaceURI() != null) { // Output end delimiter currentOutputInterceptor.outputDelimiter( currentSavedOutput, currentOutputInterceptor.getDelimiterNamespaceURI(), currentOutputInterceptor.getDelimiterPrefix(), currentOutputInterceptor.getDelimiterLocalName(), "xforms-case-begin-end", "xforms-case-end-" + XFormsUtils.namespaceId(containingDocument, effectiveId)); } else { // Output start and end delimiter using xhtml:span final String xhtmlPrefix = handlerContext.findXHTMLPrefix(); currentOutputInterceptor.outputDelimiter( currentSavedOutput, XMLConstants.XHTML_NAMESPACE_URI, xhtmlPrefix, "span", "xforms-case-begin-end", "xforms-case-begin-" + XFormsUtils.namespaceId(containingDocument, effectiveId)); currentOutputInterceptor.outputDelimiter( currentSavedOutput, XMLConstants.XHTML_NAMESPACE_URI, xhtmlPrefix, "span", "xforms-case-begin-end", "xforms-case-end-" + XFormsUtils.namespaceId(containingDocument, effectiveId)); } } } else if (!isVisible) { // Case not visible, restore output controller.setOutput(currentSavedOutput); } }
@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); }
@Override public void handleControlEnd( String uri, String localname, String qName, Attributes attributes, String effectiveId, XFormsControl control) throws SAXException { final ElementHandlerController controller = handlerContext.getController(); if (!handlerContext.isNoScript()) { // Restore output controller.setOutput(currentSavedOutput); // Delimiter: end repeat outputInterceptor.flushCharacters(true, true); final boolean isMustGenerateBeginEndDelimiters = !handlerContext.isFullUpdateTopLevelControl(effectiveId); if (isMustGenerateBeginEndDelimiters) { outputInterceptor.outputDelimiter( currentSavedOutput, outputInterceptor.getDelimiterNamespaceURI(), outputInterceptor.getDelimiterPrefix(), outputInterceptor.getDelimiterLocalName(), "xforms-group-begin-end", "group-end-" + XFormsUtils.namespaceId(containingDocument, effectiveId)); } } else if (isNonRelevant(control)) { // In noscript, group was not visible, restore output controller.setOutput(currentSavedOutput); } // Don't support help, alert, or hint! }
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 outputResponseDocument( final PipelineContext pipelineContext, final ExternalContext externalContext, final IndentedLogger indentedLogger, final SAXStore annotatedDocument, final XFormsContainingDocument containingDocument, final XMLReceiver xmlReceiver) throws SAXException, IOException { final List<XFormsContainingDocument.Load> loads = containingDocument.getLoadsToRun(); if (containingDocument.isGotSubmissionReplaceAll()) { // 1. Got a submission with replace="all" // NOP: Response already sent out by a submission // TODO: modify XFormsModelSubmission accordingly indentedLogger.logDebug("", "handling response for submission with replace=\"all\""); } else if (loads != null && loads.size() > 0) { // 2. Got at least one xforms:load // Send redirect out // Get first load only final XFormsContainingDocument.Load load = loads.get(0); // Send redirect final String redirectResource = load.getResource(); indentedLogger.logDebug( "", "handling redirect response for xforms:load", "url", redirectResource); // Set isNoRewrite to true, because the resource is either a relative path or already contains // the servlet context externalContext.getResponse().sendRedirect(redirectResource, null, false, false, true); // Still send out a null document to signal that no further processing must take place XMLUtils.streamNullDocument(xmlReceiver); } else { // 3. Regular case: produce an XHTML document out final ElementHandlerController controller = new ElementHandlerController(); // Register handlers on controller (the other handlers are registered by the body handler) { controller.registerHandler( XHTMLHeadHandler.class.getName(), XMLConstants.XHTML_NAMESPACE_URI, "head"); controller.registerHandler( XHTMLBodyHandler.class.getName(), XMLConstants.XHTML_NAMESPACE_URI, "body"); // Register a handler for AVTs on HTML elements final boolean hostLanguageAVTs = XFormsProperties .isHostLanguageAVTs(); // TODO: this should be obtained per document, but we only // know about this in the extractor if (hostLanguageAVTs) { controller.registerHandler( XXFormsAttributeHandler.class.getName(), XFormsConstants.XXFORMS_NAMESPACE_URI, "attribute"); controller.registerHandler( XHTMLElementHandler.class.getName(), XMLConstants.XHTML_NAMESPACE_URI); } // Swallow XForms elements that are unknown controller.registerHandler( NullHandler.class.getName(), XFormsConstants.XFORMS_NAMESPACE_URI); controller.registerHandler( NullHandler.class.getName(), XFormsConstants.XXFORMS_NAMESPACE_URI); controller.registerHandler(NullHandler.class.getName(), XFormsConstants.XBL_NAMESPACE_URI); } // Set final output controller.setOutput(new DeferredXMLReceiverImpl(xmlReceiver)); // Set handler context controller.setElementHandlerContext( new HandlerContext( controller, pipelineContext, containingDocument, externalContext, null)); // Process the entire input annotatedDocument.replay( new ExceptionWrapperXMLReceiver(controller, "converting XHTML+XForms document to XHTML")); } containingDocument.afterInitialResponse(); }
@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); }