public void characters(char[] chars, int start, int length) throws SAXException {
    if (inPreserve) {
      super.characters(chars, start, length);
    } else {

      // TODO: we must not output characters here if we are not directly within an XForms element
      // See:
      // http://forge.objectweb.org/tracker/index.php?func=detail&aid=310835&group_id=168&atid=350207
      if (inXFormsOrExtension) // TODO: check this: only keep spaces within XForms elements that
                               // require it in order to reduce the size of the static state
      super.characters(chars, start, length);
    }
  }
 private void sendStartPrefixMappings() throws SAXException {
   for (Enumeration e = namespaceSupport.getPrefixes(); e.hasMoreElements(); ) {
     final String namespacePrefix = (String) e.nextElement();
     final String namespaceURI = namespaceSupport.getURI(namespacePrefix);
     if (!namespacePrefix.startsWith("xml"))
       super.startPrefixMapping(namespacePrefix, namespaceURI);
   }
 }
  public void endElement(String uri, String localname, String qName) throws SAXException {

    level--;

    // Check for XForms or extension namespaces
    //        final boolean isXForms = XFormsConstants.XFORMS_NAMESPACE_URI.equals(uri);
    //        final boolean isXXForms = XFormsConstants.XXFORMS_NAMESPACE_URI.equals(uri);
    //        final boolean isEXForms = XFormsConstants.EXFORMS_NAMESPACE_URI.equals(uri);
    //        final boolean isXBL = XFormsConstants.XBL_NAMESPACE_URI.equals(uri);
    final boolean isXHTML = XMLConstants.XHTML_NAMESPACE_URI.equals(uri);
    //        final boolean isXFormsOrExtension = isXForms || isXXForms || isEXForms || isXBL;
    final boolean isXFormsOrExtension =
        !isXHTML && !"".equals(uri); // TODO: how else can we handle components?

    if (level > 0 || !ignoreRootElement) {
      // We are within preserved content or we output regular XForms content
      if (inXFormsOrExtension && (inPreserve || isXFormsOrExtension)) {
        super.endElement(uri, localname, qName);
      }

      if (inPreserve && level == preserveLevel) {
        // Leaving preserved content
        inPreserve = false;
      }

      if (inXFormsOrExtension && level == xformsLevel) {
        // Leaving model or controls
        inXFormsOrExtension = false;
        sendEndPrefixMappings();
      }
    } else {
      // Just close the root element
      super.endElement(uri, localname, qName);
      sendEndPrefixMappings();
    }

    if (!inXFormsOrExtension) {
      xmlBaseStack.pop();
    }

    namespaceSupport.endElement();
  }
  public void endDocument() throws SAXException {

    outputFirstElementIfNeeded();

    // Output global properties
    if (properties.size() > 0) {
      final AttributesImpl newAttributes = new AttributesImpl();
      for (final Map.Entry<String, String> currentEntry : properties.entrySet()) {
        final String propertyName = currentEntry.getKey();
        newAttributes.addAttribute(
            XFormsConstants.XXFORMS_NAMESPACE_URI,
            propertyName,
            "xxforms:" + propertyName,
            ContentHandlerHelper.CDATA,
            currentEntry.getValue());
      }

      super.startPrefixMapping("xxforms", XFormsConstants.XXFORMS_NAMESPACE_URI);
      super.startElement("", "properties", "properties", newAttributes);
      super.endElement("", "properties", "properties");
      super.endPrefixMapping("xxforms");
    }

    super.endElement("", "static-state", "static-state");
    super.endDocument();
  }
 public void setDocumentLocator(Locator locator) {
   this.locator = locator;
   super.setDocumentLocator(locator);
 }
 public void endPrefixMapping(String s) throws SAXException {
   if (inXFormsOrExtension) super.endPrefixMapping(s);
 }
 public void startPrefixMapping(String prefix, String uri) throws SAXException {
   namespaceSupport.startPrefixMapping(prefix, uri);
   if (inXFormsOrExtension) super.startPrefixMapping(prefix, uri);
 }
  public void startElement(String uri, String localname, String qName, Attributes attributes)
      throws SAXException {

    namespaceSupport.startElement();

    // Handle location data
    if (locationData == null && locator != null && mustOutputFirstElement) {
      final String systemId = locator.getSystemId();
      if (systemId != null) {
        locationData =
            new LocationData(systemId, locator.getLineNumber(), locator.getColumnNumber());
      }
    }

    // Check for XForms or extension namespaces
    final boolean isXForms = XFormsConstants.XFORMS_NAMESPACE_URI.equals(uri);
    final boolean isXXForms = XFormsConstants.XXFORMS_NAMESPACE_URI.equals(uri);
    final boolean isEXForms = XFormsConstants.EXFORMS_NAMESPACE_URI.equals(uri);
    final boolean isXBL = XFormsConstants.XBL_NAMESPACE_URI.equals(uri);
    final boolean isXHTML = XMLConstants.XHTML_NAMESPACE_URI.equals(uri);

    // TODO: how else can we handle components?
    // NOTE: Here we have an issue identifying which elements must have content preserved. For
    // example, an element
    // to which an XBL binding is applied should be preserved, because XBL template processing take
    // place during
    // static state analysis. In XFormsDocumentAnnotatorContentHandler, we detect XBL bindings.
    // Should we do the
    // same here again? It is wasteful to do it twice. Possibly, XFDACH could pass this information
    // here since
    // it already does all the work to detect content preservation. E.g. custom attribute.

    //        final boolean isXFormsOrExtension = isXForms || isXXForms || isEXForms || isXBL;
    final boolean isXFormsOrExtension = !isXHTML && !"".equals(uri); // see NOTE above
    final boolean isExtension =
        isXFormsOrExtension && !isXForms && !isXXForms && !isEXForms && !isXBL; // see NOTE above

    // Handle xml:base
    if (!inXFormsOrExtension) {
      final String xmlBaseAttribute = attributes.getValue(XMLConstants.XML_URI, "base");
      if (xmlBaseAttribute == null) {
        xmlBaseStack.push(xmlBaseStack.peek());
      } else {
        try {
          final URI currentXMLBaseURI = xmlBaseStack.peek();
          xmlBaseStack.push(
              currentXMLBaseURI
                  .resolve(new URI(xmlBaseAttribute))
                  .normalize()); // normalize to remove "..", etc.
        } catch (URISyntaxException e) {
          throw new ValidationException(
              "Error creating URI from: '"
                  + xmlBaseStack.peek()
                  + "' and '"
                  + xmlBaseAttribute
                  + "'.",
              e,
              new LocationData(locator));
        }
      }
    }

    // Handle properties of the form @xxforms:* when outside of models or controls
    if (!inXFormsOrExtension && !isXFormsOrExtension) {
      final int attributesCount = attributes.getLength();
      for (int i = 0; i < attributesCount; i++) {
        final String attributeURI = attributes.getURI(i);
        if (XFormsConstants.XXFORMS_NAMESPACE_URI.equals(attributeURI)) {
          // Found xxforms:* attribute
          final String attributeLocalName = attributes.getLocalName(i);
          // Only take the first occurrence into account, and make sure the property is supported
          if (properties.get(attributeLocalName) == null
              && XFormsProperties.getPropertyDefinition(attributeLocalName) != null) {
            properties.put(attributeLocalName, attributes.getValue(i));
          }
        }
      }
    }

    if (level > 0 || !ignoreRootElement) {

      // Start extracting model or controls
      if (!inXFormsOrExtension && isXFormsOrExtension) {

        inXFormsOrExtension = true;
        xformsLevel = level;

        outputFirstElementIfNeeded();

        // Add xml:base on element
        attributes =
            XMLUtils.addOrReplaceAttribute(
                attributes, XMLConstants.XML_URI, "xml", "base", getCurrentBaseURI());

        sendStartPrefixMappings();
      }

      // Check for preserved content
      if (inXFormsOrExtension && !inPreserve) {
        // TODO: Just warn?
        if (isXXForms) {
          // Check that we are getting a valid xxforms:* element
          if (XFormsConstants.ALLOWED_XXFORMS_ELEMENTS.get(localname) == null
              && !XFormsActions.isActionName(XFormsConstants.XXFORMS_NAMESPACE_URI, localname))
            throw new ValidationException(
                "Invalid extension element in XForms document: " + qName,
                new LocationData(locator));
        } else if (isEXForms) {
          // Check that we are getting a valid exforms:* element
          if (XFormsConstants.ALLOWED_EXFORMS_ELEMENTS.get(localname) == null)
            throw new ValidationException(
                "Invalid eXForms element in XForms document: " + qName, new LocationData(locator));
        } else if (isXBL) {
          // Check that we are getting a valid xbl:* element
          if (XFormsConstants.ALLOWED_XBL_ELEMENTS.get(localname) == null)
            throw new ValidationException(
                "Invalid XBL element in XForms document: " + qName, new LocationData(locator));
        }

        // Preserve as is the content of labels, etc., instances, and schemas
        if ((XFormsConstants.LABEL_HINT_HELP_ALERT_ELEMENT.get(localname)
                        != null // labels, etc. may contain XHTML
                    || "instance".equals(localname))
                && isXForms // XForms instances
            || "schema".equals(localname) && XMLConstants.XSD_URI.equals(uri) // XML schemas
            || "xbl".equals(localname)
                && isXBL // preserve everything under xbl:xbl so that templates may be processed by
                         // static state
            || isExtension) {
          inPreserve = true;
          preserveLevel = level;
        }
      }

      // We are within preserved content or we output regular XForms content
      if (inXFormsOrExtension && (inPreserve || isXFormsOrExtension)) {
        super.startElement(uri, localname, qName, attributes);
      }
    } else {
      // Just open the root element
      outputFirstElementIfNeeded();
      sendStartPrefixMappings();
      super.startElement(uri, localname, qName, attributes);
    }

    level++;
  }
  private void outputFirstElementIfNeeded() throws SAXException {
    if (mustOutputFirstElement) {
      final AttributesImpl attributesImpl = new AttributesImpl();

      if (externalContext != null) { // case of nested document (XBL templates)
        // Add xml:base attribute
        attributesImpl.addAttribute(
            XMLConstants.XML_URI,
            "base",
            "xml:base",
            ContentHandlerHelper.CDATA,
            externalContext.getResponse().rewriteRenderURL((xmlBaseStack.get(0)).toString()));
        // Add deployment attribute
        attributesImpl.addAttribute(
            XMLConstants.XML_URI,
            "deployment",
            "deployment",
            ContentHandlerHelper.CDATA,
            isSeparateDeployment ? "separate" : "integrated");
        // Add context path attribute
        attributesImpl.addAttribute(
            XMLConstants.XML_URI,
            "context-path",
            "context-path",
            ContentHandlerHelper.CDATA,
            requestContextPath);
        // Add container-type attribute
        attributesImpl.addAttribute(
            "",
            "container-type",
            "container-type",
            ContentHandlerHelper.CDATA,
            externalContext.getRequest().getContainerType());
        // Add container-namespace attribute
        attributesImpl.addAttribute(
            "",
            "container-namespace",
            "container-namespace",
            ContentHandlerHelper.CDATA,
            externalContext.getRequest().getContainerNamespace());
      }

      // Add location information
      if (locationData != null) {
        attributesImpl.addAttribute(
            "", "system-id", "system-id", ContentHandlerHelper.CDATA, locationData.getSystemID());
        attributesImpl.addAttribute(
            "",
            "line",
            "line",
            ContentHandlerHelper.CDATA,
            Integer.toString(locationData.getLine()));
        attributesImpl.addAttribute(
            "",
            "column",
            "column",
            ContentHandlerHelper.CDATA,
            Integer.toString(locationData.getCol()));
      }

      super.startElement("", "static-state", "static-state", attributesImpl);
      mustOutputFirstElement = false;
    }
  }
 public void startDocument() throws SAXException {
   super.startDocument();
 }