/** * Copyright (C) 2010 Orbeon, Inc. * * This program is free software; you can redistribute it and/or modify it under the terms of the * GNU Lesser General Public License as published by the Free Software Foundation; either version * 2.1 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * The full text of the license is available at http://www.gnu.org/copyleft/lesser.html */ package org.orbeon.oxf.xml; import org.orbeon.oxf.common.OXFException; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.AttributesImpl; import java.util.Stack; /** * Wrapper to an XML receiver. Provides more high-level methods to send events to a XML receiver. */ public class XMLReceiverHelper { public static final String CDATA = "CDATA"; private Stack<ElementInfo> elements = new Stack<ElementInfo>(); private XMLReceiver xmlReceiver; private AttributesImpl attributesImpl = new AttributesImpl(); private static class ElementInfo { public final String uri; public final String name; public final String qName; private ElementInfo(String uri, String name, String qName) { this.uri = uri; this.name = name; this.qName = qName; } } public XMLReceiverHelper(XMLReceiver xmlReceiver) { this.xmlReceiver = xmlReceiver; } /** * ContentHandler to write to. * * @param xmlReceiver receiver to write to * @param validateStream true if the stream must be validated by InspectingContentHandler */ public XMLReceiverHelper(XMLReceiver xmlReceiver, boolean validateStream) { if (validateStream) this.xmlReceiver = new InspectingXMLReceiver(xmlReceiver); else this.xmlReceiver = xmlReceiver; } public XMLReceiver getXmlReceiver() { return xmlReceiver; } public void startElement(String name) { startElement("", name); } public void startElement(String namespaceURI, String name) { startElement("", namespaceURI, name); } public void startElement(String prefix, String namespaceURI, String name) { attributesImpl.clear(); startElement(prefix, namespaceURI, name, attributesImpl); } public void startElement(String name, Attributes attributes) { startElement("", "", name, attributes); } public void startElement(String prefix, String namespaceURI, String name, Attributes attributes) { try { final String qName = XMLUtils.buildQName(prefix, name); xmlReceiver.startElement(namespaceURI, name, qName, attributes); elements.add(new ElementInfo(namespaceURI, name, qName)); } catch (SAXException e) { throw new OXFException(e); } } public void startElement(String name, String[] attributes) { startElement("", name, attributes); } public void startElement(String namespaceURI, String name, String[] attributes) { startElement("", namespaceURI, name, attributes); } public void startElement(String prefix, String namespaceURI, String name, String[] attributes) { attributesImpl.clear(); populateAttributes(attributesImpl, attributes); startElement(prefix, namespaceURI, name, attributesImpl); } public void endElement() { try { final ElementInfo elementInfo = elements.pop(); xmlReceiver.endElement(elementInfo.uri, elementInfo.name, elementInfo.qName); } catch (SAXException e) { throw new OXFException(e); } } public void element(String prefix, String namespaceURI, String name, Attributes attributes) { startElement(prefix, namespaceURI, name, attributes); endElement(); } public void element(String namespaceURI, String name, String[] attributes) { startElement("", namespaceURI, name, attributes); endElement(); } public void element(String name, String[] attributes) { startElement("", "", name, attributes); endElement(); } public void element(String prefix, String namespaceURI, String name, String[] attributes) { startElement(prefix, namespaceURI, name, attributes); endElement(); } public void element(String name, String text) { element("", name, text); } public void element(String namespaceURI, String name, String text) { element("", namespaceURI, name, text); } public void element(String prefix, String namespaceURI, String name, String text) { startElement(prefix, namespaceURI, name); text(text); endElement(); } public void element(String name, long number) { element("", name, number); } private void element(String namespaceURI, String name, long number) { element("", namespaceURI, name, number); } private void element(String prefix, String namespaceURI, String name, long number) { attributesImpl.clear(); startElement(prefix, namespaceURI, name); text(Long.toString(number)); endElement(); } public void text(String text) { try { if (text != null) xmlReceiver.characters(text.toCharArray(), 0, text.length()); } catch (SAXException e) { throw new OXFException(e); } } public void startDocument() { try { xmlReceiver.startDocument(); } catch (SAXException e) { throw new OXFException(e); } } public void endDocument() { try { if (!elements.isEmpty()) { throw new OXFException("Element '" + elements.peek() + "' not closed"); } xmlReceiver.endDocument(); } catch (SAXException e) { throw new OXFException(e); } } public void startPrefixMapping (String prefix, String uri) { try { xmlReceiver.startPrefixMapping(prefix, uri); } catch (SAXException e) { throw new OXFException(e); } } public void endPrefixMapping (String prefix) { try { xmlReceiver.endPrefixMapping(prefix); } catch (SAXException e) { throw new OXFException(e); } } public static void populateAttributes(AttributesImpl attributesImpl, String[] attributes) { if (attributes != null) { for (int i = 0; i < attributes.length / 2; i++) { final String attributeName = attributes[i * 2]; final String attributeValue = attributes[i * 2 + 1]; if (attributeName != null && attributeValue != null) attributesImpl.addAttribute("", attributeName, attributeName, CDATA, attributeValue); } } } }