/* * Javolution - Java(TM) Solution for Real-Time and Embedded Systems * Copyright (C) 2012 - Javolution (http://javolution.org/) * All rights reserved. * * Permission to use, copy, modify, and distribute this software is * freely granted, provided that this notice is preserved. */ package javolution.xml.sax; import java.io.IOException; import javolution.text.CharArray; import javolution.text.Text; import org.xml.sax.Attributes; import org.xml.sax.ContentHandler; import org.xml.sax.DTDHandler; import org.xml.sax.EntityResolver; import org.xml.sax.ErrorHandler; import org.xml.sax.InputSource; import org.xml.sax.Locator; import org.xml.sax.SAXException; import org.xml.sax.SAXNotRecognizedException; import org.xml.sax.SAXNotSupportedException; import org.xml.sax.SAXParseException; import org.xml.sax.XMLReader; import java.lang.CharSequence; /** * <p> This class provides a SAX2-compliant parser wrapping a * {@link javolution.xml.sax.XMLReaderImpl}. This parser allocates * <code>java.lang.String</code> instances while parsing in accordance * with the SAX2 specification. For faster performance (2-5x), the use of * the SAX2-like {@link javolution.xml.sax.XMLReaderImpl * XMLSaxParserImpl} or better{@link javolution.xml.stream.XMLStreamReader * XMLStreamReader} is recommended.</p> * * @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a> * @version 4.0, June 16, 2005 * @see <a href="http://www.saxproject.org"> SAX -- Simple API for XML</a> */ public final class SAX2ReaderImpl implements XMLReader { /** * Holds the SAX2 default handler instance. */ private static Sax2DefaultHandler DEFAULT_HANDLER = new Sax2DefaultHandler(); /** * Holds the real-time parser instance associated to this SAX2 parser. */ private final XMLReaderImpl _parser = new XMLReaderImpl(); /** * Holds the content handler proxy. */ private final Proxy _proxy = new Proxy(); /** * Default constructor. */ public SAX2ReaderImpl() {} // Implements org.xml.sax.XMLReader interface. public boolean getFeature(String name) throws SAXNotRecognizedException, SAXNotSupportedException { return _parser.getFeature(name); } // Implements org.xml.sax.XMLReader interface. public void setFeature(String name, boolean value) throws SAXNotRecognizedException, SAXNotSupportedException { _parser.setFeature(name, value); } // Implements org.xml.sax.XMLReader interface. public Object getProperty(String name) throws SAXNotRecognizedException, SAXNotSupportedException { return _parser.getProperty(name); } // Implements org.xml.sax.XMLReader interface. public void setProperty(String name, Object value) throws SAXNotRecognizedException, SAXNotSupportedException { _parser.setProperty(name, value); } // Implements org.xml.sax.XMLReader interface. public void setEntityResolver(EntityResolver resolver) { _parser.setEntityResolver(resolver); } // Implements org.xml.sax.XMLReader interface. public EntityResolver getEntityResolver() { return _parser.getEntityResolver(); } // Implements org.xml.sax.XMLReader interface. public void setDTDHandler(DTDHandler handler) { _parser.setDTDHandler(handler); } // Implements org.xml.sax.XMLReader interface. public DTDHandler getDTDHandler() { return _parser.getDTDHandler(); } // Implements org.xml.sax.XMLReader interface. public void setContentHandler(ContentHandler handler) { if (handler != null) { _proxy._sax2Handler = handler; _parser.setContentHandler(_proxy); } else { throw new NullPointerException(); } } // Implements org.xml.sax.XMLReader interface. public ContentHandler getContentHandler() { return (_proxy._sax2Handler == DEFAULT_HANDLER) ? null : _proxy._sax2Handler; } // Implements org.xml.sax.XMLReader interface. public void setErrorHandler(ErrorHandler handler) { _parser.setErrorHandler(handler); } // Implements org.xml.sax.XMLReader interface. public ErrorHandler getErrorHandler() { return _parser.getErrorHandler(); } // Implements org.xml.sax.XMLReader interface. public void parse(InputSource input) throws IOException, SAXException { try { _parser.parse(input); } finally { _parser.reset(); } } // Implements org.xml.sax.XMLReader interface. public void parse(String systemId) throws IOException, SAXException { try { _parser.parse(systemId); } finally { _parser.reset(); } } // Implements Reusable interface. public void reset() { _parser.reset(); } /** * This class defines the proxy for content handler and attributes. */ private static final class Proxy implements javolution.xml.sax.ContentHandler, Attributes { /** * Holds the SAX2 content handler to which SAX2 events are forwarded. */ private ContentHandler _sax2Handler = DEFAULT_HANDLER; /** * Holds the real-time attributes implementation from which attributes * values are read. */ private javolution.xml.sax.Attributes _attributes; /** * Default constructor. */ public Proxy() {} // Implements ContentHandler public void setDocumentLocator(Locator locator) { _sax2Handler.setDocumentLocator(locator); } // Implements ContentHandler public void startDocument() throws SAXException { _sax2Handler.startDocument(); } // Implements ContentHandler public void endDocument() throws SAXException { _sax2Handler.endDocument(); _sax2Handler = DEFAULT_HANDLER; } // Implements ContentHandler public void startPrefixMapping(CharArray prefix, CharArray uri) throws SAXException { _sax2Handler.startPrefixMapping(prefix.toString(), uri.toString()); } // Implements ContentHandler public void endPrefixMapping(CharArray prefix) throws SAXException { _sax2Handler.endPrefixMapping(prefix.toString()); } // Implements ContentHandler public void startElement(CharArray namespaceURI, CharArray localName, CharArray qName, javolution.xml.sax.Attributes atts) throws SAXException { _attributes = atts; _sax2Handler.startElement(namespaceURI.toString(), localName.toString(), qName.toString(), this); } // Implements ContentHandler public void endElement(CharArray namespaceURI, CharArray localName, CharArray qName) throws SAXException { _sax2Handler.endElement(namespaceURI.toString(), localName.toString(), qName.toString()); } // Implements ContentHandler public void characters(char ch[], int start, int length) throws SAXException { _sax2Handler.characters(ch, start, length); } // Implements ContentHandler public void ignorableWhitespace(char ch[], int start, int length) throws SAXException { _sax2Handler.ignorableWhitespace(ch, start, length); } // Implements ContentHandler public void processingInstruction(CharArray target, CharArray data) throws SAXException { _sax2Handler.processingInstruction(target.toString(), data.toString()); } // Implements ContentHandler public void skippedEntity(CharArray name) throws SAXException { _sax2Handler.skippedEntity(name.toString()); } // Implements Attributes public int getLength() { return (_attributes != null ? _attributes.getLength() : 0); } // Implements Attributes public String getURI(int index) { CharSequence chars = (_attributes != null ? _attributes .getURI(index) : null); return (chars != null ? chars.toString() : ""); } // Implements Attributes public String getLocalName(int index) { CharSequence chars = (_attributes != null ? _attributes .getLocalName(index) : null); return (chars != null ? chars.toString() : ""); } // Implements Attributes public String getQName(int index) { CharSequence chars = (_attributes != null ? _attributes .getQName(index) : null); return (chars != null ? chars.toString() : ""); } // Implements Attributes public String getType(int index) { return (_attributes != null ? _attributes.getType(index).toString() : null); } // Implements Attributes public String getValue(int index) { CharSequence chars = (_attributes != null ? _attributes .getValue(index) : null); return (chars != null ? chars.toString() : null); } // Implements Attributes public int getIndex(String uri, String localName) { return (uri != null && localName != null && _attributes != null ? _attributes .getIndex(toCharSequence(uri), toCharSequence(localName)) : -1); } // Implements Attributes public int getIndex(String qName) { return (qName != null && _attributes != null ? _attributes .getIndex(toCharSequence(qName)) : -1); } // Implements Attributes public String getType(String uri, String localName) { return (uri != null && localName != null && _attributes != null ? _attributes .getType(toCharSequence(uri), toCharSequence(localName)) .toString() : null); } // Implements Attributes public String getType(String qName) { return (qName != null && _attributes != null ? _attributes.getType( toCharSequence(qName)).toString() : null); } // Implements Attributes public String getValue(String uri, String localName) { return (uri != null && localName != null && _attributes != null && _attributes.getValue(toCharSequence(uri), toCharSequence(localName)) != null ? _attributes .getValue(toCharSequence(uri), toCharSequence(localName)) .toString() : null); } // Implements Attributes public String getValue(String qName) { return (qName != null && _attributes != null ? _attributes .getValue(toCharSequence(qName)).toString() : null); } } private static final class Sax2DefaultHandler implements EntityResolver, DTDHandler, ContentHandler, ErrorHandler { public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException { return null; } public void notationDecl(String name, String publicId, String systemId) throws SAXException {} public void unparsedEntityDecl(String name, String publicId, String systemId, String notationName) throws SAXException {} public void setDocumentLocator(Locator locator) {} public void startDocument() throws SAXException {} public void endDocument() throws SAXException {} public void startPrefixMapping(String prefix, String uri) throws SAXException {} public void endPrefixMapping(String prefix) throws SAXException {} public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {} public void endElement(String uri, String localName, String qName) throws SAXException {} public void characters(char[] ch, int start, int length) throws SAXException {} public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {} public void processingInstruction(String target, String data) throws SAXException {} public void skippedEntity(String name) throws SAXException {} public void warning(SAXParseException exception) throws SAXException {} public void error(SAXParseException exception) throws SAXException {} public void fatalError(SAXParseException exception) throws SAXException { throw exception; } } private static CharSequence toCharSequence(Object obj) { return obj instanceof CharSequence ? (CharSequence) obj : Text .valueOf(obj); } }