8004371: (props) Properties.loadFromXML needs small footprint XML parser as fallback when JAXP is not present
Reviewed-by: alanb, mchung, psandoz
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/jdk/internal/org/xml/sax/Attributes.java Wed Dec 19 12:09:10 2012 +0000
@@ -0,0 +1,281 @@
+/*
+ * Copyright (c) 2000, 2005, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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 General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// Attributes.java - attribute list with Namespace support
+// http://www.saxproject.org
+// Written by David Megginson
+// NO WARRANTY! This class is in the public domain.
+// $Id: Attributes.java,v 1.2 2004/11/03 22:44:51 jsuttor Exp $
+
+package jdk.internal.org.xml.sax;
+
+
+/**
+ * Interface for a list of XML attributes.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
+ * for further information.
+ * </blockquote>
+ *
+ * <p>This interface allows access to a list of attributes in
+ * three different ways:</p>
+ *
+ * <ol>
+ * <li>by attribute index;</li>
+ * <li>by Namespace-qualified name; or</li>
+ * <li>by qualified (prefixed) name.</li>
+ * </ol>
+ *
+ * <p>The list will not contain attributes that were declared
+ * #IMPLIED but not specified in the start tag. It will also not
+ * contain attributes used as Namespace declarations (xmlns*) unless
+ * the <code>http://xml.org/sax/features/namespace-prefixes</code>
+ * feature is set to <var>true</var> (it is <var>false</var> by
+ * default).
+ * Because SAX2 conforms to the original "Namespaces in XML"
+ * recommendation, it normally does not
+ * give namespace declaration attributes a namespace URI.
+ * </p>
+ *
+ * <p>Some SAX2 parsers may support using an optional feature flag
+ * (<code>http://xml.org/sax/features/xmlns-uris</code>) to request
+ * that those attributes be given URIs, conforming to a later
+ * backwards-incompatible revision of that recommendation. (The
+ * attribute's "local name" will be the prefix, or "xmlns" when
+ * defining a default element namespace.) For portability, handler
+ * code should always resolve that conflict, rather than requiring
+ * parsers that can change the setting of that feature flag. </p>
+ *
+ * <p>If the namespace-prefixes feature (see above) is
+ * <var>false</var>, access by qualified name may not be available; if
+ * the <code>http://xml.org/sax/features/namespaces</code> feature is
+ * <var>false</var>, access by Namespace-qualified names may not be
+ * available.</p>
+ *
+ * <p>This interface replaces the now-deprecated SAX1 {@link
+ * org.xml.sax.AttributeList AttributeList} interface, which does not
+ * contain Namespace support. In addition to Namespace support, it
+ * adds the <var>getIndex</var> methods (below).</p>
+ *
+ * <p>The order of attributes in the list is unspecified, and will
+ * vary from implementation to implementation.</p>
+ *
+ * @since SAX 2.0
+ * @author David Megginson
+ * @see org.xml.sax.helpers.AttributesImpl
+ * @see org.xml.sax.ext.DeclHandler#attributeDecl
+ */
+public interface Attributes
+{
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Indexed access.
+ ////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * Return the number of attributes in the list.
+ *
+ * <p>Once you know the number of attributes, you can iterate
+ * through the list.</p>
+ *
+ * @return The number of attributes in the list.
+ * @see #getURI(int)
+ * @see #getLocalName(int)
+ * @see #getQName(int)
+ * @see #getType(int)
+ * @see #getValue(int)
+ */
+ public abstract int getLength ();
+
+
+ /**
+ * Look up an attribute's Namespace URI by index.
+ *
+ * @param index The attribute index (zero-based).
+ * @return The Namespace URI, or the empty string if none
+ * is available, or null if the index is out of
+ * range.
+ * @see #getLength
+ */
+ public abstract String getURI (int index);
+
+
+ /**
+ * Look up an attribute's local name by index.
+ *
+ * @param index The attribute index (zero-based).
+ * @return The local name, or the empty string if Namespace
+ * processing is not being performed, or null
+ * if the index is out of range.
+ * @see #getLength
+ */
+ public abstract String getLocalName (int index);
+
+
+ /**
+ * Look up an attribute's XML qualified (prefixed) name by index.
+ *
+ * @param index The attribute index (zero-based).
+ * @return The XML qualified name, or the empty string
+ * if none is available, or null if the index
+ * is out of range.
+ * @see #getLength
+ */
+ public abstract String getQName (int index);
+
+
+ /**
+ * Look up an attribute's type by index.
+ *
+ * <p>The attribute type is one of the strings "CDATA", "ID",
+ * "IDREF", "IDREFS", "NMTOKEN", "NMTOKENS", "ENTITY", "ENTITIES",
+ * or "NOTATION" (always in upper case).</p>
+ *
+ * <p>If the parser has not read a declaration for the attribute,
+ * or if the parser does not report attribute types, then it must
+ * return the value "CDATA" as stated in the XML 1.0 Recommendation
+ * (clause 3.3.3, "Attribute-Value Normalization").</p>
+ *
+ * <p>For an enumerated attribute that is not a notation, the
+ * parser will report the type as "NMTOKEN".</p>
+ *
+ * @param index The attribute index (zero-based).
+ * @return The attribute's type as a string, or null if the
+ * index is out of range.
+ * @see #getLength
+ */
+ public abstract String getType (int index);
+
+
+ /**
+ * Look up an attribute's value by index.
+ *
+ * <p>If the attribute value is a list of tokens (IDREFS,
+ * ENTITIES, or NMTOKENS), the tokens will be concatenated
+ * into a single string with each token separated by a
+ * single space.</p>
+ *
+ * @param index The attribute index (zero-based).
+ * @return The attribute's value as a string, or null if the
+ * index is out of range.
+ * @see #getLength
+ */
+ public abstract String getValue (int index);
+
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Name-based query.
+ ////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * Look up the index of an attribute by Namespace name.
+ *
+ * @param uri The Namespace URI, or the empty string if
+ * the name has no Namespace URI.
+ * @param localName The attribute's local name.
+ * @return The index of the attribute, or -1 if it does not
+ * appear in the list.
+ */
+ public int getIndex (String uri, String localName);
+
+
+ /**
+ * Look up the index of an attribute by XML qualified (prefixed) name.
+ *
+ * @param qName The qualified (prefixed) name.
+ * @return The index of the attribute, or -1 if it does not
+ * appear in the list.
+ */
+ public int getIndex (String qName);
+
+
+ /**
+ * Look up an attribute's type by Namespace name.
+ *
+ * <p>See {@link #getType(int) getType(int)} for a description
+ * of the possible types.</p>
+ *
+ * @param uri The Namespace URI, or the empty String if the
+ * name has no Namespace URI.
+ * @param localName The local name of the attribute.
+ * @return The attribute type as a string, or null if the
+ * attribute is not in the list or if Namespace
+ * processing is not being performed.
+ */
+ public abstract String getType (String uri, String localName);
+
+
+ /**
+ * Look up an attribute's type by XML qualified (prefixed) name.
+ *
+ * <p>See {@link #getType(int) getType(int)} for a description
+ * of the possible types.</p>
+ *
+ * @param qName The XML qualified name.
+ * @return The attribute type as a string, or null if the
+ * attribute is not in the list or if qualified names
+ * are not available.
+ */
+ public abstract String getType (String qName);
+
+
+ /**
+ * Look up an attribute's value by Namespace name.
+ *
+ * <p>See {@link #getValue(int) getValue(int)} for a description
+ * of the possible values.</p>
+ *
+ * @param uri The Namespace URI, or the empty String if the
+ * name has no Namespace URI.
+ * @param localName The local name of the attribute.
+ * @return The attribute value as a string, or null if the
+ * attribute is not in the list.
+ */
+ public abstract String getValue (String uri, String localName);
+
+
+ /**
+ * Look up an attribute's value by XML qualified (prefixed) name.
+ *
+ * <p>See {@link #getValue(int) getValue(int)} for a description
+ * of the possible values.</p>
+ *
+ * @param qName The XML qualified name.
+ * @return The attribute value as a string, or null if the
+ * attribute is not in the list or if qualified names
+ * are not available.
+ */
+ public abstract String getValue (String qName);
+
+}
+
+// end of Attributes.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/jdk/internal/org/xml/sax/ContentHandler.java Wed Dec 19 12:09:10 2012 +0000
@@ -0,0 +1,443 @@
+/*
+ * Copyright (c) 2000, 2005, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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 General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// ContentHandler.java - handle main document content.
+// http://www.saxproject.org
+// Written by David Megginson
+// NO WARRANTY! This class is in the public domain.
+// $Id: ContentHandler.java,v 1.2 2004/11/03 22:44:51 jsuttor Exp $
+
+package jdk.internal.org.xml.sax;
+
+
+/**
+ * Receive notification of the logical content of a document.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
+ * for further information.
+ * </blockquote>
+ *
+ * <p>This is the main interface that most SAX applications
+ * implement: if the application needs to be informed of basic parsing
+ * events, it implements this interface and registers an instance with
+ * the SAX parser using the {@link org.xml.sax.XMLReader#setContentHandler
+ * setContentHandler} method. The parser uses the instance to report
+ * basic document-related events like the start and end of elements
+ * and character data.</p>
+ *
+ * <p>The order of events in this interface is very important, and
+ * mirrors the order of information in the document itself. For
+ * example, all of an element's content (character data, processing
+ * instructions, and/or subelements) will appear, in order, between
+ * the startElement event and the corresponding endElement event.</p>
+ *
+ * <p>This interface is similar to the now-deprecated SAX 1.0
+ * DocumentHandler interface, but it adds support for Namespaces
+ * and for reporting skipped entities (in non-validating XML
+ * processors).</p>
+ *
+ * <p>Implementors should note that there is also a
+ * <code>ContentHandler</code> class in the <code>java.net</code>
+ * package; that means that it's probably a bad idea to do</p>
+ *
+ * <pre>import java.net.*;
+ * import org.xml.sax.*;
+ * </pre>
+ *
+ * <p>In fact, "import ...*" is usually a sign of sloppy programming
+ * anyway, so the user should consider this a feature rather than a
+ * bug.</p>
+ *
+ * @since SAX 2.0
+ * @author David Megginson
+ * @see org.xml.sax.XMLReader
+ * @see org.xml.sax.DTDHandler
+ * @see org.xml.sax.ErrorHandler
+ */
+public interface ContentHandler
+{
+
+ /**
+ * Receive an object for locating the origin of SAX document events.
+ *
+ * <p>SAX parsers are strongly encouraged (though not absolutely
+ * required) to supply a locator: if it does so, it must supply
+ * the locator to the application by invoking this method before
+ * invoking any of the other methods in the ContentHandler
+ * interface.</p>
+ *
+ * <p>The locator allows the application to determine the end
+ * position of any document-related event, even if the parser is
+ * not reporting an error. Typically, the application will
+ * use this information for reporting its own errors (such as
+ * character content that does not match an application's
+ * business rules). The information returned by the locator
+ * is probably not sufficient for use with a search engine.</p>
+ *
+ * <p>Note that the locator will return correct information only
+ * during the invocation SAX event callbacks after
+ * {@link #startDocument startDocument} returns and before
+ * {@link #endDocument endDocument} is called. The
+ * application should not attempt to use it at any other time.</p>
+ *
+ * @param locator an object that can return the location of
+ * any SAX document event
+ * @see org.xml.sax.Locator
+ */
+ public void setDocumentLocator (Locator locator);
+
+
+ /**
+ * Receive notification of the beginning of a document.
+ *
+ * <p>The SAX parser will invoke this method only once, before any
+ * other event callbacks (except for {@link #setDocumentLocator
+ * setDocumentLocator}).</p>
+ *
+ * @throws org.xml.sax.SAXException any SAX exception, possibly
+ * wrapping another exception
+ * @see #endDocument
+ */
+ public void startDocument ()
+ throws SAXException;
+
+
+ /**
+ * Receive notification of the end of a document.
+ *
+ * <p><strong>There is an apparent contradiction between the
+ * documentation for this method and the documentation for {@link
+ * org.xml.sax.ErrorHandler#fatalError}. Until this ambiguity is
+ * resolved in a future major release, clients should make no
+ * assumptions about whether endDocument() will or will not be
+ * invoked when the parser has reported a fatalError() or thrown
+ * an exception.</strong></p>
+ *
+ * <p>The SAX parser will invoke this method only once, and it will
+ * be the last method invoked during the parse. The parser shall
+ * not invoke this method until it has either abandoned parsing
+ * (because of an unrecoverable error) or reached the end of
+ * input.</p>
+ *
+ * @throws org.xml.sax.SAXException any SAX exception, possibly
+ * wrapping another exception
+ * @see #startDocument
+ */
+ public void endDocument()
+ throws SAXException;
+
+
+ /**
+ * Begin the scope of a prefix-URI Namespace mapping.
+ *
+ * <p>The information from this event is not necessary for
+ * normal Namespace processing: the SAX XML reader will
+ * automatically replace prefixes for element and attribute
+ * names when the <code>http://xml.org/sax/features/namespaces</code>
+ * feature is <var>true</var> (the default).</p>
+ *
+ * <p>There are cases, however, when applications need to
+ * use prefixes in character data or in attribute values,
+ * where they cannot safely be expanded automatically; the
+ * start/endPrefixMapping event supplies the information
+ * to the application to expand prefixes in those contexts
+ * itself, if necessary.</p>
+ *
+ * <p>Note that start/endPrefixMapping events are not
+ * guaranteed to be properly nested relative to each other:
+ * all startPrefixMapping events will occur immediately before the
+ * corresponding {@link #startElement startElement} event,
+ * and all {@link #endPrefixMapping endPrefixMapping}
+ * events will occur immediately after the corresponding
+ * {@link #endElement endElement} event,
+ * but their order is not otherwise
+ * guaranteed.</p>
+ *
+ * <p>There should never be start/endPrefixMapping events for the
+ * "xml" prefix, since it is predeclared and immutable.</p>
+ *
+ * @param prefix the Namespace prefix being declared.
+ * An empty string is used for the default element namespace,
+ * which has no prefix.
+ * @param uri the Namespace URI the prefix is mapped to
+ * @throws org.xml.sax.SAXException the client may throw
+ * an exception during processing
+ * @see #endPrefixMapping
+ * @see #startElement
+ */
+ public void startPrefixMapping (String prefix, String uri)
+ throws SAXException;
+
+
+ /**
+ * End the scope of a prefix-URI mapping.
+ *
+ * <p>See {@link #startPrefixMapping startPrefixMapping} for
+ * details. These events will always occur immediately after the
+ * corresponding {@link #endElement endElement} event, but the order of
+ * {@link #endPrefixMapping endPrefixMapping} events is not otherwise
+ * guaranteed.</p>
+ *
+ * @param prefix the prefix that was being mapped.
+ * This is the empty string when a default mapping scope ends.
+ * @throws org.xml.sax.SAXException the client may throw
+ * an exception during processing
+ * @see #startPrefixMapping
+ * @see #endElement
+ */
+ public void endPrefixMapping (String prefix)
+ throws SAXException;
+
+
+ /**
+ * Receive notification of the beginning of an element.
+ *
+ * <p>The Parser will invoke this method at the beginning of every
+ * element in the XML document; there will be a corresponding
+ * {@link #endElement endElement} event for every startElement event
+ * (even when the element is empty). All of the element's content will be
+ * reported, in order, before the corresponding endElement
+ * event.</p>
+ *
+ * <p>This event allows up to three name components for each
+ * element:</p>
+ *
+ * <ol>
+ * <li>the Namespace URI;</li>
+ * <li>the local name; and</li>
+ * <li>the qualified (prefixed) name.</li>
+ * </ol>
+ *
+ * <p>Any or all of these may be provided, depending on the
+ * values of the <var>http://xml.org/sax/features/namespaces</var>
+ * and the <var>http://xml.org/sax/features/namespace-prefixes</var>
+ * properties:</p>
+ *
+ * <ul>
+ * <li>the Namespace URI and local name are required when
+ * the namespaces property is <var>true</var> (the default), and are
+ * optional when the namespaces property is <var>false</var> (if one is
+ * specified, both must be);</li>
+ * <li>the qualified name is required when the namespace-prefixes property
+ * is <var>true</var>, and is optional when the namespace-prefixes property
+ * is <var>false</var> (the default).</li>
+ * </ul>
+ *
+ * <p>Note that the attribute list provided will contain only
+ * attributes with explicit values (specified or defaulted):
+ * #IMPLIED attributes will be omitted. The attribute list
+ * will contain attributes used for Namespace declarations
+ * (xmlns* attributes) only if the
+ * <code>http://xml.org/sax/features/namespace-prefixes</code>
+ * property is true (it is false by default, and support for a
+ * true value is optional).</p>
+ *
+ * <p>Like {@link #characters characters()}, attribute values may have
+ * characters that need more than one <code>char</code> value. </p>
+ *
+ * @param uri the Namespace URI, or the empty string if the
+ * element has no Namespace URI or if Namespace
+ * processing is not being performed
+ * @param localName the local name (without prefix), or the
+ * empty string if Namespace processing is not being
+ * performed
+ * @param qName the qualified name (with prefix), or the
+ * empty string if qualified names are not available
+ * @param atts the attributes attached to the element. If
+ * there are no attributes, it shall be an empty
+ * Attributes object. The value of this object after
+ * startElement returns is undefined
+ * @throws org.xml.sax.SAXException any SAX exception, possibly
+ * wrapping another exception
+ * @see #endElement
+ * @see org.xml.sax.Attributes
+ * @see org.xml.sax.helpers.AttributesImpl
+ */
+ public void startElement (String uri, String localName,
+ String qName, Attributes atts)
+ throws SAXException;
+
+
+ /**
+ * Receive notification of the end of an element.
+ *
+ * <p>The SAX parser will invoke this method at the end of every
+ * element in the XML document; there will be a corresponding
+ * {@link #startElement startElement} event for every endElement
+ * event (even when the element is empty).</p>
+ *
+ * <p>For information on the names, see startElement.</p>
+ *
+ * @param uri the Namespace URI, or the empty string if the
+ * element has no Namespace URI or if Namespace
+ * processing is not being performed
+ * @param localName the local name (without prefix), or the
+ * empty string if Namespace processing is not being
+ * performed
+ * @param qName the qualified XML name (with prefix), or the
+ * empty string if qualified names are not available
+ * @throws org.xml.sax.SAXException any SAX exception, possibly
+ * wrapping another exception
+ */
+ public void endElement (String uri, String localName,
+ String qName)
+ throws SAXException;
+
+
+ /**
+ * Receive notification of character data.
+ *
+ * <p>The Parser will call this method to report each chunk of
+ * character data. SAX parsers may return all contiguous character
+ * data in a single chunk, or they may split it into several
+ * chunks; however, all of the characters in any single event
+ * must come from the same external entity so that the Locator
+ * provides useful information.</p>
+ *
+ * <p>The application must not attempt to read from the array
+ * outside of the specified range.</p>
+ *
+ * <p>Individual characters may consist of more than one Java
+ * <code>char</code> value. There are two important cases where this
+ * happens, because characters can't be represented in just sixteen bits.
+ * In one case, characters are represented in a <em>Surrogate Pair</em>,
+ * using two special Unicode values. Such characters are in the so-called
+ * "Astral Planes", with a code point above U+FFFF. A second case involves
+ * composite characters, such as a base character combining with one or
+ * more accent characters. </p>
+ *
+ * <p> Your code should not assume that algorithms using
+ * <code>char</code>-at-a-time idioms will be working in character
+ * units; in some cases they will split characters. This is relevant
+ * wherever XML permits arbitrary characters, such as attribute values,
+ * processing instruction data, and comments as well as in data reported
+ * from this method. It's also generally relevant whenever Java code
+ * manipulates internationalized text; the issue isn't unique to XML.</p>
+ *
+ * <p>Note that some parsers will report whitespace in element
+ * content using the {@link #ignorableWhitespace ignorableWhitespace}
+ * method rather than this one (validating parsers <em>must</em>
+ * do so).</p>
+ *
+ * @param ch the characters from the XML document
+ * @param start the start position in the array
+ * @param length the number of characters to read from the array
+ * @throws org.xml.sax.SAXException any SAX exception, possibly
+ * wrapping another exception
+ * @see #ignorableWhitespace
+ * @see org.xml.sax.Locator
+ */
+ public void characters (char ch[], int start, int length)
+ throws SAXException;
+
+
+ /**
+ * Receive notification of ignorable whitespace in element content.
+ *
+ * <p>Validating Parsers must use this method to report each chunk
+ * of whitespace in element content (see the W3C XML 1.0
+ * recommendation, section 2.10): non-validating parsers may also
+ * use this method if they are capable of parsing and using
+ * content models.</p>
+ *
+ * <p>SAX parsers may return all contiguous whitespace in a single
+ * chunk, or they may split it into several chunks; however, all of
+ * the characters in any single event must come from the same
+ * external entity, so that the Locator provides useful
+ * information.</p>
+ *
+ * <p>The application must not attempt to read from the array
+ * outside of the specified range.</p>
+ *
+ * @param ch the characters from the XML document
+ * @param start the start position in the array
+ * @param length the number of characters to read from the array
+ * @throws org.xml.sax.SAXException any SAX exception, possibly
+ * wrapping another exception
+ * @see #characters
+ */
+ public void ignorableWhitespace (char ch[], int start, int length)
+ throws SAXException;
+
+
+ /**
+ * Receive notification of a processing instruction.
+ *
+ * <p>The Parser will invoke this method once for each processing
+ * instruction found: note that processing instructions may occur
+ * before or after the main document element.</p>
+ *
+ * <p>A SAX parser must never report an XML declaration (XML 1.0,
+ * section 2.8) or a text declaration (XML 1.0, section 4.3.1)
+ * using this method.</p>
+ *
+ * <p>Like {@link #characters characters()}, processing instruction
+ * data may have characters that need more than one <code>char</code>
+ * value. </p>
+ *
+ * @param target the processing instruction target
+ * @param data the processing instruction data, or null if
+ * none was supplied. The data does not include any
+ * whitespace separating it from the target
+ * @throws org.xml.sax.SAXException any SAX exception, possibly
+ * wrapping another exception
+ */
+ public void processingInstruction (String target, String data)
+ throws SAXException;
+
+
+ /**
+ * Receive notification of a skipped entity.
+ * This is not called for entity references within markup constructs
+ * such as element start tags or markup declarations. (The XML
+ * recommendation requires reporting skipped external entities.
+ * SAX also reports internal entity expansion/non-expansion, except
+ * within markup constructs.)
+ *
+ * <p>The Parser will invoke this method each time the entity is
+ * skipped. Non-validating processors may skip entities if they
+ * have not seen the declarations (because, for example, the
+ * entity was declared in an external DTD subset). All processors
+ * may skip external entities, depending on the values of the
+ * <code>http://xml.org/sax/features/external-general-entities</code>
+ * and the
+ * <code>http://xml.org/sax/features/external-parameter-entities</code>
+ * properties.</p>
+ *
+ * @param name the name of the skipped entity. If it is a
+ * parameter entity, the name will begin with '%', and if
+ * it is the external DTD subset, it will be the string
+ * "[dtd]"
+ * @throws org.xml.sax.SAXException any SAX exception, possibly
+ * wrapping another exception
+ */
+ public void skippedEntity (String name)
+ throws SAXException;
+}
+
+// end of ContentHandler.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/jdk/internal/org/xml/sax/DTDHandler.java Wed Dec 19 12:09:10 2012 +0000
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2000, 2005, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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 General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// SAX DTD handler.
+// http://www.saxproject.org
+// No warranty; no copyright -- use this as you will.
+// $Id: DTDHandler.java,v 1.2 2004/11/03 22:44:51 jsuttor Exp $
+
+package jdk.internal.org.xml.sax;
+
+/**
+ * Receive notification of basic DTD-related events.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
+ * for further information.
+ * </blockquote>
+ *
+ * <p>If a SAX application needs information about notations and
+ * unparsed entities, then the application implements this
+ * interface and registers an instance with the SAX parser using
+ * the parser's setDTDHandler method. The parser uses the
+ * instance to report notation and unparsed entity declarations to
+ * the application.</p>
+ *
+ * <p>Note that this interface includes only those DTD events that
+ * the XML recommendation <em>requires</em> processors to report:
+ * notation and unparsed entity declarations.</p>
+ *
+ * <p>The SAX parser may report these events in any order, regardless
+ * of the order in which the notations and unparsed entities were
+ * declared; however, all DTD events must be reported after the
+ * document handler's startDocument event, and before the first
+ * startElement event.
+ * (If the {@link org.xml.sax.ext.LexicalHandler LexicalHandler} is
+ * used, these events must also be reported before the endDTD event.)
+ * </p>
+ *
+ * <p>It is up to the application to store the information for
+ * future use (perhaps in a hash table or object tree).
+ * If the application encounters attributes of type "NOTATION",
+ * "ENTITY", or "ENTITIES", it can use the information that it
+ * obtained through this interface to find the entity and/or
+ * notation corresponding with the attribute value.</p>
+ *
+ * @since SAX 1.0
+ * @author David Megginson
+ * @see org.xml.sax.XMLReader#setDTDHandler
+ */
+public interface DTDHandler {
+
+
+ /**
+ * Receive notification of a notation declaration event.
+ *
+ * <p>It is up to the application to record the notation for later
+ * reference, if necessary;
+ * notations may appear as attribute values and in unparsed entity
+ * declarations, and are sometime used with processing instruction
+ * target names.</p>
+ *
+ * <p>At least one of publicId and systemId must be non-null.
+ * If a system identifier is present, and it is a URL, the SAX
+ * parser must resolve it fully before passing it to the
+ * application through this event.</p>
+ *
+ * <p>There is no guarantee that the notation declaration will be
+ * reported before any unparsed entities that use it.</p>
+ *
+ * @param name The notation name.
+ * @param publicId The notation's public identifier, or null if
+ * none was given.
+ * @param systemId The notation's system identifier, or null if
+ * none was given.
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @see #unparsedEntityDecl
+ * @see org.xml.sax.Attributes
+ */
+ public abstract void notationDecl (String name,
+ String publicId,
+ String systemId)
+ throws SAXException;
+
+
+ /**
+ * Receive notification of an unparsed entity declaration event.
+ *
+ * <p>Note that the notation name corresponds to a notation
+ * reported by the {@link #notationDecl notationDecl} event.
+ * It is up to the application to record the entity for later
+ * reference, if necessary;
+ * unparsed entities may appear as attribute values.
+ * </p>
+ *
+ * <p>If the system identifier is a URL, the parser must resolve it
+ * fully before passing it to the application.</p>
+ *
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @param name The unparsed entity's name.
+ * @param publicId The entity's public identifier, or null if none
+ * was given.
+ * @param systemId The entity's system identifier.
+ * @param notationName The name of the associated notation.
+ * @see #notationDecl
+ * @see org.xml.sax.Attributes
+ */
+ public abstract void unparsedEntityDecl (String name,
+ String publicId,
+ String systemId,
+ String notationName)
+ throws SAXException;
+
+}
+
+// end of DTDHandler.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/jdk/internal/org/xml/sax/EntityResolver.java Wed Dec 19 12:09:10 2012 +0000
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2000, 2005, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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 General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// SAX entity resolver.
+// http://www.saxproject.org
+// No warranty; no copyright -- use this as you will.
+// $Id: EntityResolver.java,v 1.2 2004/11/03 22:44:52 jsuttor Exp $
+
+package jdk.internal.org.xml.sax;
+
+import java.io.IOException;
+
+
+/**
+ * Basic interface for resolving entities.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
+ * for further information.
+ * </blockquote>
+ *
+ * <p>If a SAX application needs to implement customized handling
+ * for external entities, it must implement this interface and
+ * register an instance with the SAX driver using the
+ * {@link org.xml.sax.XMLReader#setEntityResolver setEntityResolver}
+ * method.</p>
+ *
+ * <p>The XML reader will then allow the application to intercept any
+ * external entities (including the external DTD subset and external
+ * parameter entities, if any) before including them.</p>
+ *
+ * <p>Many SAX applications will not need to implement this interface,
+ * but it will be especially useful for applications that build
+ * XML documents from databases or other specialised input sources,
+ * or for applications that use URI types other than URLs.</p>
+ *
+ * <p>The following resolver would provide the application
+ * with a special character stream for the entity with the system
+ * identifier "http://www.myhost.com/today":</p>
+ *
+ * <pre>
+ * import org.xml.sax.EntityResolver;
+ * import org.xml.sax.InputSource;
+ *
+ * public class MyResolver implements EntityResolver {
+ * public InputSource resolveEntity (String publicId, String systemId)
+ * {
+ * if (systemId.equals("http://www.myhost.com/today")) {
+ * // return a special input source
+ * MyReader reader = new MyReader();
+ * return new InputSource(reader);
+ * } else {
+ * // use the default behaviour
+ * return null;
+ * }
+ * }
+ * }
+ * </pre>
+ *
+ * <p>The application can also use this interface to redirect system
+ * identifiers to local URIs or to look up replacements in a catalog
+ * (possibly by using the public identifier).</p>
+ *
+ * @since SAX 1.0
+ * @author David Megginson
+ * @see org.xml.sax.XMLReader#setEntityResolver
+ * @see org.xml.sax.InputSource
+ */
+public interface EntityResolver {
+
+
+ /**
+ * Allow the application to resolve external entities.
+ *
+ * <p>The parser will call this method before opening any external
+ * entity except the top-level document entity. Such entities include
+ * the external DTD subset and external parameter entities referenced
+ * within the DTD (in either case, only if the parser reads external
+ * parameter entities), and external general entities referenced
+ * within the document element (if the parser reads external general
+ * entities). The application may request that the parser locate
+ * the entity itself, that it use an alternative URI, or that it
+ * use data provided by the application (as a character or byte
+ * input stream).</p>
+ *
+ * <p>Application writers can use this method to redirect external
+ * system identifiers to secure and/or local URIs, to look up
+ * public identifiers in a catalogue, or to read an entity from a
+ * database or other input source (including, for example, a dialog
+ * box). Neither XML nor SAX specifies a preferred policy for using
+ * public or system IDs to resolve resources. However, SAX specifies
+ * how to interpret any InputSource returned by this method, and that
+ * if none is returned, then the system ID will be dereferenced as
+ * a URL. </p>
+ *
+ * <p>If the system identifier is a URL, the SAX parser must
+ * resolve it fully before reporting it to the application.</p>
+ *
+ * @param publicId The public identifier of the external entity
+ * being referenced, or null if none was supplied.
+ * @param systemId The system identifier of the external entity
+ * being referenced.
+ * @return An InputSource object describing the new input source,
+ * or null to request that the parser open a regular
+ * URI connection to the system identifier.
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @exception java.io.IOException A Java-specific IO exception,
+ * possibly the result of creating a new InputStream
+ * or Reader for the InputSource.
+ * @see org.xml.sax.InputSource
+ */
+ public abstract InputSource resolveEntity (String publicId,
+ String systemId)
+ throws SAXException, IOException;
+
+}
+
+// end of EntityResolver.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/jdk/internal/org/xml/sax/ErrorHandler.java Wed Dec 19 12:09:10 2012 +0000
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2000, 2005, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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 General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// SAX error handler.
+// http://www.saxproject.org
+// No warranty; no copyright -- use this as you will.
+// $Id: ErrorHandler.java,v 1.2 2004/11/03 22:44:52 jsuttor Exp $
+
+package jdk.internal.org.xml.sax;
+
+
+/**
+ * Basic interface for SAX error handlers.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
+ * for further information.
+ * </blockquote>
+ *
+ * <p>If a SAX application needs to implement customized error
+ * handling, it must implement this interface and then register an
+ * instance with the XML reader using the
+ * {@link org.xml.sax.XMLReader#setErrorHandler setErrorHandler}
+ * method. The parser will then report all errors and warnings
+ * through this interface.</p>
+ *
+ * <p><strong>WARNING:</strong> If an application does <em>not</em>
+ * register an ErrorHandler, XML parsing errors will go unreported,
+ * except that <em>SAXParseException</em>s will be thrown for fatal errors.
+ * In order to detect validity errors, an ErrorHandler that does something
+ * with {@link #error error()} calls must be registered.</p>
+ *
+ * <p>For XML processing errors, a SAX driver must use this interface
+ * in preference to throwing an exception: it is up to the application
+ * to decide whether to throw an exception for different types of
+ * errors and warnings. Note, however, that there is no requirement that
+ * the parser continue to report additional errors after a call to
+ * {@link #fatalError fatalError}. In other words, a SAX driver class
+ * may throw an exception after reporting any fatalError.
+ * Also parsers may throw appropriate exceptions for non-XML errors.
+ * For example, {@link XMLReader#parse XMLReader.parse()} would throw
+ * an IOException for errors accessing entities or the document.</p>
+ *
+ * @since SAX 1.0
+ * @author David Megginson
+ * @see org.xml.sax.XMLReader#setErrorHandler
+ * @see org.xml.sax.SAXParseException
+ */
+public interface ErrorHandler {
+
+
+ /**
+ * Receive notification of a warning.
+ *
+ * <p>SAX parsers will use this method to report conditions that
+ * are not errors or fatal errors as defined by the XML
+ * recommendation. The default behaviour is to take no
+ * action.</p>
+ *
+ * <p>The SAX parser must continue to provide normal parsing events
+ * after invoking this method: it should still be possible for the
+ * application to process the document through to the end.</p>
+ *
+ * <p>Filters may use this method to report other, non-XML warnings
+ * as well.</p>
+ *
+ * @param exception The warning information encapsulated in a
+ * SAX parse exception.
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @see org.xml.sax.SAXParseException
+ */
+ public abstract void warning (SAXParseException exception)
+ throws SAXException;
+
+
+ /**
+ * Receive notification of a recoverable error.
+ *
+ * <p>This corresponds to the definition of "error" in section 1.2
+ * of the W3C XML 1.0 Recommendation. For example, a validating
+ * parser would use this callback to report the violation of a
+ * validity constraint. The default behaviour is to take no
+ * action.</p>
+ *
+ * <p>The SAX parser must continue to provide normal parsing
+ * events after invoking this method: it should still be possible
+ * for the application to process the document through to the end.
+ * If the application cannot do so, then the parser should report
+ * a fatal error even if the XML recommendation does not require
+ * it to do so.</p>
+ *
+ * <p>Filters may use this method to report other, non-XML errors
+ * as well.</p>
+ *
+ * @param exception The error information encapsulated in a
+ * SAX parse exception.
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @see org.xml.sax.SAXParseException
+ */
+ public abstract void error (SAXParseException exception)
+ throws SAXException;
+
+
+ /**
+ * Receive notification of a non-recoverable error.
+ *
+ * <p><strong>There is an apparent contradiction between the
+ * documentation for this method and the documentation for {@link
+ * org.xml.sax.ContentHandler#endDocument}. Until this ambiguity
+ * is resolved in a future major release, clients should make no
+ * assumptions about whether endDocument() will or will not be
+ * invoked when the parser has reported a fatalError() or thrown
+ * an exception.</strong></p>
+ *
+ * <p>This corresponds to the definition of "fatal error" in
+ * section 1.2 of the W3C XML 1.0 Recommendation. For example, a
+ * parser would use this callback to report the violation of a
+ * well-formedness constraint.</p>
+ *
+ * <p>The application must assume that the document is unusable
+ * after the parser has invoked this method, and should continue
+ * (if at all) only for the sake of collecting additional error
+ * messages: in fact, SAX parsers are free to stop reporting any
+ * other events once this method has been invoked.</p>
+ *
+ * @param exception The error information encapsulated in a
+ * SAX parse exception.
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @see org.xml.sax.SAXParseException
+ */
+ public abstract void fatalError (SAXParseException exception)
+ throws SAXException;
+
+}
+
+// end of ErrorHandler.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/jdk/internal/org/xml/sax/InputSource.java Wed Dec 19 12:09:10 2012 +0000
@@ -0,0 +1,360 @@
+/*
+ * Copyright (c) 2000, 2005, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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 General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// SAX input source.
+// http://www.saxproject.org
+// No warranty; no copyright -- use this as you will.
+// $Id: InputSource.java,v 1.2 2004/11/03 22:55:32 jsuttor Exp $
+
+package jdk.internal.org.xml.sax;
+
+import java.io.Reader;
+import java.io.InputStream;
+
+/**
+ * A single input source for an XML entity.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
+ * for further information.
+ * </blockquote>
+ *
+ * <p>This class allows a SAX application to encapsulate information
+ * about an input source in a single object, which may include
+ * a public identifier, a system identifier, a byte stream (possibly
+ * with a specified encoding), and/or a character stream.</p>
+ *
+ * <p>There are two places that the application can deliver an
+ * input source to the parser: as the argument to the Parser.parse
+ * method, or as the return value of the EntityResolver.resolveEntity
+ * method.</p>
+ *
+ * <p>The SAX parser will use the InputSource object to determine how
+ * to read XML input. If there is a character stream available, the
+ * parser will read that stream directly, disregarding any text
+ * encoding declaration found in that stream.
+ * If there is no character stream, but there is
+ * a byte stream, the parser will use that byte stream, using the
+ * encoding specified in the InputSource or else (if no encoding is
+ * specified) autodetecting the character encoding using an algorithm
+ * such as the one in the XML specification. If neither a character
+ * stream nor a
+ * byte stream is available, the parser will attempt to open a URI
+ * connection to the resource identified by the system
+ * identifier.</p>
+ *
+ * <p>An InputSource object belongs to the application: the SAX parser
+ * shall never modify it in any way (it may modify a copy if
+ * necessary). However, standard processing of both byte and
+ * character streams is to close them on as part of end-of-parse cleanup,
+ * so applications should not attempt to re-use such streams after they
+ * have been handed to a parser. </p>
+ *
+ * @since SAX 1.0
+ * @author David Megginson
+ * @see org.xml.sax.XMLReader#parse(org.xml.sax.InputSource)
+ * @see org.xml.sax.EntityResolver#resolveEntity
+ * @see java.io.InputStream
+ * @see java.io.Reader
+ */
+public class InputSource {
+
+ /**
+ * Zero-argument default constructor.
+ *
+ * @see #setPublicId
+ * @see #setSystemId
+ * @see #setByteStream
+ * @see #setCharacterStream
+ * @see #setEncoding
+ */
+ public InputSource ()
+ {
+ }
+
+
+ /**
+ * Create a new input source with a system identifier.
+ *
+ * <p>Applications may use setPublicId to include a
+ * public identifier as well, or setEncoding to specify
+ * the character encoding, if known.</p>
+ *
+ * <p>If the system identifier is a URL, it must be fully
+ * resolved (it may not be a relative URL).</p>
+ *
+ * @param systemId The system identifier (URI).
+ * @see #setPublicId
+ * @see #setSystemId
+ * @see #setByteStream
+ * @see #setEncoding
+ * @see #setCharacterStream
+ */
+ public InputSource (String systemId)
+ {
+ setSystemId(systemId);
+ }
+
+
+ /**
+ * Create a new input source with a byte stream.
+ *
+ * <p>Application writers should use setSystemId() to provide a base
+ * for resolving relative URIs, may use setPublicId to include a
+ * public identifier, and may use setEncoding to specify the object's
+ * character encoding.</p>
+ *
+ * @param byteStream The raw byte stream containing the document.
+ * @see #setPublicId
+ * @see #setSystemId
+ * @see #setEncoding
+ * @see #setByteStream
+ * @see #setCharacterStream
+ */
+ public InputSource (InputStream byteStream)
+ {
+ setByteStream(byteStream);
+ }
+
+
+ /**
+ * Create a new input source with a character stream.
+ *
+ * <p>Application writers should use setSystemId() to provide a base
+ * for resolving relative URIs, and may use setPublicId to include a
+ * public identifier.</p>
+ *
+ * <p>The character stream shall not include a byte order mark.</p>
+ *
+ * @see #setPublicId
+ * @see #setSystemId
+ * @see #setByteStream
+ * @see #setCharacterStream
+ */
+ public InputSource (Reader characterStream)
+ {
+ setCharacterStream(characterStream);
+ }
+
+
+ /**
+ * Set the public identifier for this input source.
+ *
+ * <p>The public identifier is always optional: if the application
+ * writer includes one, it will be provided as part of the
+ * location information.</p>
+ *
+ * @param publicId The public identifier as a string.
+ * @see #getPublicId
+ * @see org.xml.sax.Locator#getPublicId
+ * @see org.xml.sax.SAXParseException#getPublicId
+ */
+ public void setPublicId (String publicId)
+ {
+ this.publicId = publicId;
+ }
+
+
+ /**
+ * Get the public identifier for this input source.
+ *
+ * @return The public identifier, or null if none was supplied.
+ * @see #setPublicId
+ */
+ public String getPublicId ()
+ {
+ return publicId;
+ }
+
+
+ /**
+ * Set the system identifier for this input source.
+ *
+ * <p>The system identifier is optional if there is a byte stream
+ * or a character stream, but it is still useful to provide one,
+ * since the application can use it to resolve relative URIs
+ * and can include it in error messages and warnings (the parser
+ * will attempt to open a connection to the URI only if
+ * there is no byte stream or character stream specified).</p>
+ *
+ * <p>If the application knows the character encoding of the
+ * object pointed to by the system identifier, it can register
+ * the encoding using the setEncoding method.</p>
+ *
+ * <p>If the system identifier is a URL, it must be fully
+ * resolved (it may not be a relative URL).</p>
+ *
+ * @param systemId The system identifier as a string.
+ * @see #setEncoding
+ * @see #getSystemId
+ * @see org.xml.sax.Locator#getSystemId
+ * @see org.xml.sax.SAXParseException#getSystemId
+ */
+ public void setSystemId (String systemId)
+ {
+ this.systemId = systemId;
+ }
+
+
+ /**
+ * Get the system identifier for this input source.
+ *
+ * <p>The getEncoding method will return the character encoding
+ * of the object pointed to, or null if unknown.</p>
+ *
+ * <p>If the system ID is a URL, it will be fully resolved.</p>
+ *
+ * @return The system identifier, or null if none was supplied.
+ * @see #setSystemId
+ * @see #getEncoding
+ */
+ public String getSystemId ()
+ {
+ return systemId;
+ }
+
+
+ /**
+ * Set the byte stream for this input source.
+ *
+ * <p>The SAX parser will ignore this if there is also a character
+ * stream specified, but it will use a byte stream in preference
+ * to opening a URI connection itself.</p>
+ *
+ * <p>If the application knows the character encoding of the
+ * byte stream, it should set it with the setEncoding method.</p>
+ *
+ * @param byteStream A byte stream containing an XML document or
+ * other entity.
+ * @see #setEncoding
+ * @see #getByteStream
+ * @see #getEncoding
+ * @see java.io.InputStream
+ */
+ public void setByteStream (InputStream byteStream)
+ {
+ this.byteStream = byteStream;
+ }
+
+
+ /**
+ * Get the byte stream for this input source.
+ *
+ * <p>The getEncoding method will return the character
+ * encoding for this byte stream, or null if unknown.</p>
+ *
+ * @return The byte stream, or null if none was supplied.
+ * @see #getEncoding
+ * @see #setByteStream
+ */
+ public InputStream getByteStream ()
+ {
+ return byteStream;
+ }
+
+
+ /**
+ * Set the character encoding, if known.
+ *
+ * <p>The encoding must be a string acceptable for an
+ * XML encoding declaration (see section 4.3.3 of the XML 1.0
+ * recommendation).</p>
+ *
+ * <p>This method has no effect when the application provides a
+ * character stream.</p>
+ *
+ * @param encoding A string describing the character encoding.
+ * @see #setSystemId
+ * @see #setByteStream
+ * @see #getEncoding
+ */
+ public void setEncoding (String encoding)
+ {
+ this.encoding = encoding;
+ }
+
+
+ /**
+ * Get the character encoding for a byte stream or URI.
+ * This value will be ignored when the application provides a
+ * character stream.
+ *
+ * @return The encoding, or null if none was supplied.
+ * @see #setByteStream
+ * @see #getSystemId
+ * @see #getByteStream
+ */
+ public String getEncoding ()
+ {
+ return encoding;
+ }
+
+
+ /**
+ * Set the character stream for this input source.
+ *
+ * <p>If there is a character stream specified, the SAX parser
+ * will ignore any byte stream and will not attempt to open
+ * a URI connection to the system identifier.</p>
+ *
+ * @param characterStream The character stream containing the
+ * XML document or other entity.
+ * @see #getCharacterStream
+ * @see java.io.Reader
+ */
+ public void setCharacterStream (Reader characterStream)
+ {
+ this.characterStream = characterStream;
+ }
+
+
+ /**
+ * Get the character stream for this input source.
+ *
+ * @return The character stream, or null if none was supplied.
+ * @see #setCharacterStream
+ */
+ public Reader getCharacterStream ()
+ {
+ return characterStream;
+ }
+
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Internal state.
+ ////////////////////////////////////////////////////////////////////
+
+ private String publicId;
+ private String systemId;
+ private InputStream byteStream;
+ private String encoding;
+ private Reader characterStream;
+
+}
+
+// end of InputSource.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/jdk/internal/org/xml/sax/Locator.java Wed Dec 19 12:09:10 2012 +0000
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2000, 2005, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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 General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// SAX locator interface for document events.
+// http://www.saxproject.org
+// No warranty; no copyright -- use this as you will.
+// $Id: Locator.java,v 1.2 2004/11/03 22:55:32 jsuttor Exp $
+
+package jdk.internal.org.xml.sax;
+
+
+/**
+ * Interface for associating a SAX event with a document location.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
+ * for further information.
+ * </blockquote>
+ *
+ * <p>If a SAX parser provides location information to the SAX
+ * application, it does so by implementing this interface and then
+ * passing an instance to the application using the content
+ * handler's {@link org.xml.sax.ContentHandler#setDocumentLocator
+ * setDocumentLocator} method. The application can use the
+ * object to obtain the location of any other SAX event
+ * in the XML source document.</p>
+ *
+ * <p>Note that the results returned by the object will be valid only
+ * during the scope of each callback method: the application
+ * will receive unpredictable results if it attempts to use the
+ * locator at any other time, or after parsing completes.</p>
+ *
+ * <p>SAX parsers are not required to supply a locator, but they are
+ * very strongly encouraged to do so. If the parser supplies a
+ * locator, it must do so before reporting any other document events.
+ * If no locator has been set by the time the application receives
+ * the {@link org.xml.sax.ContentHandler#startDocument startDocument}
+ * event, the application should assume that a locator is not
+ * available.</p>
+ *
+ * @since SAX 1.0
+ * @author David Megginson
+ * @see org.xml.sax.ContentHandler#setDocumentLocator
+ */
+public interface Locator {
+
+
+ /**
+ * Return the public identifier for the current document event.
+ *
+ * <p>The return value is the public identifier of the document
+ * entity or of the external parsed entity in which the markup
+ * triggering the event appears.</p>
+ *
+ * @return A string containing the public identifier, or
+ * null if none is available.
+ * @see #getSystemId
+ */
+ public abstract String getPublicId ();
+
+
+ /**
+ * Return the system identifier for the current document event.
+ *
+ * <p>The return value is the system identifier of the document
+ * entity or of the external parsed entity in which the markup
+ * triggering the event appears.</p>
+ *
+ * <p>If the system identifier is a URL, the parser must resolve it
+ * fully before passing it to the application. For example, a file
+ * name must always be provided as a <em>file:...</em> URL, and other
+ * kinds of relative URI are also resolved against their bases.</p>
+ *
+ * @return A string containing the system identifier, or null
+ * if none is available.
+ * @see #getPublicId
+ */
+ public abstract String getSystemId ();
+
+
+ /**
+ * Return the line number where the current document event ends.
+ * Lines are delimited by line ends, which are defined in
+ * the XML specification.
+ *
+ * <p><strong>Warning:</strong> The return value from the method
+ * is intended only as an approximation for the sake of diagnostics;
+ * it is not intended to provide sufficient information
+ * to edit the character content of the original XML document.
+ * In some cases, these "line" numbers match what would be displayed
+ * as columns, and in others they may not match the source text
+ * due to internal entity expansion. </p>
+ *
+ * <p>The return value is an approximation of the line number
+ * in the document entity or external parsed entity where the
+ * markup triggering the event appears.</p>
+ *
+ * <p>If possible, the SAX driver should provide the line position
+ * of the first character after the text associated with the document
+ * event. The first line is line 1.</p>
+ *
+ * @return The line number, or -1 if none is available.
+ * @see #getColumnNumber
+ */
+ public abstract int getLineNumber ();
+
+
+ /**
+ * Return the column number where the current document event ends.
+ * This is one-based number of Java <code>char</code> values since
+ * the last line end.
+ *
+ * <p><strong>Warning:</strong> The return value from the method
+ * is intended only as an approximation for the sake of diagnostics;
+ * it is not intended to provide sufficient information
+ * to edit the character content of the original XML document.
+ * For example, when lines contain combining character sequences, wide
+ * characters, surrogate pairs, or bi-directional text, the value may
+ * not correspond to the column in a text editor's display. </p>
+ *
+ * <p>The return value is an approximation of the column number
+ * in the document entity or external parsed entity where the
+ * markup triggering the event appears.</p>
+ *
+ * <p>If possible, the SAX driver should provide the line position
+ * of the first character after the text associated with the document
+ * event. The first column in each line is column 1.</p>
+ *
+ * @return The column number, or -1 if none is available.
+ * @see #getLineNumber
+ */
+ public abstract int getColumnNumber ();
+
+}
+
+// end of Locator.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/jdk/internal/org/xml/sax/SAXException.java Wed Dec 19 12:09:10 2012 +0000
@@ -0,0 +1,188 @@
+/*
+ * Copyright (c) 2000, 2005, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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 General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// SAX exception class.
+// http://www.saxproject.org
+// No warranty; no copyright -- use this as you will.
+// $Id: SAXException.java,v 1.3 2004/11/03 22:55:32 jsuttor Exp $
+
+package jdk.internal.org.xml.sax;
+
+/**
+ * Encapsulate a general SAX error or warning.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
+ * for further information.
+ * </blockquote>
+ *
+ * <p>This class can contain basic error or warning information from
+ * either the XML parser or the application: a parser writer or
+ * application writer can subclass it to provide additional
+ * functionality. SAX handlers may throw this exception or
+ * any exception subclassed from it.</p>
+ *
+ * <p>If the application needs to pass through other types of
+ * exceptions, it must wrap those exceptions in a SAXException
+ * or an exception derived from a SAXException.</p>
+ *
+ * <p>If the parser or application needs to include information about a
+ * specific location in an XML document, it should use the
+ * {@link org.xml.sax.SAXParseException SAXParseException} subclass.</p>
+ *
+ * @since SAX 1.0
+ * @author David Megginson
+ * @version 2.0.1 (sax2r2)
+ * @see org.xml.sax.SAXParseException
+ */
+public class SAXException extends Exception {
+
+
+ /**
+ * Create a new SAXException.
+ */
+ public SAXException ()
+ {
+ super();
+ this.exception = null;
+ }
+
+
+ /**
+ * Create a new SAXException.
+ *
+ * @param message The error or warning message.
+ */
+ public SAXException (String message) {
+ super(message);
+ this.exception = null;
+ }
+
+
+ /**
+ * Create a new SAXException wrapping an existing exception.
+ *
+ * <p>The existing exception will be embedded in the new
+ * one, and its message will become the default message for
+ * the SAXException.</p>
+ *
+ * @param e The exception to be wrapped in a SAXException.
+ */
+ public SAXException (Exception e)
+ {
+ super();
+ this.exception = e;
+ }
+
+
+ /**
+ * Create a new SAXException from an existing exception.
+ *
+ * <p>The existing exception will be embedded in the new
+ * one, but the new exception will have its own message.</p>
+ *
+ * @param message The detail message.
+ * @param e The exception to be wrapped in a SAXException.
+ */
+ public SAXException (String message, Exception e)
+ {
+ super(message);
+ this.exception = e;
+ }
+
+
+ /**
+ * Return a detail message for this exception.
+ *
+ * <p>If there is an embedded exception, and if the SAXException
+ * has no detail message of its own, this method will return
+ * the detail message from the embedded exception.</p>
+ *
+ * @return The error or warning message.
+ */
+ public String getMessage ()
+ {
+ String message = super.getMessage();
+
+ if (message == null && exception != null) {
+ return exception.getMessage();
+ } else {
+ return message;
+ }
+ }
+
+
+ /**
+ * Return the embedded exception, if any.
+ *
+ * @return The embedded exception, or null if there is none.
+ */
+ public Exception getException ()
+ {
+ return exception;
+ }
+
+ /**
+ * Return the cause of the exception
+ *
+ * @return Return the cause of the exception
+ */
+ public Throwable getCause() {
+ return exception;
+ }
+
+ /**
+ * Override toString to pick up any embedded exception.
+ *
+ * @return A string representation of this exception.
+ */
+ public String toString ()
+ {
+ if (exception != null) {
+ return super.toString() + "\n" + exception.toString();
+ } else {
+ return super.toString();
+ }
+ }
+
+
+
+ //////////////////////////////////////////////////////////////////////
+ // Internal state.
+ //////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * @serial The embedded exception if tunnelling, or null.
+ */
+ private Exception exception;
+
+ // Added serialVersionUID to preserve binary compatibility
+ static final long serialVersionUID = 583241635256073760L;
+}
+
+// end of SAXException.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/jdk/internal/org/xml/sax/SAXNotRecognizedException.java Wed Dec 19 12:09:10 2012 +0000
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2000, 2005, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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 General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// SAXNotRecognizedException.java - unrecognized feature or value.
+// http://www.saxproject.org
+// Written by David Megginson
+// NO WARRANTY! This class is in the Public Domain.
+// $Id: SAXNotRecognizedException.java,v 1.3 2004/11/03 22:55:32 jsuttor Exp $
+
+package jdk.internal.org.xml.sax;
+
+
+/**
+ * Exception class for an unrecognized identifier.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
+ * for further information.
+ * </blockquote>
+ *
+ * <p>An XMLReader will throw this exception when it finds an
+ * unrecognized feature or property identifier; SAX applications and
+ * extensions may use this class for other, similar purposes.</p>
+ *
+ * @since SAX 2.0
+ * @author David Megginson
+ * @see org.xml.sax.SAXNotSupportedException
+ */
+public class SAXNotRecognizedException extends SAXException
+{
+
+ /**
+ * Default constructor.
+ */
+ public SAXNotRecognizedException ()
+ {
+ super();
+ }
+
+
+ /**
+ * Construct a new exception with the given message.
+ *
+ * @param message The text message of the exception.
+ */
+ public SAXNotRecognizedException (String message)
+ {
+ super(message);
+ }
+
+ // Added serialVersionUID to preserve binary compatibility
+ static final long serialVersionUID = 5440506620509557213L;
+}
+
+// end of SAXNotRecognizedException.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/jdk/internal/org/xml/sax/SAXNotSupportedException.java Wed Dec 19 12:09:10 2012 +0000
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2000, 2005, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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 General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// SAXNotSupportedException.java - unsupported feature or value.
+// http://www.saxproject.org
+// Written by David Megginson
+// NO WARRANTY! This class is in the Public Domain.
+// $Id: SAXNotSupportedException.java,v 1.4 2004/11/03 22:55:32 jsuttor Exp $
+
+package jdk.internal.org.xml.sax;
+
+/**
+ * Exception class for an unsupported operation.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
+ * for further information.
+ * </blockquote>
+ *
+ * <p>An XMLReader will throw this exception when it recognizes a
+ * feature or property identifier, but cannot perform the requested
+ * operation (setting a state or value). Other SAX2 applications and
+ * extensions may use this class for similar purposes.</p>
+ *
+ * @since SAX 2.0
+ * @author David Megginson
+ * @see org.xml.sax.SAXNotRecognizedException
+ */
+public class SAXNotSupportedException extends SAXException
+{
+
+ /**
+ * Construct a new exception with no message.
+ */
+ public SAXNotSupportedException ()
+ {
+ super();
+ }
+
+
+ /**
+ * Construct a new exception with the given message.
+ *
+ * @param message The text message of the exception.
+ */
+ public SAXNotSupportedException (String message)
+ {
+ super(message);
+ }
+
+ // Added serialVersionUID to preserve binary compatibility
+ static final long serialVersionUID = -1422818934641823846L;
+}
+
+// end of SAXNotSupportedException.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/jdk/internal/org/xml/sax/SAXParseException.java Wed Dec 19 12:09:10 2012 +0000
@@ -0,0 +1,313 @@
+/*
+ * Copyright (c) 2000, 2005, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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 General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// SAX exception class.
+// http://www.saxproject.org
+// No warranty; no copyright -- use this as you will.
+// $Id: SAXParseException.java,v 1.2 2004/11/03 22:55:32 jsuttor Exp $
+
+package jdk.internal.org.xml.sax;
+
+/**
+ * Encapsulate an XML parse error or warning.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
+ * for further information.
+ * </blockquote>
+ *
+ * <p>This exception may include information for locating the error
+ * in the original XML document, as if it came from a {@link Locator}
+ * object. Note that although the application
+ * will receive a SAXParseException as the argument to the handlers
+ * in the {@link org.xml.sax.ErrorHandler ErrorHandler} interface,
+ * the application is not actually required to throw the exception;
+ * instead, it can simply read the information in it and take a
+ * different action.</p>
+ *
+ * <p>Since this exception is a subclass of {@link org.xml.sax.SAXException
+ * SAXException}, it inherits the ability to wrap another exception.</p>
+ *
+ * @since SAX 1.0
+ * @author David Megginson
+ * @version 2.0.1 (sax2r2)
+ * @see org.xml.sax.SAXException
+ * @see org.xml.sax.Locator
+ * @see org.xml.sax.ErrorHandler
+ */
+public class SAXParseException extends SAXException {
+
+
+ //////////////////////////////////////////////////////////////////////
+ // Constructors.
+ //////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * Create a new SAXParseException from a message and a Locator.
+ *
+ * <p>This constructor is especially useful when an application is
+ * creating its own exception from within a {@link org.xml.sax.ContentHandler
+ * ContentHandler} callback.</p>
+ *
+ * @param message The error or warning message.
+ * @param locator The locator object for the error or warning (may be
+ * null).
+ * @see org.xml.sax.Locator
+ */
+ public SAXParseException (String message, Locator locator) {
+ super(message);
+ if (locator != null) {
+ init(locator.getPublicId(), locator.getSystemId(),
+ locator.getLineNumber(), locator.getColumnNumber());
+ } else {
+ init(null, null, -1, -1);
+ }
+ }
+
+
+ /**
+ * Wrap an existing exception in a SAXParseException.
+ *
+ * <p>This constructor is especially useful when an application is
+ * creating its own exception from within a {@link org.xml.sax.ContentHandler
+ * ContentHandler} callback, and needs to wrap an existing exception that is not a
+ * subclass of {@link org.xml.sax.SAXException SAXException}.</p>
+ *
+ * @param message The error or warning message, or null to
+ * use the message from the embedded exception.
+ * @param locator The locator object for the error or warning (may be
+ * null).
+ * @param e Any exception.
+ * @see org.xml.sax.Locator
+ */
+ public SAXParseException (String message, Locator locator,
+ Exception e) {
+ super(message, e);
+ if (locator != null) {
+ init(locator.getPublicId(), locator.getSystemId(),
+ locator.getLineNumber(), locator.getColumnNumber());
+ } else {
+ init(null, null, -1, -1);
+ }
+ }
+
+
+ /**
+ * Create a new SAXParseException.
+ *
+ * <p>This constructor is most useful for parser writers.</p>
+ *
+ * <p>All parameters except the message are as if
+ * they were provided by a {@link Locator}. For example, if the
+ * system identifier is a URL (including relative filename), the
+ * caller must resolve it fully before creating the exception.</p>
+ *
+ *
+ * @param message The error or warning message.
+ * @param publicId The public identifier of the entity that generated
+ * the error or warning.
+ * @param systemId The system identifier of the entity that generated
+ * the error or warning.
+ * @param lineNumber The line number of the end of the text that
+ * caused the error or warning.
+ * @param columnNumber The column number of the end of the text that
+ * cause the error or warning.
+ */
+ public SAXParseException (String message, String publicId, String systemId,
+ int lineNumber, int columnNumber)
+ {
+ super(message);
+ init(publicId, systemId, lineNumber, columnNumber);
+ }
+
+
+ /**
+ * Create a new SAXParseException with an embedded exception.
+ *
+ * <p>This constructor is most useful for parser writers who
+ * need to wrap an exception that is not a subclass of
+ * {@link org.xml.sax.SAXException SAXException}.</p>
+ *
+ * <p>All parameters except the message and exception are as if
+ * they were provided by a {@link Locator}. For example, if the
+ * system identifier is a URL (including relative filename), the
+ * caller must resolve it fully before creating the exception.</p>
+ *
+ * @param message The error or warning message, or null to use
+ * the message from the embedded exception.
+ * @param publicId The public identifier of the entity that generated
+ * the error or warning.
+ * @param systemId The system identifier of the entity that generated
+ * the error or warning.
+ * @param lineNumber The line number of the end of the text that
+ * caused the error or warning.
+ * @param columnNumber The column number of the end of the text that
+ * cause the error or warning.
+ * @param e Another exception to embed in this one.
+ */
+ public SAXParseException (String message, String publicId, String systemId,
+ int lineNumber, int columnNumber, Exception e)
+ {
+ super(message, e);
+ init(publicId, systemId, lineNumber, columnNumber);
+ }
+
+
+ /**
+ * Internal initialization method.
+ *
+ * @param publicId The public identifier of the entity which generated the exception,
+ * or null.
+ * @param systemId The system identifier of the entity which generated the exception,
+ * or null.
+ * @param lineNumber The line number of the error, or -1.
+ * @param columnNumber The column number of the error, or -1.
+ */
+ private void init (String publicId, String systemId,
+ int lineNumber, int columnNumber)
+ {
+ this.publicId = publicId;
+ this.systemId = systemId;
+ this.lineNumber = lineNumber;
+ this.columnNumber = columnNumber;
+ }
+
+
+ /**
+ * Get the public identifier of the entity where the exception occurred.
+ *
+ * @return A string containing the public identifier, or null
+ * if none is available.
+ * @see org.xml.sax.Locator#getPublicId
+ */
+ public String getPublicId ()
+ {
+ return this.publicId;
+ }
+
+
+ /**
+ * Get the system identifier of the entity where the exception occurred.
+ *
+ * <p>If the system identifier is a URL, it will have been resolved
+ * fully.</p>
+ *
+ * @return A string containing the system identifier, or null
+ * if none is available.
+ * @see org.xml.sax.Locator#getSystemId
+ */
+ public String getSystemId ()
+ {
+ return this.systemId;
+ }
+
+
+ /**
+ * The line number of the end of the text where the exception occurred.
+ *
+ * <p>The first line is line 1.</p>
+ *
+ * @return An integer representing the line number, or -1
+ * if none is available.
+ * @see org.xml.sax.Locator#getLineNumber
+ */
+ public int getLineNumber ()
+ {
+ return this.lineNumber;
+ }
+
+
+ /**
+ * The column number of the end of the text where the exception occurred.
+ *
+ * <p>The first column in a line is position 1.</p>
+ *
+ * @return An integer representing the column number, or -1
+ * if none is available.
+ * @see org.xml.sax.Locator#getColumnNumber
+ */
+ public int getColumnNumber ()
+ {
+ return this.columnNumber;
+ }
+
+ /**
+ * Override toString to provide more detailed error message.
+ *
+ * @return A string representation of this exception.
+ */
+ public String toString() {
+ StringBuilder buf = new StringBuilder(getClass().getName());
+ String message = getLocalizedMessage();
+ if (publicId!=null) buf.append("publicId: ").append(publicId);
+ if (systemId!=null) buf.append("; systemId: ").append(systemId);
+ if (lineNumber!=-1) buf.append("; lineNumber: ").append(lineNumber);
+ if (columnNumber!=-1) buf.append("; columnNumber: ").append(columnNumber);
+
+ //append the exception message at the end
+ if (message!=null) buf.append("; ").append(message);
+ return buf.toString();
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ // Internal state.
+ //////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * @serial The public identifier, or null.
+ * @see #getPublicId
+ */
+ private String publicId;
+
+
+ /**
+ * @serial The system identifier, or null.
+ * @see #getSystemId
+ */
+ private String systemId;
+
+
+ /**
+ * @serial The line number, or -1.
+ * @see #getLineNumber
+ */
+ private int lineNumber;
+
+
+ /**
+ * @serial The column number, or -1.
+ * @see #getColumnNumber
+ */
+ private int columnNumber;
+
+ // Added serialVersionUID to preserve binary compatibility
+ static final long serialVersionUID = -5651165872476709336L;
+}
+
+// end of SAXParseException.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/jdk/internal/org/xml/sax/XMLReader.java Wed Dec 19 12:09:10 2012 +0000
@@ -0,0 +1,428 @@
+/*
+ * Copyright (c) 2000, 2005, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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 General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// XMLReader.java - read an XML document.
+// http://www.saxproject.org
+// Written by David Megginson
+// NO WARRANTY! This class is in the Public Domain.
+// $Id: XMLReader.java,v 1.3 2004/11/03 22:55:32 jsuttor Exp $
+
+package jdk.internal.org.xml.sax;
+
+import java.io.IOException;
+
+
+/**
+ * Interface for reading an XML document using callbacks.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
+ * for further information.
+ * </blockquote>
+ *
+ * <p><strong>Note:</strong> despite its name, this interface does
+ * <em>not</em> extend the standard Java {@link java.io.Reader Reader}
+ * interface, because reading XML is a fundamentally different activity
+ * than reading character data.</p>
+ *
+ * <p>XMLReader is the interface that an XML parser's SAX2 driver must
+ * implement. This interface allows an application to set and
+ * query features and properties in the parser, to register
+ * event handlers for document processing, and to initiate
+ * a document parse.</p>
+ *
+ * <p>All SAX interfaces are assumed to be synchronous: the
+ * {@link #parse parse} methods must not return until parsing
+ * is complete, and readers must wait for an event-handler callback
+ * to return before reporting the next event.</p>
+ *
+ * <p>This interface replaces the (now deprecated) SAX 1.0 {@link
+ * org.xml.sax.Parser Parser} interface. The XMLReader interface
+ * contains two important enhancements over the old Parser
+ * interface (as well as some minor ones):</p>
+ *
+ * <ol>
+ * <li>it adds a standard way to query and set features and
+ * properties; and</li>
+ * <li>it adds Namespace support, which is required for many
+ * higher-level XML standards.</li>
+ * </ol>
+ *
+ * <p>There are adapters available to convert a SAX1 Parser to
+ * a SAX2 XMLReader and vice-versa.</p>
+ *
+ * @since SAX 2.0
+ * @author David Megginson
+ * @see org.xml.sax.XMLFilter
+ * @see org.xml.sax.helpers.ParserAdapter
+ * @see org.xml.sax.helpers.XMLReaderAdapter
+ */
+public interface XMLReader
+{
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Configuration.
+ ////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * Look up the value of a feature flag.
+ *
+ * <p>The feature name is any fully-qualified URI. It is
+ * possible for an XMLReader to recognize a feature name but
+ * temporarily be unable to return its value.
+ * Some feature values may be available only in specific
+ * contexts, such as before, during, or after a parse.
+ * Also, some feature values may not be programmatically accessible.
+ * (In the case of an adapter for SAX1 {@link Parser}, there is no
+ * implementation-independent way to expose whether the underlying
+ * parser is performing validation, expanding external entities,
+ * and so forth.) </p>
+ *
+ * <p>All XMLReaders are required to recognize the
+ * http://xml.org/sax/features/namespaces and the
+ * http://xml.org/sax/features/namespace-prefixes feature names.</p>
+ *
+ * <p>Typical usage is something like this:</p>
+ *
+ * <pre>
+ * XMLReader r = new MySAXDriver();
+ *
+ * // try to activate validation
+ * try {
+ * r.setFeature("http://xml.org/sax/features/validation", true);
+ * } catch (SAXException e) {
+ * System.err.println("Cannot activate validation.");
+ * }
+ *
+ * // register event handlers
+ * r.setContentHandler(new MyContentHandler());
+ * r.setErrorHandler(new MyErrorHandler());
+ *
+ * // parse the first document
+ * try {
+ * r.parse("http://www.foo.com/mydoc.xml");
+ * } catch (IOException e) {
+ * System.err.println("I/O exception reading XML document");
+ * } catch (SAXException e) {
+ * System.err.println("XML exception reading document.");
+ * }
+ * </pre>
+ *
+ * <p>Implementors are free (and encouraged) to invent their own features,
+ * using names built on their own URIs.</p>
+ *
+ * @param name The feature name, which is a fully-qualified URI.
+ * @return The current value of the feature (true or false).
+ * @exception org.xml.sax.SAXNotRecognizedException If the feature
+ * value can't be assigned or retrieved.
+ * @exception org.xml.sax.SAXNotSupportedException When the
+ * XMLReader recognizes the feature name but
+ * cannot determine its value at this time.
+ * @see #setFeature
+ */
+ public boolean getFeature (String name)
+ throws SAXNotRecognizedException, SAXNotSupportedException;
+
+
+ /**
+ * Set the value of a feature flag.
+ *
+ * <p>The feature name is any fully-qualified URI. It is
+ * possible for an XMLReader to expose a feature value but
+ * to be unable to change the current value.
+ * Some feature values may be immutable or mutable only
+ * in specific contexts, such as before, during, or after
+ * a parse.</p>
+ *
+ * <p>All XMLReaders are required to support setting
+ * http://xml.org/sax/features/namespaces to true and
+ * http://xml.org/sax/features/namespace-prefixes to false.</p>
+ *
+ * @param name The feature name, which is a fully-qualified URI.
+ * @param value The requested value of the feature (true or false).
+ * @exception org.xml.sax.SAXNotRecognizedException If the feature
+ * value can't be assigned or retrieved.
+ * @exception org.xml.sax.SAXNotSupportedException When the
+ * XMLReader recognizes the feature name but
+ * cannot set the requested value.
+ * @see #getFeature
+ */
+ public void setFeature (String name, boolean value)
+ throws SAXNotRecognizedException, SAXNotSupportedException;
+
+
+ /**
+ * Look up the value of a property.
+ *
+ * <p>The property name is any fully-qualified URI. It is
+ * possible for an XMLReader to recognize a property name but
+ * temporarily be unable to return its value.
+ * Some property values may be available only in specific
+ * contexts, such as before, during, or after a parse.</p>
+ *
+ * <p>XMLReaders are not required to recognize any specific
+ * property names, though an initial core set is documented for
+ * SAX2.</p>
+ *
+ * <p>Implementors are free (and encouraged) to invent their own properties,
+ * using names built on their own URIs.</p>
+ *
+ * @param name The property name, which is a fully-qualified URI.
+ * @return The current value of the property.
+ * @exception org.xml.sax.SAXNotRecognizedException If the property
+ * value can't be assigned or retrieved.
+ * @exception org.xml.sax.SAXNotSupportedException When the
+ * XMLReader recognizes the property name but
+ * cannot determine its value at this time.
+ * @see #setProperty
+ */
+ public Object getProperty (String name)
+ throws SAXNotRecognizedException, SAXNotSupportedException;
+
+
+ /**
+ * Set the value of a property.
+ *
+ * <p>The property name is any fully-qualified URI. It is
+ * possible for an XMLReader to recognize a property name but
+ * to be unable to change the current value.
+ * Some property values may be immutable or mutable only
+ * in specific contexts, such as before, during, or after
+ * a parse.</p>
+ *
+ * <p>XMLReaders are not required to recognize setting
+ * any specific property names, though a core set is defined by
+ * SAX2.</p>
+ *
+ * <p>This method is also the standard mechanism for setting
+ * extended handlers.</p>
+ *
+ * @param name The property name, which is a fully-qualified URI.
+ * @param value The requested value for the property.
+ * @exception org.xml.sax.SAXNotRecognizedException If the property
+ * value can't be assigned or retrieved.
+ * @exception org.xml.sax.SAXNotSupportedException When the
+ * XMLReader recognizes the property name but
+ * cannot set the requested value.
+ */
+ public void setProperty (String name, Object value)
+ throws SAXNotRecognizedException, SAXNotSupportedException;
+
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Event handlers.
+ ////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * Allow an application to register an entity resolver.
+ *
+ * <p>If the application does not register an entity resolver,
+ * the XMLReader will perform its own default resolution.</p>
+ *
+ * <p>Applications may register a new or different resolver in the
+ * middle of a parse, and the SAX parser must begin using the new
+ * resolver immediately.</p>
+ *
+ * @param resolver The entity resolver.
+ * @see #getEntityResolver
+ */
+ public void setEntityResolver (EntityResolver resolver);
+
+
+ /**
+ * Return the current entity resolver.
+ *
+ * @return The current entity resolver, or null if none
+ * has been registered.
+ * @see #setEntityResolver
+ */
+ public EntityResolver getEntityResolver ();
+
+
+ /**
+ * Allow an application to register a DTD event handler.
+ *
+ * <p>If the application does not register a DTD handler, all DTD
+ * events reported by the SAX parser will be silently ignored.</p>
+ *
+ * <p>Applications may register a new or different handler in the
+ * middle of a parse, and the SAX parser must begin using the new
+ * handler immediately.</p>
+ *
+ * @param handler The DTD handler.
+ * @see #getDTDHandler
+ */
+ public void setDTDHandler (DTDHandler handler);
+
+
+ /**
+ * Return the current DTD handler.
+ *
+ * @return The current DTD handler, or null if none
+ * has been registered.
+ * @see #setDTDHandler
+ */
+ public DTDHandler getDTDHandler ();
+
+
+ /**
+ * Allow an application to register a content event handler.
+ *
+ * <p>If the application does not register a content handler, all
+ * content events reported by the SAX parser will be silently
+ * ignored.</p>
+ *
+ * <p>Applications may register a new or different handler in the
+ * middle of a parse, and the SAX parser must begin using the new
+ * handler immediately.</p>
+ *
+ * @param handler The content handler.
+ * @see #getContentHandler
+ */
+ public void setContentHandler (ContentHandler handler);
+
+
+ /**
+ * Return the current content handler.
+ *
+ * @return The current content handler, or null if none
+ * has been registered.
+ * @see #setContentHandler
+ */
+ public ContentHandler getContentHandler ();
+
+
+ /**
+ * Allow an application to register an error event handler.
+ *
+ * <p>If the application does not register an error handler, all
+ * error events reported by the SAX parser will be silently
+ * ignored; however, normal processing may not continue. It is
+ * highly recommended that all SAX applications implement an
+ * error handler to avoid unexpected bugs.</p>
+ *
+ * <p>Applications may register a new or different handler in the
+ * middle of a parse, and the SAX parser must begin using the new
+ * handler immediately.</p>
+ *
+ * @param handler The error handler.
+ * @see #getErrorHandler
+ */
+ public void setErrorHandler (ErrorHandler handler);
+
+
+ /**
+ * Return the current error handler.
+ *
+ * @return The current error handler, or null if none
+ * has been registered.
+ * @see #setErrorHandler
+ */
+ public ErrorHandler getErrorHandler ();
+
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Parsing.
+ ////////////////////////////////////////////////////////////////////
+
+ /**
+ * Parse an XML document.
+ *
+ * <p>The application can use this method to instruct the XML
+ * reader to begin parsing an XML document from any valid input
+ * source (a character stream, a byte stream, or a URI).</p>
+ *
+ * <p>Applications may not invoke this method while a parse is in
+ * progress (they should create a new XMLReader instead for each
+ * nested XML document). Once a parse is complete, an
+ * application may reuse the same XMLReader object, possibly with a
+ * different input source.
+ * Configuration of the XMLReader object (such as handler bindings and
+ * values established for feature flags and properties) is unchanged
+ * by completion of a parse, unless the definition of that aspect of
+ * the configuration explicitly specifies other behavior.
+ * (For example, feature flags or properties exposing
+ * characteristics of the document being parsed.)
+ * </p>
+ *
+ * <p>During the parse, the XMLReader will provide information
+ * about the XML document through the registered event
+ * handlers.</p>
+ *
+ * <p>This method is synchronous: it will not return until parsing
+ * has ended. If a client application wants to terminate
+ * parsing early, it should throw an exception.</p>
+ *
+ * @param input The input source for the top-level of the
+ * XML document.
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @exception java.io.IOException An IO exception from the parser,
+ * possibly from a byte stream or character stream
+ * supplied by the application.
+ * @see org.xml.sax.InputSource
+ * @see #parse(java.lang.String)
+ * @see #setEntityResolver
+ * @see #setDTDHandler
+ * @see #setContentHandler
+ * @see #setErrorHandler
+ */
+ public void parse (InputSource input)
+ throws IOException, SAXException;
+
+
+ /**
+ * Parse an XML document from a system identifier (URI).
+ *
+ * <p>This method is a shortcut for the common case of reading a
+ * document from a system identifier. It is the exact
+ * equivalent of the following:</p>
+ *
+ * <pre>
+ * parse(new InputSource(systemId));
+ * </pre>
+ *
+ * <p>If the system identifier is a URL, it must be fully resolved
+ * by the application before it is passed to the parser.</p>
+ *
+ * @param systemId The system identifier (URI).
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @exception java.io.IOException An IO exception from the parser,
+ * possibly from a byte stream or character stream
+ * supplied by the application.
+ * @see #parse(org.xml.sax.InputSource)
+ */
+ public void parse (String systemId)
+ throws IOException, SAXException;
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/jdk/internal/org/xml/sax/helpers/DefaultHandler.java Wed Dec 19 12:09:10 2012 +0000
@@ -0,0 +1,491 @@
+/*
+ * Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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 General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// DefaultHandler.java - default implementation of the core handlers.
+// http://www.saxproject.org
+// Written by David Megginson
+// NO WARRANTY! This class is in the public domain.
+// $Id: DefaultHandler.java,v 1.3 2006/04/13 02:06:32 jeffsuttor Exp $
+
+package jdk.internal.org.xml.sax.helpers;
+
+import java.io.IOException;
+
+import jdk.internal.org.xml.sax.InputSource;
+import jdk.internal.org.xml.sax.Locator;
+import jdk.internal.org.xml.sax.Attributes;
+import jdk.internal.org.xml.sax.EntityResolver;
+import jdk.internal.org.xml.sax.DTDHandler;
+import jdk.internal.org.xml.sax.ContentHandler;
+import jdk.internal.org.xml.sax.ErrorHandler;
+import jdk.internal.org.xml.sax.SAXException;
+import jdk.internal.org.xml.sax.SAXParseException;
+
+
+/**
+ * Default base class for SAX2 event handlers.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
+ * for further information.
+ * </blockquote>
+ *
+ * <p>This class is available as a convenience base class for SAX2
+ * applications: it provides default implementations for all of the
+ * callbacks in the four core SAX2 handler classes:</p>
+ *
+ * <ul>
+ * <li>{@link org.xml.sax.EntityResolver EntityResolver}</li>
+ * <li>{@link org.xml.sax.DTDHandler DTDHandler}</li>
+ * <li>{@link org.xml.sax.ContentHandler ContentHandler}</li>
+ * <li>{@link org.xml.sax.ErrorHandler ErrorHandler}</li>
+ * </ul>
+ *
+ * <p>Application writers can extend this class when they need to
+ * implement only part of an interface; parser writers can
+ * instantiate this class to provide default handlers when the
+ * application has not supplied its own.</p>
+ *
+ * <p>This class replaces the deprecated SAX1
+ * {@link org.xml.sax.HandlerBase HandlerBase} class.</p>
+ *
+ * @since SAX 2.0
+ * @author David Megginson,
+ * @see org.xml.sax.EntityResolver
+ * @see org.xml.sax.DTDHandler
+ * @see org.xml.sax.ContentHandler
+ * @see org.xml.sax.ErrorHandler
+ */
+public class DefaultHandler
+ implements EntityResolver, DTDHandler, ContentHandler, ErrorHandler
+{
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Default implementation of the EntityResolver interface.
+ ////////////////////////////////////////////////////////////////////
+
+ /**
+ * Resolve an external entity.
+ *
+ * <p>Always return null, so that the parser will use the system
+ * identifier provided in the XML document. This method implements
+ * the SAX default behaviour: application writers can override it
+ * in a subclass to do special translations such as catalog lookups
+ * or URI redirection.</p>
+ *
+ * @param publicId The public identifier, or null if none is
+ * available.
+ * @param systemId The system identifier provided in the XML
+ * document.
+ * @return The new input source, or null to require the
+ * default behaviour.
+ * @exception java.io.IOException If there is an error setting
+ * up the new input source.
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @see org.xml.sax.EntityResolver#resolveEntity
+ */
+ public InputSource resolveEntity (String publicId, String systemId)
+ throws IOException, SAXException
+ {
+ return null;
+ }
+
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Default implementation of DTDHandler interface.
+ ////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * Receive notification of a notation declaration.
+ *
+ * <p>By default, do nothing. Application writers may override this
+ * method in a subclass if they wish to keep track of the notations
+ * declared in a document.</p>
+ *
+ * @param name The notation name.
+ * @param publicId The notation public identifier, or null if not
+ * available.
+ * @param systemId The notation system identifier.
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @see org.xml.sax.DTDHandler#notationDecl
+ */
+ public void notationDecl (String name, String publicId, String systemId)
+ throws SAXException
+ {
+ // no op
+ }
+
+
+ /**
+ * Receive notification of an unparsed entity declaration.
+ *
+ * <p>By default, do nothing. Application writers may override this
+ * method in a subclass to keep track of the unparsed entities
+ * declared in a document.</p>
+ *
+ * @param name The entity name.
+ * @param publicId The entity public identifier, or null if not
+ * available.
+ * @param systemId The entity system identifier.
+ * @param notationName The name of the associated notation.
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @see org.xml.sax.DTDHandler#unparsedEntityDecl
+ */
+ public void unparsedEntityDecl (String name, String publicId,
+ String systemId, String notationName)
+ throws SAXException
+ {
+ // no op
+ }
+
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Default implementation of ContentHandler interface.
+ ////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * Receive a Locator object for document events.
+ *
+ * <p>By default, do nothing. Application writers may override this
+ * method in a subclass if they wish to store the locator for use
+ * with other document events.</p>
+ *
+ * @param locator A locator for all SAX document events.
+ * @see org.xml.sax.ContentHandler#setDocumentLocator
+ * @see org.xml.sax.Locator
+ */
+ public void setDocumentLocator (Locator locator)
+ {
+ // no op
+ }
+
+
+ /**
+ * Receive notification of the beginning of the document.
+ *
+ * <p>By default, do nothing. Application writers may override this
+ * method in a subclass to take specific actions at the beginning
+ * of a document (such as allocating the root node of a tree or
+ * creating an output file).</p>
+ *
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @see org.xml.sax.ContentHandler#startDocument
+ */
+ public void startDocument ()
+ throws SAXException
+ {
+ // no op
+ }
+
+
+ /**
+ * Receive notification of the end of the document.
+ *
+ * <p>By default, do nothing. Application writers may override this
+ * method in a subclass to take specific actions at the end
+ * of a document (such as finalising a tree or closing an output
+ * file).</p>
+ *
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @see org.xml.sax.ContentHandler#endDocument
+ */
+ public void endDocument ()
+ throws SAXException
+ {
+ // no op
+ }
+
+
+ /**
+ * Receive notification of the start of a Namespace mapping.
+ *
+ * <p>By default, do nothing. Application writers may override this
+ * method in a subclass to take specific actions at the start of
+ * each Namespace prefix scope (such as storing the prefix mapping).</p>
+ *
+ * @param prefix The Namespace prefix being declared.
+ * @param uri The Namespace URI mapped to the prefix.
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @see org.xml.sax.ContentHandler#startPrefixMapping
+ */
+ public void startPrefixMapping (String prefix, String uri)
+ throws SAXException
+ {
+ // no op
+ }
+
+
+ /**
+ * Receive notification of the end of a Namespace mapping.
+ *
+ * <p>By default, do nothing. Application writers may override this
+ * method in a subclass to take specific actions at the end of
+ * each prefix mapping.</p>
+ *
+ * @param prefix The Namespace prefix being declared.
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @see org.xml.sax.ContentHandler#endPrefixMapping
+ */
+ public void endPrefixMapping (String prefix)
+ throws SAXException
+ {
+ // no op
+ }
+
+
+ /**
+ * Receive notification of the start of an element.
+ *
+ * <p>By default, do nothing. Application writers may override this
+ * method in a subclass to take specific actions at the start of
+ * each element (such as allocating a new tree node or writing
+ * output to a file).</p>
+ *
+ * @param uri The Namespace URI, or the empty string if the
+ * element has no Namespace URI or if Namespace
+ * processing is not being performed.
+ * @param localName The local name (without prefix), or the
+ * empty string if Namespace processing is not being
+ * performed.
+ * @param qName The qualified name (with prefix), or the
+ * empty string if qualified names are not available.
+ * @param attributes The attributes attached to the element. If
+ * there are no attributes, it shall be an empty
+ * Attributes object.
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @see org.xml.sax.ContentHandler#startElement
+ */
+ public void startElement (String uri, String localName,
+ String qName, Attributes attributes)
+ throws SAXException
+ {
+ // no op
+ }
+
+
+ /**
+ * Receive notification of the end of an element.
+ *
+ * <p>By default, do nothing. Application writers may override this
+ * method in a subclass to take specific actions at the end of
+ * each element (such as finalising a tree node or writing
+ * output to a file).</p>
+ *
+ * @param uri The Namespace URI, or the empty string if the
+ * element has no Namespace URI or if Namespace
+ * processing is not being performed.
+ * @param localName The local name (without prefix), or the
+ * empty string if Namespace processing is not being
+ * performed.
+ * @param qName The qualified name (with prefix), or the
+ * empty string if qualified names are not available.
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @see org.xml.sax.ContentHandler#endElement
+ */
+ public void endElement (String uri, String localName, String qName)
+ throws SAXException
+ {
+ // no op
+ }
+
+
+ /**
+ * Receive notification of character data inside an element.
+ *
+ * <p>By default, do nothing. Application writers may override this
+ * method to take specific actions for each chunk of character data
+ * (such as adding the data to a node or buffer, or printing it to
+ * a file).</p>
+ *
+ * @param ch The characters.
+ * @param start The start position in the character array.
+ * @param length The number of characters to use from the
+ * character array.
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @see org.xml.sax.ContentHandler#characters
+ */
+ public void characters (char ch[], int start, int length)
+ throws SAXException
+ {
+ // no op
+ }
+
+
+ /**
+ * Receive notification of ignorable whitespace in element content.
+ *
+ * <p>By default, do nothing. Application writers may override this
+ * method to take specific actions for each chunk of ignorable
+ * whitespace (such as adding data to a node or buffer, or printing
+ * it to a file).</p>
+ *
+ * @param ch The whitespace characters.
+ * @param start The start position in the character array.
+ * @param length The number of characters to use from the
+ * character array.
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @see org.xml.sax.ContentHandler#ignorableWhitespace
+ */
+ public void ignorableWhitespace (char ch[], int start, int length)
+ throws SAXException
+ {
+ // no op
+ }
+
+
+ /**
+ * Receive notification of a processing instruction.
+ *
+ * <p>By default, do nothing. Application writers may override this
+ * method in a subclass to take specific actions for each
+ * processing instruction, such as setting status variables or
+ * invoking other methods.</p>
+ *
+ * @param target The processing instruction target.
+ * @param data The processing instruction data, or null if
+ * none is supplied.
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @see org.xml.sax.ContentHandler#processingInstruction
+ */
+ public void processingInstruction (String target, String data)
+ throws SAXException
+ {
+ // no op
+ }
+
+
+ /**
+ * Receive notification of a skipped entity.
+ *
+ * <p>By default, do nothing. Application writers may override this
+ * method in a subclass to take specific actions for each
+ * processing instruction, such as setting status variables or
+ * invoking other methods.</p>
+ *
+ * @param name The name of the skipped entity.
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @see org.xml.sax.ContentHandler#processingInstruction
+ */
+ public void skippedEntity (String name)
+ throws SAXException
+ {
+ // no op
+ }
+
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Default implementation of the ErrorHandler interface.
+ ////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * Receive notification of a parser warning.
+ *
+ * <p>The default implementation does nothing. Application writers
+ * may override this method in a subclass to take specific actions
+ * for each warning, such as inserting the message in a log file or
+ * printing it to the console.</p>
+ *
+ * @param e The warning information encoded as an exception.
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @see org.xml.sax.ErrorHandler#warning
+ * @see org.xml.sax.SAXParseException
+ */
+ public void warning (SAXParseException e)
+ throws SAXException
+ {
+ // no op
+ }
+
+
+ /**
+ * Receive notification of a recoverable parser error.
+ *
+ * <p>The default implementation does nothing. Application writers
+ * may override this method in a subclass to take specific actions
+ * for each error, such as inserting the message in a log file or
+ * printing it to the console.</p>
+ *
+ * @param e The error information encoded as an exception.
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @see org.xml.sax.ErrorHandler#warning
+ * @see org.xml.sax.SAXParseException
+ */
+ public void error (SAXParseException e)
+ throws SAXException
+ {
+ // no op
+ }
+
+
+ /**
+ * Report a fatal XML parsing error.
+ *
+ * <p>The default implementation throws a SAXParseException.
+ * Application writers may override this method in a subclass if
+ * they need to take specific actions for each fatal error (such as
+ * collecting all of the errors into a single report): in any case,
+ * the application must stop all regular processing when this
+ * method is invoked, since the document is no longer reliable, and
+ * the parser may no longer report parsing events.</p>
+ *
+ * @param e The error information encoded as an exception.
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @see org.xml.sax.ErrorHandler#fatalError
+ * @see org.xml.sax.SAXParseException
+ */
+ public void fatalError (SAXParseException e)
+ throws SAXException
+ {
+ throw e;
+ }
+
+}
+
+// end of DefaultHandler.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/jdk/internal/util/xml/PropertiesDefaultHandler.java Wed Dec 19 12:09:10 2012 +0000
@@ -0,0 +1,232 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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 General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.util.xml;
+
+import java.io.*;
+import java.util.InvalidPropertiesFormatException;
+import java.util.Properties;
+import jdk.internal.org.xml.sax.Attributes;
+import jdk.internal.org.xml.sax.InputSource;
+import jdk.internal.org.xml.sax.SAXException;
+import jdk.internal.org.xml.sax.SAXParseException;
+import jdk.internal.org.xml.sax.helpers.DefaultHandler;
+import jdk.internal.util.xml.impl.SAXParserImpl;
+import jdk.internal.util.xml.impl.XMLStreamWriterImpl;
+
+/**
+ * A class used to aid in Properties load and save in XML. This class is
+ * re-implemented using a subset of SAX
+ *
+ * @author Joe Wang
+ * @since 8
+ */
+public class PropertiesDefaultHandler extends DefaultHandler {
+
+ // Elements specified in the properties.dtd
+ private static final String ELEMENT_ROOT = "properties";
+ private static final String ELEMENT_COMMENT = "comment";
+ private static final String ELEMENT_ENTRY = "entry";
+ private static final String ATTR_KEY = "key";
+ // The required DTD URI for exported properties
+ private static final String PROPS_DTD_DECL =
+ "<!DOCTYPE properties SYSTEM \"http://java.sun.com/dtd/properties.dtd\">";
+ private static final String PROPS_DTD_URI =
+ "http://java.sun.com/dtd/properties.dtd";
+ private static final String PROPS_DTD =
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ + "<!-- DTD for properties -->"
+ + "<!ELEMENT properties ( comment?, entry* ) >"
+ + "<!ATTLIST properties"
+ + " version CDATA #FIXED \"1.0\">"
+ + "<!ELEMENT comment (#PCDATA) >"
+ + "<!ELEMENT entry (#PCDATA) >"
+ + "<!ATTLIST entry "
+ + " key CDATA #REQUIRED>";
+ /**
+ * Version number for the format of exported properties files.
+ */
+ private static final String EXTERNAL_XML_VERSION = "1.0";
+ private Properties properties;
+
+ public void load(Properties props, InputStream in)
+ throws IOException, InvalidPropertiesFormatException, UnsupportedEncodingException
+ {
+ this.properties = props;
+
+ try {
+ SAXParser parser = new SAXParserImpl();
+ parser.parse(in, this);
+ } catch (SAXException saxe) {
+ throw new InvalidPropertiesFormatException(saxe);
+ }
+
+ /**
+ * String xmlVersion = propertiesElement.getAttribute("version"); if
+ * (xmlVersion.compareTo(EXTERNAL_XML_VERSION) > 0) throw new
+ * InvalidPropertiesFormatException( "Exported Properties file format
+ * version " + xmlVersion + " is not supported. This java installation
+ * can read" + " versions " + EXTERNAL_XML_VERSION + " or older. You" +
+ * " may need to install a newer version of JDK.");
+ */
+ }
+
+ public void store(Properties props, OutputStream os, String comment, String encoding)
+ throws IOException
+ {
+ try {
+ XMLStreamWriter writer = new XMLStreamWriterImpl(os, encoding);
+ writer.writeStartDocument();
+ writer.writeDTD(PROPS_DTD_DECL);
+ writer.writeStartElement(ELEMENT_ROOT);
+ if (comment != null && comment.length() > 0) {
+ writer.writeStartElement(ELEMENT_COMMENT);
+ writer.writeCharacters(comment);
+ writer.writeEndElement();
+ }
+
+ for (String key : props.stringPropertyNames()) {
+ String val = props.getProperty(key);
+ writer.writeStartElement(ELEMENT_ENTRY);
+ writer.writeAttribute(ATTR_KEY, key);
+ writer.writeCharacters(val);
+ writer.writeEndElement();
+ }
+
+ writer.writeEndElement();
+ writer.writeEndDocument();
+ writer.close();
+ } catch (XMLStreamException e) {
+ if (e.getCause() instanceof UnsupportedEncodingException) {
+ throw (UnsupportedEncodingException) e.getCause();
+ }
+ throw new IOException(e);
+ }
+
+ }
+ ////////////////////////////////////////////////////////////////////
+ // Validate while parsing
+ ////////////////////////////////////////////////////////////////////
+ final static String ALLOWED_ELEMENTS = "properties, comment, entry";
+ final static String ALLOWED_COMMENT = "comment";
+ ////////////////////////////////////////////////////////////////////
+ // Handler methods
+ ////////////////////////////////////////////////////////////////////
+ StringBuffer buf = new StringBuffer();
+ boolean sawComment = false;
+ boolean validEntry = false;
+ int rootElem = 0;
+ String key;
+ String rootElm;
+
+ @Override
+ public void startElement(String uri, String localName, String qName, Attributes attributes)
+ throws SAXException
+ {
+ if (rootElem < 2) {
+ rootElem++;
+ }
+
+ if (rootElm == null) {
+ fatalError(new SAXParseException("An XML properties document must contain"
+ + " the DOCTYPE declaration as defined by java.util.Properties.", null));
+ }
+
+ if (rootElem == 1 && !rootElm.equals(qName)) {
+ fatalError(new SAXParseException("Document root element \"" + qName
+ + "\", must match DOCTYPE root \"" + rootElm + "\"", null));
+ }
+ if (!ALLOWED_ELEMENTS.contains(qName)) {
+ fatalError(new SAXParseException("Element type \"" + qName + "\" must be declared.", null));
+ }
+ if (qName.equals(ELEMENT_ENTRY)) {
+ validEntry = true;
+ key = attributes.getValue(ATTR_KEY);
+ if (key == null) {
+ fatalError(new SAXParseException("Attribute \"key\" is required and must be specified for element type \"entry\"", null));
+ }
+ } else if (qName.equals(ALLOWED_COMMENT)) {
+ if (sawComment) {
+ fatalError(new SAXParseException("Only one comment element may be allowed. "
+ + "The content of element type \"properties\" must match \"(comment?,entry*)\"", null));
+ }
+ sawComment = true;
+ }
+ }
+
+ @Override
+ public void characters(char[] ch, int start, int length) throws SAXException {
+ if (validEntry) {
+ buf.append(ch, start, length);
+ }
+ }
+
+ @Override
+ public void endElement(String uri, String localName, String qName) throws SAXException {
+ if (!ALLOWED_ELEMENTS.contains(qName)) {
+ fatalError(new SAXParseException("Element: " + qName + " is invalid, must match \"(comment?,entry*)\".", null));
+ }
+
+ if (validEntry) {
+ properties.setProperty(key, buf.toString());
+ buf.delete(0, buf.length());
+ validEntry = false;
+ }
+ }
+
+ @Override
+ public void notationDecl(String name, String publicId, String systemId) throws SAXException {
+ rootElm = name;
+ }
+
+ @Override
+ public InputSource resolveEntity(String pubid, String sysid)
+ throws SAXException, IOException {
+ {
+ if (sysid.equals(PROPS_DTD_URI)) {
+ InputSource is;
+ is = new InputSource(new StringReader(PROPS_DTD));
+ is.setSystemId(PROPS_DTD_URI);
+ return is;
+ }
+ throw new SAXException("Invalid system identifier: " + sysid);
+ }
+ }
+
+ @Override
+ public void error(SAXParseException x) throws SAXException {
+ throw x;
+ }
+
+ @Override
+ public void fatalError(SAXParseException x) throws SAXException {
+ throw x;
+ }
+
+ @Override
+ public void warning(SAXParseException x) throws SAXException {
+ throw x;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/jdk/internal/util/xml/SAXParser.java Wed Dec 19 12:09:10 2012 +0000
@@ -0,0 +1,246 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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 General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.util.xml;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import jdk.internal.org.xml.sax.InputSource;
+import jdk.internal.org.xml.sax.SAXException;
+import jdk.internal.org.xml.sax.XMLReader;
+import jdk.internal.org.xml.sax.helpers.DefaultHandler;
+
+
+/**
+ * Defines the API that wraps an {@link org.xml.sax.XMLReader}
+ * implementation class. In JAXP 1.0, this class wrapped the
+ * {@link org.xml.sax.Parser} interface, however this interface was
+ * replaced by the {@link org.xml.sax.XMLReader}. For ease
+ * of transition, this class continues to support the same name
+ * and interface as well as supporting new methods.
+ *
+ * An instance of this class can be obtained from the
+ * {@link javax.xml.parsers.SAXParserFactory#newSAXParser()} method.
+ * Once an instance of this class is obtained, XML can be parsed from
+ * a variety of input sources. These input sources are InputStreams,
+ * Files, URLs, and SAX InputSources.<p>
+ *
+ * This static method creates a new factory instance based
+ * on a system property setting or uses the platform default
+ * if no property has been defined.<p>
+ *
+ * The system property that controls which Factory implementation
+ * to create is named <code>"javax.xml.parsers.SAXParserFactory"</code>.
+ * This property names a class that is a concrete subclass of this
+ * abstract class. If no property is defined, a platform default
+ * will be used.</p>
+ *
+ * As the content is parsed by the underlying parser, methods of the
+ * given
+ * {@link org.xml.sax.helpers.DefaultHandler} are called.<p>
+ *
+ * Implementors of this class which wrap an underlaying implementation
+ * can consider using the {@link org.xml.sax.helpers.ParserAdapter}
+ * class to initially adapt their SAX1 implementation to work under
+ * this revised class.
+ *
+ * @author <a href="mailto:Jeff.Suttor@Sun.com">Jeff Suttor</a>
+ * @version $Revision: 1.8 $, $Date: 2010-11-01 04:36:09 $
+ *
+ * @author Joe Wang
+ * This is a subset of that in JAXP, javax.xml.parsers.SAXParser
+ *
+ */
+public abstract class SAXParser {
+
+ /**
+ * <p>Protected constructor to prevent instantiation.</p>
+ */
+ protected SAXParser() {
+ }
+
+ /**
+ * Parse the content of the given {@link java.io.InputStream}
+ * instance as XML using the specified
+ * {@link org.xml.sax.helpers.DefaultHandler}.
+ *
+ * @param is InputStream containing the content to be parsed.
+ * @param dh The SAX DefaultHandler to use.
+ *
+ * @throws IllegalArgumentException If the given InputStream is null.
+ * @throws IOException If any IO errors occur.
+ * @throws SAXException If any SAX errors occur during processing.
+ *
+ * @see org.xml.sax.DocumentHandler
+ */
+ public void parse(InputStream is, DefaultHandler dh)
+ throws SAXException, IOException
+ {
+ if (is == null) {
+ throw new IllegalArgumentException("InputStream cannot be null");
+ }
+
+ InputSource input = new InputSource(is);
+ this.parse(input, dh);
+ }
+
+ /**
+ * Parse the content described by the giving Uniform Resource
+ * Identifier (URI) as XML using the specified
+ * {@link org.xml.sax.helpers.DefaultHandler}.
+ *
+ * @param uri The location of the content to be parsed.
+ * @param dh The SAX DefaultHandler to use.
+ *
+ * @throws IllegalArgumentException If the uri is null.
+ * @throws IOException If any IO errors occur.
+ * @throws SAXException If any SAX errors occur during processing.
+ *
+ * @see org.xml.sax.DocumentHandler
+ */
+ public void parse(String uri, DefaultHandler dh)
+ throws SAXException, IOException
+ {
+ if (uri == null) {
+ throw new IllegalArgumentException("uri cannot be null");
+ }
+
+ InputSource input = new InputSource(uri);
+ this.parse(input, dh);
+ }
+
+ /**
+ * Parse the content of the file specified as XML using the
+ * specified {@link org.xml.sax.helpers.DefaultHandler}.
+ *
+ * @param f The file containing the XML to parse
+ * @param dh The SAX DefaultHandler to use.
+ *
+ * @throws IllegalArgumentException If the File object is null.
+ * @throws IOException If any IO errors occur.
+ * @throws SAXException If any SAX errors occur during processing.
+ *
+ * @see org.xml.sax.DocumentHandler
+ */
+ public void parse(File f, DefaultHandler dh)
+ throws SAXException, IOException
+ {
+ if (f == null) {
+ throw new IllegalArgumentException("File cannot be null");
+ }
+
+ //convert file to appropriate URI, f.toURI().toASCIIString()
+ //converts the URI to string as per rule specified in
+ //RFC 2396,
+ InputSource input = new InputSource(f.toURI().toASCIIString());
+ this.parse(input, dh);
+ }
+
+ /**
+ * Parse the content given {@link org.xml.sax.InputSource}
+ * as XML using the specified
+ * {@link org.xml.sax.helpers.DefaultHandler}.
+ *
+ * @param is The InputSource containing the content to be parsed.
+ * @param dh The SAX DefaultHandler to use.
+ *
+ * @throws IllegalArgumentException If the <code>InputSource</code> object
+ * is <code>null</code>.
+ * @throws IOException If any IO errors occur.
+ * @throws SAXException If any SAX errors occur during processing.
+ *
+ * @see org.xml.sax.DocumentHandler
+ */
+ public void parse(InputSource is, DefaultHandler dh)
+ throws SAXException, IOException
+ {
+ if (is == null) {
+ throw new IllegalArgumentException("InputSource cannot be null");
+ }
+
+ XMLReader reader = this.getXMLReader();
+ if (dh != null) {
+ reader.setContentHandler(dh);
+ reader.setEntityResolver(dh);
+ reader.setErrorHandler(dh);
+ reader.setDTDHandler(dh);
+ }
+ reader.parse(is);
+ }
+
+ /**
+ * Returns the {@link org.xml.sax.XMLReader} that is encapsulated by the
+ * implementation of this class.
+ *
+ * @return The XMLReader that is encapsulated by the
+ * implementation of this class.
+ *
+ * @throws SAXException If any SAX errors occur during processing.
+ */
+ public abstract XMLReader getXMLReader() throws SAXException;
+
+ /**
+ * Indicates whether or not this parser is configured to
+ * understand namespaces.
+ *
+ * @return true if this parser is configured to
+ * understand namespaces; false otherwise.
+ */
+ public abstract boolean isNamespaceAware();
+
+ /**
+ * Indicates whether or not this parser is configured to
+ * validate XML documents.
+ *
+ * @return true if this parser is configured to
+ * validate XML documents; false otherwise.
+ */
+ public abstract boolean isValidating();
+
+ /**
+ * <p>Get the XInclude processing mode for this parser.</p>
+ *
+ * @return
+ * the return value of
+ * the {@link SAXParserFactory#isXIncludeAware()}
+ * when this parser was created from factory.
+ *
+ * @throws UnsupportedOperationException When implementation does not
+ * override this method
+ *
+ * @since 1.5
+ *
+ * @see SAXParserFactory#setXIncludeAware(boolean)
+ */
+ public boolean isXIncludeAware() {
+ throw new UnsupportedOperationException(
+ "This parser does not support specification \""
+ + this.getClass().getPackage().getSpecificationTitle()
+ + "\" version \""
+ + this.getClass().getPackage().getSpecificationVersion()
+ + "\"");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/jdk/internal/util/xml/XMLStreamException.java Wed Dec 19 12:09:10 2012 +0000
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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 General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.util.xml;
+
+/**
+ * A copy of the StAX XMLStreamException without Location support
+ *
+ * The base exception for unexpected processing errors. This Exception
+ * class is used to report well-formedness errors as well as unexpected
+ * processing conditions.
+ * @version 1.0
+ * @author Copyright (c) 2009 by Oracle Corporation. All Rights Reserved.
+ * @since 1.6
+ */
+
+public class XMLStreamException extends Exception {
+ private static final long serialVersionUID = 1L;
+
+
+ protected Throwable nested;
+
+ /**
+ * Default constructor
+ */
+ public XMLStreamException() {
+ super();
+ }
+
+ /**
+ * Construct an exception with the assocated message.
+ *
+ * @param msg the message to report
+ */
+ public XMLStreamException(String msg) {
+ super(msg);
+ }
+
+ /**
+ * Construct an exception with the assocated exception
+ *
+ * @param th a nested exception
+ */
+ public XMLStreamException(Throwable th) {
+ super(th);
+ nested = th;
+ }
+
+ /**
+ * Construct an exception with the assocated message and exception
+ *
+ * @param th a nested exception
+ * @param msg the message to report
+ */
+ public XMLStreamException(String msg, Throwable th) {
+ super(msg, th);
+ nested = th;
+ }
+
+ /**
+ * Gets the nested exception.
+ *
+ * @return Nested exception
+ */
+ public Throwable getNestedException() {
+ return nested;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/jdk/internal/util/xml/XMLStreamWriter.java Wed Dec 19 12:09:10 2012 +0000
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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 General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.util.xml;
+
+/**
+ * Basic XMLStreamWriter for writing simple XML files such as those
+ * defined in java.util.Properties
+ *
+ * This is a subset of javax.xml.stream.XMLStreamWriter
+ *
+ * @author Joe Wang
+ */
+public interface XMLStreamWriter {
+
+ //Defaults the XML version to 1.0, and the encoding to utf-8
+ public final static String DEFAULT_XML_VERSION = "1.0";
+ public final static String DEFAULT_ENCODING = "UTF-8";
+
+ /**
+ * Writes a start tag to the output. All writeStartElement methods
+ * open a new scope in the internal namespace context. Writing the
+ * corresponding EndElement causes the scope to be closed.
+ * @param localName local name of the tag, may not be null
+ * @throws XMLStreamException
+ */
+ public void writeStartElement(String localName) throws XMLStreamException;
+
+ /**
+ * Writes an empty element tag to the output
+ * @param localName local name of the tag, may not be null
+ * @throws XMLStreamException
+ */
+ public void writeEmptyElement(String localName) throws XMLStreamException;
+
+ /**
+ * Writes an end tag to the output relying on the internal
+ * state of the writer to determine the prefix and local name
+ * of the event.
+ * @throws XMLStreamException
+ */
+ public void writeEndElement() throws XMLStreamException;
+
+ /**
+ * Closes any start tags and writes corresponding end tags.
+ * @throws XMLStreamException
+ */
+ public void writeEndDocument() throws XMLStreamException;
+
+ /**
+ * Close this writer and free any resources associated with the
+ * writer. This must not close the underlying output stream.
+ * @throws XMLStreamException
+ */
+ public void close() throws XMLStreamException;
+
+ /**
+ * Write any cached data to the underlying output mechanism.
+ * @throws XMLStreamException
+ */
+ public void flush() throws XMLStreamException;
+
+ /**
+ * Writes an attribute to the output stream without
+ * a prefix.
+ * @param localName the local name of the attribute
+ * @param value the value of the attribute
+ * @throws IllegalStateException if the current state does not allow Attribute writing
+ * @throws XMLStreamException
+ */
+ public void writeAttribute(String localName, String value)
+ throws XMLStreamException;
+
+ /**
+ * Writes a CData section
+ * @param data the data contained in the CData Section, may not be null
+ * @throws XMLStreamException
+ */
+ public void writeCData(String data) throws XMLStreamException;
+
+ /**
+ * Write a DTD section. This string represents the entire doctypedecl production
+ * from the XML 1.0 specification.
+ *
+ * @param dtd the DTD to be written
+ * @throws XMLStreamException
+ */
+ public void writeDTD(String dtd) throws XMLStreamException;
+
+ /**
+ * Write the XML Declaration. Defaults the XML version to 1.0, and the encoding to utf-8
+ * @throws XMLStreamException
+ */
+ public void writeStartDocument() throws XMLStreamException;
+
+ /**
+ * Write the XML Declaration. Defaults the the encoding to utf-8
+ * @param version version of the xml document
+ * @throws XMLStreamException
+ */
+ public void writeStartDocument(String version) throws XMLStreamException;
+
+ /**
+ * Write the XML Declaration. Note that the encoding parameter does
+ * not set the actual encoding of the underlying output. That must
+ * be set when the instance of the XMLStreamWriter is created using the
+ * XMLOutputFactory
+ * @param encoding encoding of the xml declaration
+ * @param version version of the xml document
+ * @throws XMLStreamException If given encoding does not match encoding
+ * of the underlying stream
+ */
+ public void writeStartDocument(String encoding, String version)
+ throws XMLStreamException;
+
+ /**
+ * Write text to the output
+ * @param text the value to write
+ * @throws XMLStreamException
+ */
+ public void writeCharacters(String text) throws XMLStreamException;
+
+ /**
+ * Write text to the output
+ * @param text the value to write
+ * @param start the starting position in the array
+ * @param len the number of characters to write
+ * @throws XMLStreamException
+ */
+ public void writeCharacters(char[] text, int start, int len)
+ throws XMLStreamException;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/jdk/internal/util/xml/impl/Attrs.java Wed Dec 19 12:09:10 2012 +0000
@@ -0,0 +1,430 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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 General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.util.xml.impl;
+
+import jdk.internal.org.xml.sax.Attributes;
+
+public class Attrs implements Attributes {
+
+ /**
+ * Attributes string array. Each individual attribute is represented by four
+ * strings: namespace URL(+0), qname(+1), local name(+2), value(+3),
+ * type(+4), declared["d"] and default["D"](+5). In order to find attribute
+ * by the attrubute index, the attribute index MUST be multiplied by 8. The
+ * result will point to the attribute namespace URL.
+ */
+ /* pkg */ String[] mItems;
+ /**
+ * Number of attributes in the attributes string array.
+ */
+ private char mLength;
+ /**
+ * current index
+ */
+ private char mAttrIdx = 0;
+
+ /**
+ * Constructor.
+ */
+ public Attrs() {
+ // The default number of attributies capacity is 8.
+ mItems = new String[(8 << 3)];
+ }
+
+ /**
+ * Sets up the number of attributes and ensure the capacity of the attribute
+ * string array.
+ *
+ * @param length The number of attributes in the object.
+ */
+ public void setLength(char length) {
+ if (length > ((char) (mItems.length >> 3))) {
+ mItems = new String[length << 3];
+ }
+ mLength = length;
+ }
+
+ /**
+ * Return the number of attributes in the list.
+ *
+ * <p>Once you know the number of attributes, you can iterate through the
+ * list.</p>
+ *
+ * @return The number of attributes in the list.
+ * @see #getURI(int)
+ * @see #getLocalName(int)
+ * @see #getQName(int)
+ * @see #getType(int)
+ * @see #getValue(int)
+ */
+ public int getLength() {
+ return mLength;
+ }
+
+ /**
+ * Look up an attribute's Namespace URI by index.
+ *
+ * @param index The attribute index (zero-based).
+ * @return The Namespace URI, or the empty string if none is available, or
+ * null if the index is out of range.
+ * @see #getLength
+ */
+ public String getURI(int index) {
+ return ((index >= 0) && (index < mLength))
+ ? (mItems[index << 3])
+ : null;
+ }
+
+ /**
+ * Look up an attribute's local name by index.
+ *
+ * @param index The attribute index (zero-based).
+ * @return The local name, or the empty string if Namespace processing is
+ * not being performed, or null if the index is out of range.
+ * @see #getLength
+ */
+ public String getLocalName(int index) {
+ return ((index >= 0) && (index < mLength))
+ ? (mItems[(index << 3) + 2])
+ : null;
+ }
+
+ /**
+ * Look up an attribute's XML 1.0 qualified name by index.
+ *
+ * @param index The attribute index (zero-based).
+ * @return The XML 1.0 qualified name, or the empty string if none is
+ * available, or null if the index is out of range.
+ * @see #getLength
+ */
+ public String getQName(int index) {
+ if ((index < 0) || (index >= mLength)) {
+ return null;
+ }
+ return mItems[(index << 3) + 1];
+ }
+
+ /**
+ * Look up an attribute's type by index.
+ *
+ * <p>The attribute type is one of the strings "CDATA", "ID", "IDREF",
+ * "IDREFS", "NMTOKEN", "NMTOKENS", "ENTITY", "ENTITIES", or "NOTATION"
+ * (always in upper case).</p>
+ *
+ * <p>If the parser has not read a declaration for the attribute, or if the
+ * parser does not report attribute types, then it must return the value
+ * "CDATA" as stated in the XML 1.0 Recommentation (clause 3.3.3,
+ * "Attribute-Value Normalization").</p>
+ *
+ * <p>For an enumerated attribute that is not a notation, the parser will
+ * report the type as "NMTOKEN".</p>
+ *
+ * @param index The attribute index (zero-based).
+ * @return The attribute's type as a string, or null if the index is out of
+ * range.
+ * @see #getLength
+ */
+ public String getType(int index) {
+ return ((index >= 0) && (index < (mItems.length >> 3)))
+ ? (mItems[(index << 3) + 4])
+ : null;
+ }
+
+ /**
+ * Look up an attribute's value by index.
+ *
+ * <p>If the attribute value is a list of tokens (IDREFS, ENTITIES, or
+ * NMTOKENS), the tokens will be concatenated into a single string with each
+ * token separated by a single space.</p>
+ *
+ * @param index The attribute index (zero-based).
+ * @return The attribute's value as a string, or null if the index is out of
+ * range.
+ * @see #getLength
+ */
+ public String getValue(int index) {
+ return ((index >= 0) && (index < mLength))
+ ? (mItems[(index << 3) + 3])
+ : null;
+ }
+
+ /**
+ * Look up the index of an attribute by Namespace name.
+ *
+ * @param uri The Namespace URI, or the empty string if the name has no
+ * Namespace URI.
+ * @param localName The attribute's local name.
+ * @return The index of the attribute, or -1 if it does not appear in the
+ * list.
+ */
+ public int getIndex(String uri, String localName) {
+ char len = mLength;
+ for (char idx = 0; idx < len; idx++) {
+ if ((mItems[idx << 3]).equals(uri)
+ && mItems[(idx << 3) + 2].equals(localName)) {
+ return idx;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Look up the index of an attribute by Namespace name.
+ *
+ * @param uri The Namespace URI, or the empty string if the name has no
+ * Namespace URI. <code>null</code> value enforce the search by the local
+ * name only.
+ * @param localName The attribute's local name.
+ * @return The index of the attribute, or -1 if it does not appear in the
+ * list.
+ */
+ /* pkg */ int getIndexNullNS(String uri, String localName) {
+ char len = mLength;
+ if (uri != null) {
+ for (char idx = 0; idx < len; idx++) {
+ if ((mItems[idx << 3]).equals(uri)
+ && mItems[(idx << 3) + 2].equals(localName)) {
+ return idx;
+ }
+ }
+ } else {
+ for (char idx = 0; idx < len; idx++) {
+ if (mItems[(idx << 3) + 2].equals(localName)) {
+ return idx;
+ }
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Look up the index of an attribute by XML 1.0 qualified name.
+ *
+ * @param qName The qualified (prefixed) name.
+ * @return The index of the attribute, or -1 if it does not appear in the
+ * list.
+ */
+ public int getIndex(String qName) {
+ char len = mLength;
+ for (char idx = 0; idx < len; idx++) {
+ if (mItems[(idx << 3) + 1].equals(qName)) {
+ return idx;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Look up an attribute's type by Namespace name.
+ *
+ * <p>See {@link #getType(int) getType(int)} for a description of the
+ * possible types.</p>
+ *
+ * @param uri The Namespace URI, or the empty String if the name has no
+ * Namespace URI.
+ * @param localName The local name of the attribute.
+ * @return The attribute type as a string, or null if the attribute is not
+ * in the list or if Namespace processing is not being performed.
+ */
+ public String getType(String uri, String localName) {
+ int idx = getIndex(uri, localName);
+ return (idx >= 0) ? (mItems[(idx << 3) + 4]) : null;
+ }
+
+ /**
+ * Look up an attribute's type by XML 1.0 qualified name.
+ *
+ * <p>See {@link #getType(int) getType(int)} for a description of the
+ * possible types.</p>
+ *
+ * @param qName The XML 1.0 qualified name.
+ * @return The attribute type as a string, or null if the attribute is not
+ * in the list or if qualified names are not available.
+ */
+ public String getType(String qName) {
+ int idx = getIndex(qName);
+ return (idx >= 0) ? (mItems[(idx << 3) + 4]) : null;
+ }
+
+ /**
+ * Look up an attribute's value by Namespace name.
+ *
+ * <p>See {@link #getValue(int) getValue(int)} for a description of the
+ * possible values.</p>
+ *
+ * @param uri The Namespace URI, or the empty String if the name has no
+ * Namespace URI.
+ * @param localName The local name of the attribute.
+ * @return The attribute value as a string, or null if the attribute is not
+ * in the list.
+ */
+ public String getValue(String uri, String localName) {
+ int idx = getIndex(uri, localName);
+ return (idx >= 0) ? (mItems[(idx << 3) + 3]) : null;
+ }
+
+ /**
+ * Look up an attribute's value by XML 1.0 qualified name.
+ *
+ * <p>See {@link #getValue(int) getValue(int)} for a description of the
+ * possible values.</p>
+ *
+ * @param qName The XML 1.0 qualified name.
+ * @return The attribute value as a string, or null if the attribute is not
+ * in the list or if qualified names are not available.
+ */
+ public String getValue(String qName) {
+ int idx = getIndex(qName);
+ return (idx >= 0) ? (mItems[(idx << 3) + 3]) : null;
+ }
+
+ /**
+ * Returns false unless the attribute was declared in the DTD. This helps
+ * distinguish two kinds of attributes that SAX reports as CDATA: ones that
+ * were declared (and hence are usually valid), and those that were not (and
+ * which are never valid).
+ *
+ * @param index The attribute index (zero-based).
+ * @return true if the attribute was declared in the DTD, false otherwise.
+ * @exception java.lang.ArrayIndexOutOfBoundsException When the supplied
+ * index does not identify an attribute.
+ */
+ public boolean isDeclared(int index) {
+ if ((index < 0) || (index >= mLength)) {
+ throw new ArrayIndexOutOfBoundsException("");
+ }
+
+ return ((mItems[(index << 3) + 5]) != null);
+ }
+
+ /**
+ * Returns false unless the attribute was declared in the DTD. This helps
+ * distinguish two kinds of attributes that SAX reports as CDATA: ones that
+ * were declared (and hence are usually valid), and those that were not (and
+ * which are never valid).
+ *
+ * @param qName The XML qualified (prefixed) name.
+ * @return true if the attribute was declared in the DTD, false otherwise.
+ * @exception java.lang.IllegalArgumentException When the supplied name does
+ * not identify an attribute.
+ */
+ public boolean isDeclared(String qName) {
+ int idx = getIndex(qName);
+ if (idx < 0) {
+ throw new IllegalArgumentException("");
+ }
+
+ return ((mItems[(idx << 3) + 5]) != null);
+ }
+
+ /**
+ * Returns false unless the attribute was declared in the DTD. This helps
+ * distinguish two kinds of attributes that SAX reports as CDATA: ones that
+ * were declared (and hence are usually valid), and those that were not (and
+ * which are never valid).
+ *
+ * <p>Remember that since DTDs do not "understand" namespaces, the namespace
+ * URI associated with an attribute may not have come from the DTD. The
+ * declaration will have applied to the attribute's <em>qName</em>.
+ *
+ * @param uri The Namespace URI, or the empty string if the name has no
+ * Namespace URI.
+ * @param localName The attribute's local name.
+ * @return true if the attribute was declared in the DTD, false otherwise.
+ * @exception java.lang.IllegalArgumentException When the supplied names do
+ * not identify an attribute.
+ */
+ public boolean isDeclared(String uri, String localName) {
+ int idx = getIndex(uri, localName);
+ if (idx < 0) {
+ throw new IllegalArgumentException("");
+ }
+
+ return ((mItems[(idx << 3) + 5]) != null);
+ }
+
+ /**
+ * Returns true unless the attribute value was provided by DTD defaulting.
+ *
+ * @param index The attribute index (zero-based).
+ * @return true if the value was found in the XML text, false if the value
+ * was provided by DTD defaulting.
+ * @exception java.lang.ArrayIndexOutOfBoundsException When the supplied
+ * index does not identify an attribute.
+ */
+ public boolean isSpecified(int index) {
+ if ((index < 0) || (index >= mLength)) {
+ throw new ArrayIndexOutOfBoundsException("");
+ }
+
+ String str = mItems[(index << 3) + 5];
+ return ((str != null) ? (str.charAt(0) == 'd') : true);
+ }
+
+ /**
+ * Returns true unless the attribute value was provided by DTD defaulting.
+ *
+ * <p>Remember that since DTDs do not "understand" namespaces, the namespace
+ * URI associated with an attribute may not have come from the DTD. The
+ * declaration will have applied to the attribute's <em>qName</em>.
+ *
+ * @param uri The Namespace URI, or the empty string if the name has no
+ * Namespace URI.
+ * @param localName The attribute's local name.
+ * @return true if the value was found in the XML text, false if the value
+ * was provided by DTD defaulting.
+ * @exception java.lang.IllegalArgumentException When the supplied names do
+ * not identify an attribute.
+ */
+ public boolean isSpecified(String uri, String localName) {
+ int idx = getIndex(uri, localName);
+ if (idx < 0) {
+ throw new IllegalArgumentException("");
+ }
+
+ String str = mItems[(idx << 3) + 5];
+ return ((str != null) ? (str.charAt(0) == 'd') : true);
+ }
+
+ /**
+ * Returns true unless the attribute value was provided by DTD defaulting.
+ *
+ * @param qName The XML qualified (prefixed) name.
+ * @return true if the value was found in the XML text, false if the value
+ * was provided by DTD defaulting.
+ * @exception java.lang.IllegalArgumentException When the supplied name does
+ * not identify an attribute.
+ */
+ public boolean isSpecified(String qName) {
+ int idx = getIndex(qName);
+ if (idx < 0) {
+ throw new IllegalArgumentException("");
+ }
+
+ String str = mItems[(idx << 3) + 5];
+ return ((str != null) ? (str.charAt(0) == 'd') : true);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/jdk/internal/util/xml/impl/Input.java Wed Dec 19 12:09:10 2012 +0000
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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 General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.util.xml.impl;
+
+import java.io.Reader;
+
+/**
+ * A parsed entity input state.
+ *
+ * This class represents a parsed entity input state. The parser uses
+ * an instance of this class to manage input.
+ */
+
+public class Input {
+
+ /** The entity public identifier or null. */
+ public String pubid;
+ /** The entity systen identifier or null. */
+ public String sysid;
+ /** The encoding from XML declaration or null */
+ public String xmlenc;
+ /** The XML version from XML declaration or 0x0000 */
+ public char xmlver;
+ /** The entity reader. */
+ public Reader src;
+ /** The character buffer. */
+ public char[] chars;
+ /** The length of the character buffer. */
+ public int chLen;
+ /** The index of the next character to read. */
+ public int chIdx;
+ /** The next input in a chain. */
+ public Input next;
+
+ /**
+ * Constructor.
+ *
+ * @param buffsize The input buffer size.
+ */
+ public Input(int buffsize) {
+ chars = new char[buffsize];
+ chLen = chars.length;
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param buff The input buffer.
+ */
+ public Input(char[] buff) {
+ chars = buff;
+ chLen = chars.length;
+ }
+
+ /**
+ * Constructor.
+ */
+ public Input() {
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/jdk/internal/util/xml/impl/Pair.java Wed Dec 19 12:09:10 2012 +0000
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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 General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.util.xml.impl;
+
+
+/**
+ * A name with value pair.
+ *
+ * This class keeps name with value pair with additional information and
+ * supports pair chaining.
+ */
+public class Pair {
+
+ /** The pair name. */
+ public String name;
+ /** The pair value. */
+ public String value;
+ /** The pair numeric value. */
+ public int num;
+ /** The characters of name. */
+ public char[] chars;
+ /** The pair identifier. */
+ public int id;
+ /** The list of associated pairs. */
+ public Pair list;
+ /** The next pair in a chain. */
+ public Pair next;
+
+ /**
+ * Creates a qualified name string from qualified name.
+ *
+ * @return The qualified name string.
+ */
+ public String qname() {
+ return new String(chars, 1, chars.length - 1);
+ }
+
+ /**
+ * Creates a local name string from qualified name.
+ *
+ * @return The local name string.
+ */
+ public String local() {
+ if (chars[0] != 0) {
+ return new String(chars, chars[0] + 1, chars.length - chars[0] - 1);
+ }
+ return new String(chars, 1, chars.length - 1);
+ }
+
+ /**
+ * Creates a prefix string from qualified name.
+ *
+ * @return The prefix string.
+ */
+ public String pref() {
+ if (chars[0] != 0) {
+ return new String(chars, 1, chars[0] - 1);
+ }
+ return "";
+ }
+
+ /**
+ * Compares two qualified name prefixes.
+ *
+ * @param qname A qualified name.
+ * @return true if prefixes are equal.
+ */
+ public boolean eqpref(char[] qname) {
+ if (chars[0] == qname[0]) {
+ char len = chars[0];
+ for (char i = 1; i < len; i += 1) {
+ if (chars[i] != qname[i]) {
+ return false;
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Compares two qualified names.
+ *
+ * @param qname A qualified name.
+ * @return true if qualified names are equal.
+ */
+ public boolean eqname(char[] qname) {
+ char len = (char) chars.length;
+ if (len == qname.length) {
+ for (char i = 0; i < len; i += 1) {
+ if (chars[i] != qname[i]) {
+ return false;
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/jdk/internal/util/xml/impl/Parser.java Wed Dec 19 12:09:10 2012 +0000
@@ -0,0 +1,3367 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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 General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.util.xml.impl;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.UnsupportedEncodingException;
+import java.util.HashMap;
+import java.util.Map;
+import jdk.internal.org.xml.sax.InputSource;
+import jdk.internal.org.xml.sax.SAXException;
+
+/**
+ * XML non-validating parser engine.
+ */
+public abstract class Parser {
+
+ public final static String FAULT = "";
+ protected final static int BUFFSIZE_READER = 512;
+ protected final static int BUFFSIZE_PARSER = 128;
+ /**
+ * The end of stream character.
+ */
+ public final static char EOS = 0xffff;
+ private Pair mNoNS; // there is no namespace
+ private Pair mXml; // the xml namespace
+ private Map<String, Input> mEnt; // the entities look up table
+ private Map<String, Input> mPEnt; // the parmeter entities look up table
+ protected boolean mIsSAlone; // xml decl standalone flag
+ protected boolean mIsSAloneSet; // standalone is explicitely set
+ protected boolean mIsNSAware; // if true - namespace aware mode
+ protected int mPh; // current phase of document processing
+ protected final static int PH_BEFORE_DOC = -1; // before parsing
+ protected final static int PH_DOC_START = 0; // document start
+ protected final static int PH_MISC_DTD = 1; // misc before DTD
+ protected final static int PH_DTD = 2; // DTD
+ protected final static int PH_DTD_MISC = 3; // misc after DTD
+ protected final static int PH_DOCELM = 4; // document's element
+ protected final static int PH_DOCELM_MISC = 5; // misc after element
+ protected final static int PH_AFTER_DOC = 6; // after parsing
+ protected int mEvt; // current event type
+ protected final static int EV_NULL = 0; // unknown
+ protected final static int EV_ELM = 1; // empty element
+ protected final static int EV_ELMS = 2; // start element
+ protected final static int EV_ELME = 3; // end element
+ protected final static int EV_TEXT = 4; // textual content
+ protected final static int EV_WSPC = 5; // white space content
+ protected final static int EV_PI = 6; // processing instruction
+ protected final static int EV_CDAT = 7; // character data
+ protected final static int EV_COMM = 8; // comment
+ protected final static int EV_DTD = 9; // document type definition
+ protected final static int EV_ENT = 10; // skipped entity
+ private char mESt; // built-in entity recognizer state
+ // mESt values:
+ // 0x100 : the initial state
+ // > 0x100 : unrecognized name
+ // < 0x100 : replacement character
+ protected char[] mBuff; // parser buffer
+ protected int mBuffIdx; // index of the last char
+ protected Pair mPref; // stack of prefixes
+ protected Pair mElm; // stack of elements
+ // mAttL.chars - element qname
+ // mAttL.next - next element
+ // mAttL.list - list of attributes defined on this element
+ // mAttL.list.chars - attribute qname
+ // mAttL.list.id - a char representing attribute's type see below
+ // mAttL.list.next - next attribute defined on the element
+ // mAttL.list.list - devault value structure or null
+ // mAttL.list.list.chars - "name='value' " chars array for Input
+ //
+ // Attribute type character values:
+ // 'i' - "ID"
+ // 'r' - "IDREF"
+ // 'R' - "IDREFS"
+ // 'n' - "ENTITY"
+ // 'N' - "ENTITIES"
+ // 't' - "NMTOKEN"
+ // 'T' - "NMTOKENS"
+ // 'u' - enumeration type
+ // 'o' - "NOTATION"
+ // 'c' - "CDATA"
+ // see also: bkeyword() and atype()
+ //
+ protected Pair mAttL; // list of defined attrs by element name
+ protected Input mDoc; // document entity
+ protected Input mInp; // stack of entities
+ private char[] mChars; // reading buffer
+ private int mChLen; // current capacity
+ private int mChIdx; // index to the next char
+ protected Attrs mAttrs; // attributes of the curr. element
+ private String[] mItems; // attributes array of the curr. element
+ private char mAttrIdx; // attributes counter/index
+ private String mUnent; // unresolved entity name
+ private Pair mDltd; // deleted objects for reuse
+ /**
+ * Default prefixes
+ */
+ private final static char NONS[];
+ private final static char XML[];
+ private final static char XMLNS[];
+
+ static {
+ NONS = new char[1];
+ NONS[0] = (char) 0;
+
+ XML = new char[4];
+ XML[0] = (char) 4;
+ XML[1] = 'x';
+ XML[2] = 'm';
+ XML[3] = 'l';
+
+ XMLNS = new char[6];
+ XMLNS[0] = (char) 6;
+ XMLNS[1] = 'x';
+ XMLNS[2] = 'm';
+ XMLNS[3] = 'l';
+ XMLNS[4] = 'n';
+ XMLNS[5] = 's';
+ }
+ /**
+ * ASCII character type array.
+ *
+ * This array maps an ASCII (7 bit) character to the character type.<br />
+ * Possible character type values are:<br /> - ' ' for any kind of white
+ * space character;<br /> - 'a' for any lower case alphabetical character
+ * value;<br /> - 'A' for any upper case alphabetical character value;<br />
+ * - 'd' for any decimal digit character value;<br /> - 'z' for any
+ * character less then ' ' except '\t', '\n', '\r';<br /> An ASCII (7 bit)
+ * character which does not fall in any category listed above is mapped to
+ * it self.
+ */
+ private static final byte asctyp[];
+ /**
+ * NMTOKEN character type array.
+ *
+ * This array maps an ASCII (7 bit) character to the character type.<br />
+ * Possible character type values are:<br /> - 0 for underscore ('_') or any
+ * lower and upper case alphabetical character value;<br /> - 1 for colon
+ * (':') character;<br /> - 2 for dash ('-') and dot ('.') or any decimal
+ * digit character value;<br /> - 3 for any kind of white space character<br
+ * /> An ASCII (7 bit) character which does not fall in any category listed
+ * above is mapped to 0xff.
+ */
+ private static final byte nmttyp[];
+
+ /**
+ * Static constructor.
+ *
+ * Sets up the ASCII character type array which is used by
+ * {@link #asctyp asctyp} method and NMTOKEN character type array.
+ */
+ static {
+ short i = 0;
+
+ asctyp = new byte[0x80];
+ while (i < ' ') {
+ asctyp[i++] = (byte) 'z';
+ }
+ asctyp['\t'] = (byte) ' ';
+ asctyp['\r'] = (byte) ' ';
+ asctyp['\n'] = (byte) ' ';
+ while (i < '0') {
+ asctyp[i] = (byte) i++;
+ }
+ while (i <= '9') {
+ asctyp[i++] = (byte) 'd';
+ }
+ while (i < 'A') {
+ asctyp[i] = (byte) i++;
+ }
+ while (i <= 'Z') {
+ asctyp[i++] = (byte) 'A';
+ }
+ while (i < 'a') {
+ asctyp[i] = (byte) i++;
+ }
+ while (i <= 'z') {
+ asctyp[i++] = (byte) 'a';
+ }
+ while (i < 0x80) {
+ asctyp[i] = (byte) i++;
+ }
+
+ nmttyp = new byte[0x80];
+ for (i = 0; i < '0'; i++) {
+ nmttyp[i] = (byte) 0xff;
+ }
+ while (i <= '9') {
+ nmttyp[i++] = (byte) 2; // digits
+ }
+ while (i < 'A') {
+ nmttyp[i++] = (byte) 0xff;
+ }
+ // skiped upper case alphabetical character are already 0
+ for (i = '['; i < 'a'; i++) {
+ nmttyp[i] = (byte) 0xff;
+ }
+ // skiped lower case alphabetical character are already 0
+ for (i = '{'; i < 0x80; i++) {
+ nmttyp[i] = (byte) 0xff;
+ }
+ nmttyp['_'] = 0;
+ nmttyp[':'] = 1;
+ nmttyp['.'] = 2;
+ nmttyp['-'] = 2;
+ nmttyp[' '] = 3;
+ nmttyp['\t'] = 3;
+ nmttyp['\r'] = 3;
+ nmttyp['\n'] = 3;
+ }
+
+ /**
+ * Constructor.
+ */
+ protected Parser() {
+ mPh = PH_BEFORE_DOC; // before parsing
+
+ // Initialize the parser
+ mBuff = new char[BUFFSIZE_PARSER];
+ mAttrs = new Attrs();
+
+ // Default namespace
+ mPref = pair(mPref);
+ mPref.name = "";
+ mPref.value = "";
+ mPref.chars = NONS;
+ mNoNS = mPref; // no namespace
+ // XML namespace
+ mPref = pair(mPref);
+ mPref.name = "xml";
+ mPref.value = "http://www.w3.org/XML/1998/namespace";
+ mPref.chars = XML;
+ mXml = mPref; // XML namespace
+ }
+
+ /**
+ * Initializes parser's internals. Note, current input has to be set before
+ * this method is called.
+ */
+ protected void init() {
+ mUnent = null;
+ mElm = null;
+ mPref = mXml;
+ mAttL = null;
+ mPEnt = new HashMap<>();
+ mEnt = new HashMap<>();
+ mDoc = mInp; // current input is document entity
+ mChars = mInp.chars; // use document entity buffer
+ mPh = PH_DOC_START; // the begining of the document
+ }
+
+ /**
+ * Cleans up parser internal resources.
+ */
+ protected void cleanup() {
+ // Default attributes
+ while (mAttL != null) {
+ while (mAttL.list != null) {
+ if (mAttL.list.list != null) {
+ del(mAttL.list.list);
+ }
+ mAttL.list = del(mAttL.list);
+ }
+ mAttL = del(mAttL);
+ }
+ // Element stack
+ while (mElm != null) {
+ mElm = del(mElm);
+ }
+ // Namespace prefixes
+ while (mPref != mXml) {
+ mPref = del(mPref);
+ }
+ // Inputs
+ while (mInp != null) {
+ pop();
+ }
+ // Document reader
+ if ((mDoc != null) && (mDoc.src != null)) {
+ try {
+ mDoc.src.close();
+ } catch (IOException ioe) {
+ }
+ }
+ mPEnt = null;
+ mEnt = null;
+ mDoc = null;
+ mPh = PH_AFTER_DOC; // before documnet processing
+ }
+
+ /**
+ * Processes a portion of document. This method returns one of EV_*
+ * constants as an identifier of the portion of document have been read.
+ *
+ * @return Identifier of processed document portion.
+ * @exception Exception is parser specific exception form panic method.
+ * @exception IOException
+ */
+ @SuppressWarnings("fallthrough")
+ protected int step() throws Exception {
+ mEvt = EV_NULL;
+ int st = 0;
+ while (mEvt == EV_NULL) {
+ char ch = (mChIdx < mChLen) ? mChars[mChIdx++] : getch();
+ switch (st) {
+ case 0: // all sorts of markup (dispetcher)
+ if (ch != '<') {
+ bkch();
+ mBuffIdx = -1; // clean parser buffer
+ st = 1;
+ break;
+ }
+ switch (getch()) {
+ case '/': // the end of the element content
+ mEvt = EV_ELME;
+ if (mElm == null) {
+ panic(FAULT);
+ }
+ // Check element's open/close tags balance
+ mBuffIdx = -1; // clean parser buffer
+ bname(mIsNSAware);
+ char[] chars = mElm.chars;
+ if (chars.length == (mBuffIdx + 1)) {
+ for (char i = 1; i <= mBuffIdx; i += 1) {
+ if (chars[i] != mBuff[i]) {
+ panic(FAULT);
+ }
+ }
+ } else {
+ panic(FAULT);
+ }
+ // Skip white spaces before '>'
+ if (wsskip() != '>') {
+ panic(FAULT);
+ }
+ getch(); // read '>'
+ break;
+
+ case '!': // a comment or a CDATA
+ ch = getch();
+ bkch();
+ switch (ch) {
+ case '-': // must be a comment
+ mEvt = EV_COMM;
+ comm();
+ break;
+
+ case '[': // must be a CDATA section
+ mEvt = EV_CDAT;
+ cdat();
+ break;
+
+ default: // must be 'DOCTYPE'
+ mEvt = EV_DTD;
+ dtd();
+ break;
+ }
+ break;
+
+ case '?': // processing instruction
+ mEvt = EV_PI;
+ pi();
+ break;
+
+ default: // must be the first char of an xml name
+ bkch();
+ // Read an element name and put it on top of the
+ // element stack
+ mElm = pair(mElm); // add new element to the stack
+ mElm.chars = qname(mIsNSAware);
+ mElm.name = mElm.local();
+ mElm.id = (mElm.next != null) ? mElm.next.id : 0; // flags
+ mElm.num = 0; // namespace counter
+ // Find the list of defined attributs of the current
+ // element
+ Pair elm = find(mAttL, mElm.chars);
+ mElm.list = (elm != null) ? elm.list : null;
+ // Read attributes till the end of the element tag
+ mAttrIdx = 0;
+ Pair att = pair(null);
+ att.num = 0; // clear attribute's flags
+ attr(att); // get all attributes inc. defaults
+ del(att);
+ mElm.value = (mIsNSAware) ? rslv(mElm.chars) : null;
+ // Skip white spaces before '>'
+ switch (wsskip()) {
+ case '>':
+ getch(); // read '>'
+ mEvt = EV_ELMS;
+ break;
+
+ case '/':
+ getch(); // read '/'
+ if (getch() != '>') // read '>'
+ {
+ panic(FAULT);
+ }
+ mEvt = EV_ELM;
+ break;
+
+ default:
+ panic(FAULT);
+ }
+ break;
+ }
+ break;
+
+ case 1: // read white space
+ switch (ch) {
+ case ' ':
+ case '\t':
+ case '\n':
+ bappend(ch);
+ break;
+
+ case '\r': // EOL processing [#2.11]
+ if (getch() != '\n') {
+ bkch();
+ }
+ bappend('\n');
+ break;
+
+ case '<':
+ mEvt = EV_WSPC;
+ bkch();
+ bflash_ws();
+ break;
+
+ default:
+ bkch();
+ st = 2;
+ break;
+ }
+ break;
+
+ case 2: // read the text content of the element
+ switch (ch) {
+ case '&':
+ if (mUnent == null) {
+ // There was no unresolved entity on previous step.
+ if ((mUnent = ent('x')) != null) {
+ mEvt = EV_TEXT;
+ bkch(); // move back to ';' after entity name
+ setch('&'); // parser must be back on next step
+ bflash();
+ }
+ } else {
+ // There was unresolved entity on previous step.
+ mEvt = EV_ENT;
+ skippedEnt(mUnent);
+ mUnent = null;
+ }
+ break;
+
+ case '<':
+ mEvt = EV_TEXT;
+ bkch();
+ bflash();
+ break;
+
+ case '\r': // EOL processing [#2.11]
+ if (getch() != '\n') {
+ bkch();
+ }
+ bappend('\n');
+ break;
+
+ case EOS:
+ panic(FAULT);
+
+ default:
+ bappend(ch);
+ break;
+ }
+ break;
+
+ default:
+ panic(FAULT);
+ }
+ }
+
+ return mEvt;
+ }
+
+ /**
+ * Parses the document type declaration.
+ *
+ * @exception Exception is parser specific exception form panic method.
+ * @exception IOException
+ */
+ private void dtd() throws Exception {
+ char ch;
+ String str = null;
+ String name = null;
+ Pair psid = null;
+ // read 'DOCTYPE'
+ if ("DOCTYPE".equals(name(false)) != true) {
+ panic(FAULT);
+ }
+ mPh = PH_DTD; // DTD
+ for (short st = 0; st >= 0;) {
+ ch = getch();
+ switch (st) {
+ case 0: // read the document type name
+ if (chtyp(ch) != ' ') {
+ bkch();
+ name = name(mIsNSAware);
+ wsskip();
+ st = 1; // read 'PUPLIC' or 'SYSTEM'
+ }
+ break;
+
+ case 1: // read 'PUPLIC' or 'SYSTEM'
+ switch (chtyp(ch)) {
+ case 'A':
+ bkch();
+ psid = pubsys(' ');
+ st = 2; // skip spaces before internal subset
+ docType(name, psid.name, psid.value);
+ break;
+
+ case '[':
+ bkch();
+ st = 2; // skip spaces before internal subset
+ docType(name, null, null);
+ break;
+
+ case '>':
+ bkch();
+ st = 3; // skip spaces after internal subset
+ docType(name, null, null);
+ break;
+
+ default:
+ panic(FAULT);
+ }
+ break;
+
+ case 2: // skip spaces before internal subset
+ switch (chtyp(ch)) {
+ case '[':
+ // Process internal subset
+ dtdsub();
+ st = 3; // skip spaces after internal subset
+ break;
+
+ case '>':
+ // There is no internal subset
+ bkch();
+ st = 3; // skip spaces after internal subset
+ break;
+
+ case ' ':
+ // skip white spaces
+ break;
+
+ default:
+ panic(FAULT);
+ }
+ break;
+
+ case 3: // skip spaces after internal subset
+ switch (chtyp(ch)) {
+ case '>':
+ if (psid != null) {
+ // Report the DTD external subset
+ InputSource is = resolveEnt(name, psid.name, psid.value);
+ if (is != null) {
+ if (mIsSAlone == false) {
+ // Set the end of DTD external subset char
+ bkch();
+ setch(']');
+ // Set the DTD external subset InputSource
+ push(new Input(BUFFSIZE_READER));
+ setinp(is);
+ mInp.pubid = psid.name;
+ mInp.sysid = psid.value;
+ // Parse the DTD external subset
+ dtdsub();
+ } else {
+ // Unresolved DTD external subset
+ skippedEnt("[dtd]");
+ // Release reader and stream
+ if (is.getCharacterStream() != null) {
+ try {
+ is.getCharacterStream().close();
+ } catch (IOException ioe) {
+ }
+ }
+ if (is.getByteStream() != null) {
+ try {
+ is.getByteStream().close();
+ } catch (IOException ioe) {
+ }
+ }
+ }
+ } else {
+ // Unresolved DTD external subset
+ skippedEnt("[dtd]");
+ }
+ del(psid);
+ }
+ st = -1; // end of DTD
+ break;
+
+ case ' ':
+ // skip white spaces
+ break;
+
+ default:
+ panic(FAULT);
+ }
+ break;
+
+ default:
+ panic(FAULT);
+ }
+ }
+ }
+
+ /**
+ * Parses the document type declaration subset.
+ *
+ * @exception Exception is parser specific exception form panic method.
+ * @exception IOException
+ */
+ private void dtdsub() throws Exception {
+ char ch;
+ for (short st = 0; st >= 0;) {
+ ch = getch();
+ switch (st) {
+ case 0: // skip white spaces before a declaration
+ switch (chtyp(ch)) {
+ case '<':
+ ch = getch();
+ switch (ch) {
+ case '?':
+ pi();
+ break;
+
+ case '!':
+ ch = getch();
+ bkch();
+ if (ch == '-') {
+ comm();
+ break;
+ }
+ // A markup or an entity declaration
+ bntok();
+ switch (bkeyword()) {
+ case 'n':
+ dtdent();
+ break;
+
+ case 'a':
+ dtdattl(); // parse attributes declaration
+ break;
+
+ case 'e':
+ dtdelm(); // parse element declaration
+ break;
+
+ case 'o':
+ dtdnot(); // parse notation declaration
+ break;
+
+ default:
+ panic(FAULT); // unsupported markup declaration
+ break;
+ }
+ st = 1; // read the end of declaration
+ break;
+
+ default:
+ panic(FAULT);
+ break;
+ }
+ break;
+
+ case '%':
+ // A parameter entity reference
+ pent(' ');
+ break;
+
+ case ']':
+ // End of DTD subset
+ st = -1;
+ break;
+
+ case ' ':
+ // Skip white spaces
+ break;
+
+ case 'Z':
+ // End of stream
+ if (getch() != ']') {
+ panic(FAULT);
+ }
+ st = -1;
+ break;
+
+ default:
+ panic(FAULT);
+ }
+ break;
+
+ case 1: // read the end of declaration
+ switch (ch) {
+ case '>': // there is no notation
+ st = 0; // skip white spaces before a declaration
+ break;
+
+ case ' ':
+ case '\n':
+ case '\r':
+ case '\t':
+ // Skip white spaces
+ break;
+
+ default:
+ panic(FAULT);
+ break;
+ }
+ break;
+
+ default:
+ panic(FAULT);
+ }
+ }
+ }
+
+ /**
+ * Parses an entity declaration. This method fills the general (
+ * <code>mEnt</code>) and parameter
+ * (
+ * <code>mPEnt</code>) entity look up table.
+ *
+ * @exception Exception is parser specific exception form panic method.
+ * @exception IOException
+ */
+ @SuppressWarnings("fallthrough")
+ private void dtdent() throws Exception {
+ String str = null;
+ char[] val = null;
+ Input inp = null;
+ Pair ids = null;
+ char ch;
+ for (short st = 0; st >= 0;) {
+ ch = getch();
+ switch (st) {
+ case 0: // skip white spaces before entity name
+ switch (chtyp(ch)) {
+ case ' ':
+ // Skip white spaces
+ break;
+
+ case '%':
+ // Parameter entity or parameter entity declaration.
+ ch = getch();
+ bkch();
+ if (chtyp(ch) == ' ') {
+ // Parameter entity declaration.
+ wsskip();
+ str = name(false);
+ switch (chtyp(wsskip())) {
+ case 'A':
+ // Read the external identifier
+ ids = pubsys(' ');
+ if (wsskip() == '>') {
+ // External parsed entity
+ if (mPEnt.containsKey(str) == false) { // [#4.2]
+ inp = new Input();
+ inp.pubid = ids.name;
+ inp.sysid = ids.value;
+ mPEnt.put(str, inp);
+ }
+ } else {
+ panic(FAULT);
+ }
+ del(ids);
+ st = -1; // the end of declaration
+ break;
+
+ case '\"':
+ case '\'':
+ // Read the parameter entity value
+ bqstr('d');
+ // Create the parameter entity value
+ val = new char[mBuffIdx + 1];
+ System.arraycopy(mBuff, 1, val, 1, val.length - 1);
+ // Add surrounding spaces [#4.4.8]
+ val[0] = ' ';
+ // Add the entity to the entity look up table
+ if (mPEnt.containsKey(str) == false) { // [#4.2]
+ inp = new Input(val);
+ inp.pubid = mInp.pubid;
+ inp.sysid = mInp.sysid;
+ inp.xmlenc = mInp.xmlenc;
+ inp.xmlver = mInp.xmlver;
+ mPEnt.put(str, inp);
+ }
+ st = -1; // the end of declaration
+ break;
+
+ default:
+ panic(FAULT);
+ break;
+ }
+ } else {
+ // Parameter entity reference.
+ pent(' ');
+ }
+ break;
+
+ default:
+ bkch();
+ str = name(false);
+ st = 1; // read entity declaration value
+ break;
+ }
+ break;
+
+ case 1: // read entity declaration value
+ switch (chtyp(ch)) {
+ case '\"': // internal entity
+ case '\'':
+ bkch();
+ bqstr('d'); // read a string into the buffer
+ if (mEnt.get(str) == null) {
+ // Create general entity value
+ val = new char[mBuffIdx];
+ System.arraycopy(mBuff, 1, val, 0, val.length);
+ // Add the entity to the entity look up table
+ if (mEnt.containsKey(str) == false) { // [#4.2]
+ inp = new Input(val);
+ inp.pubid = mInp.pubid;
+ inp.sysid = mInp.sysid;
+ inp.xmlenc = mInp.xmlenc;
+ inp.xmlver = mInp.xmlver;
+ mEnt.put(str, inp);
+ }
+ }
+ st = -1; // the end of declaration
+ break;
+
+ case 'A': // external entity
+ bkch();
+ ids = pubsys(' ');
+ switch (wsskip()) {
+ case '>': // external parsed entity
+ if (mEnt.containsKey(str) == false) { // [#4.2]
+ inp = new Input();
+ inp.pubid = ids.name;
+ inp.sysid = ids.value;
+ mEnt.put(str, inp);
+ }
+ break;
+
+ case 'N': // external general unparsed entity
+ if ("NDATA".equals(name(false)) == true) {
+ wsskip();
+ unparsedEntDecl(str, ids.name, ids.value, name(false));
+ break;
+ }
+ default:
+ panic(FAULT);
+ break;
+ }
+ del(ids);
+ st = -1; // the end of declaration
+ break;
+
+ case ' ':
+ // Skip white spaces
+ break;
+
+ default:
+ panic(FAULT);
+ break;
+ }
+ break;
+
+ default:
+ panic(FAULT);
+ }
+ }
+ }
+
+ /**
+ * Parses an element declaration.
+ *
+ * This method parses the declaration up to the closing angle bracket.
+ *
+ * @exception Exception is parser specific exception form panic method.
+ * @exception IOException
+ */
+ @SuppressWarnings("fallthrough")
+ private void dtdelm() throws Exception {
+ // This is stub implementation which skips an element
+ // declaration.
+ wsskip();
+ name(mIsNSAware);
+
+ char ch;
+ while (true) {
+ ch = getch();
+ switch (ch) {
+ case '>':
+ bkch();
+ return;
+
+ case EOS:
+ panic(FAULT);
+
+ default:
+ break;
+ }
+ }
+ }
+
+ /**
+ * Parses an attribute list declaration.
+ *
+ * This method parses the declaration up to the closing angle bracket.
+ *
+ * @exception Exception is parser specific exception form panic method.
+ * @exception IOException
+ */
+ private void dtdattl() throws Exception {
+ char elmqn[] = null;
+ Pair elm = null;
+ char ch;
+ for (short st = 0; st >= 0;) {
+ ch = getch();
+ switch (st) {
+ case 0: // read the element name
+ switch (chtyp(ch)) {
+ case 'a':
+ case 'A':
+ case '_':
+ case 'X':
+ case ':':
+ bkch();
+ // Get the element from the list or add a new one.
+ elmqn = qname(mIsNSAware);
+ elm = find(mAttL, elmqn);
+ if (elm == null) {
+ elm = pair(mAttL);
+ elm.chars = elmqn;
+ mAttL = elm;
+ }
+ st = 1; // read an attribute declaration
+ break;
+
+ case ' ':
+ break;
+
+ case '%':
+ pent(' ');
+ break;
+
+ default:
+ panic(FAULT);
+ break;
+ }
+ break;
+
+ case 1: // read an attribute declaration
+ switch (chtyp(ch)) {
+ case 'a':
+ case 'A':
+ case '_':
+ case 'X':
+ case ':':
+ bkch();
+ dtdatt(elm);
+ if (wsskip() == '>') {
+ return;
+ }
+ break;
+
+ case ' ':
+ break;
+
+ case '%':
+ pent(' ');
+ break;
+
+ default:
+ panic(FAULT);
+ break;
+ }
+ break;
+
+ default:
+ panic(FAULT);
+ break;
+ }
+ }
+ }
+
+ /**
+ * Parses an attribute declaration.
+ *
+ * The attribute uses the following fields of Pair object: chars - characters
+ * of qualified name id - the type identifier of the attribute list - a pair
+ * which holds the default value (chars field)
+ *
+ * @param elm An object which represents all defined attributes on an
+ * element.
+ * @exception Exception is parser specific exception form panic method.
+ * @exception IOException
+ */
+ @SuppressWarnings("fallthrough")
+ private void dtdatt(Pair elm) throws Exception {
+ char attqn[] = null;
+ Pair att = null;
+ char ch;
+ for (short st = 0; st >= 0;) {
+ ch = getch();
+ switch (st) {
+ case 0: // the attribute name
+ switch (chtyp(ch)) {
+ case 'a':
+ case 'A':
+ case '_':
+ case 'X':
+ case ':':
+ bkch();
+ // Get the attribut from the list or add a new one.
+ attqn = qname(mIsNSAware);
+ att = find(elm.list, attqn);
+ if (att == null) {
+ // New attribute declaration
+ att = pair(elm.list);
+ att.chars = attqn;
+ elm.list = att;
+ } else {
+ // Do not override the attribute declaration [#3.3]
+ att = pair(null);
+ att.chars = attqn;
+ att.id = 'c';
+ }
+ wsskip();
+ st = 1;
+ break;
+
+ case '%':
+ pent(' ');
+ break;
+
+ case ' ':
+ break;
+
+ default:
+ panic(FAULT);
+ break;
+ }
+ break;
+
+ case 1: // the attribute type
+ switch (chtyp(ch)) {
+ case '(':
+ att.id = 'u'; // enumeration type
+ st = 2; // read the first element of the list
+ break;
+
+ case '%':
+ pent(' ');
+ break;
+
+ case ' ':
+ break;
+
+ default:
+ bkch();
+ bntok(); // read type id
+ att.id = bkeyword();
+ switch (att.id) {
+ case 'o': // NOTATION
+ if (wsskip() != '(') {
+ panic(FAULT);
+ }
+ ch = getch();
+ st = 2; // read the first element of the list
+ break;
+
+ case 'i': // ID
+ case 'r': // IDREF
+ case 'R': // IDREFS
+ case 'n': // ENTITY
+ case 'N': // ENTITIES
+ case 't': // NMTOKEN
+ case 'T': // NMTOKENS
+ case 'c': // CDATA
+ wsskip();
+ st = 4; // read default declaration
+ break;
+
+ default:
+ panic(FAULT);
+ break;
+ }
+ break;
+ }
+ break;
+
+ case 2: // read the first element of the list
+ switch (chtyp(ch)) {
+ case 'a':
+ case 'A':
+ case 'd':
+ case '.':
+ case ':':
+ case '-':
+ case '_':
+ case 'X':
+ bkch();
+ switch (att.id) {
+ case 'u': // enumeration type
+ bntok();
+ break;
+
+ case 'o': // NOTATION
+ mBuffIdx = -1;
+ bname(false);
+ break;
+
+ default:
+ panic(FAULT);
+ break;
+ }
+ wsskip();
+ st = 3; // read next element of the list
+ break;
+
+ case '%':
+ pent(' ');
+ break;
+
+ case ' ':
+ break;
+
+ default:
+ panic(FAULT);
+ break;
+ }
+ break;
+
+ case 3: // read next element of the list
+ switch (ch) {
+ case ')':
+ wsskip();
+ st = 4; // read default declaration
+ break;
+
+ case '|':
+ wsskip();
+ switch (att.id) {
+ case 'u': // enumeration type
+ bntok();
+ break;
+
+ case 'o': // NOTATION
+ mBuffIdx = -1;
+ bname(false);
+ break;
+
+ default:
+ panic(FAULT);
+ break;
+ }
+ wsskip();
+ break;
+
+ case '%':
+ pent(' ');
+ break;
+
+ default:
+ panic(FAULT);
+ break;
+ }
+ break;
+
+ case 4: // read default declaration
+ switch (ch) {
+ case '#':
+ bntok();
+ switch (bkeyword()) {
+ case 'F': // FIXED
+ switch (wsskip()) {
+ case '\"':
+ case '\'':
+ st = 5; // read the default value
+ break;
+
+ case EOS:
+ panic(FAULT);
+
+ default:
+ st = -1;
+ break;
+ }
+ break;
+
+ case 'Q': // REQUIRED
+ case 'I': // IMPLIED
+ st = -1;
+ break;
+
+ default:
+ panic(FAULT);
+ break;
+ }
+ break;
+
+ case '\"':
+ case '\'':
+ bkch();
+ st = 5; // read the default value
+ break;
+
+ case ' ':
+ case '\n':
+ case '\r':
+ case '\t':
+ break;
+
+ case '%':
+ pent(' ');
+ break;
+
+ default:
+ bkch();
+ st = -1;
+ break;
+ }
+ break;
+
+ case 5: // read the default value
+ switch (ch) {
+ case '\"':
+ case '\'':
+ bkch();
+ bqstr('d'); // the value in the mBuff now
+ att.list = pair(null);
+ // Create a string like "attqname='value' "
+ att.list.chars = new char[att.chars.length + mBuffIdx + 3];
+ System.arraycopy(
+ att.chars, 1, att.list.chars, 0, att.chars.length - 1);
+ att.list.chars[att.chars.length - 1] = '=';
+ att.list.chars[att.chars.length] = ch;
+ System.arraycopy(
+ mBuff, 1, att.list.chars, att.chars.length + 1, mBuffIdx);
+ att.list.chars[att.chars.length + mBuffIdx + 1] = ch;
+ att.list.chars[att.chars.length + mBuffIdx + 2] = ' ';
+ st = -1;
+ break;
+
+ default:
+ panic(FAULT);
+ break;
+ }
+ break;
+
+ default:
+ panic(FAULT);
+ break;
+ }
+ }
+ }
+
+ /**
+ * Parses a notation declaration.
+ *
+ * This method parses the declaration up to the closing angle bracket.
+ *
+ * @exception Exception is parser specific exception form panic method.
+ * @exception IOException
+ */
+ private void dtdnot() throws Exception {
+ wsskip();
+ String name = name(false);
+ wsskip();
+ Pair ids = pubsys('N');
+ notDecl(name, ids.name, ids.value);
+ del(ids);
+ }
+
+ /**
+ * Parses an attribute.
+ *
+ * This recursive method is responsible for prefix addition
+ * (
+ * <code>mPref</code>) on the way down. The element's start tag end triggers
+ * the return process. The method then on it's way back resolves prefixes
+ * and accumulates attributes.
+ *
+ * <p><code>att.num</code> carries attribute flags where: 0x1 - attribute is
+ * declared in DTD (attribute decalration had been read); 0x2 - attribute's
+ * default value is used.</p>
+ *
+ * @param att An object which reprecents current attribute.
+ * @exception Exception is parser specific exception form panic method.
+ * @exception IOException
+ */
+ @SuppressWarnings("fallthrough")
+ private void attr(Pair att) throws Exception {
+ switch (wsskip()) {
+ case '/':
+ case '>':
+ if ((att.num & 0x2) == 0) { // all attributes have been read
+ att.num |= 0x2; // set default attribute flag
+ Input inp = mInp;
+ // Go through all attributes defined on current element.
+ for (Pair def = mElm.list; def != null; def = def.next) {
+ if (def.list == null) // no default value
+ {
+ continue;
+ }
+ // Go through all attributes defined on current
+ // element and add defaults.
+ Pair act = find(att.next, def.chars);
+ if (act == null) {
+ push(new Input(def.list.chars));
+ }
+ }
+ if (mInp != inp) { // defaults have been added
+ attr(att);
+ return;
+ }
+ }
+ // Ensure the attribute string array capacity
+ mAttrs.setLength(mAttrIdx);
+ mItems = mAttrs.mItems;
+ return;
+
+ case EOS:
+ panic(FAULT);
+
+ default:
+ // Read the attribute name and value
+ att.chars = qname(mIsNSAware);
+ att.name = att.local();
+ String type = atype(att); // sets attribute's type on att.id
+ wsskip();
+ if (getch() != '=') {
+ panic(FAULT);
+ }
+ bqstr((char) att.id); // read the value with normalization.
+ String val = new String(mBuff, 1, mBuffIdx);
+ Pair next = pair(att);
+ next.num = (att.num & ~0x1); // inherit attribute flags
+ // Put a namespace declaration on top of the prefix stack
+ if ((mIsNSAware == false) || (isdecl(att, val) == false)) {
+ // An ordinary attribute
+ mAttrIdx++;
+ attr(next); // recursive call to parse the next attribute
+ mAttrIdx--;
+ // Add the attribute to the attributes string array
+ char idx = (char) (mAttrIdx << 3);
+ mItems[idx + 1] = att.qname(); // attr qname
+ mItems[idx + 2] = (mIsNSAware) ? att.name : ""; // attr local name
+ mItems[idx + 3] = val; // attr value
+ mItems[idx + 4] = type; // attr type
+ switch (att.num & 0x3) {
+ case 0x0:
+ mItems[idx + 5] = null;
+ break;
+
+ case 0x1: // declared attribute
+ mItems[idx + 5] = "d";
+ break;
+
+ default: // 0x2, 0x3 - default attribute always declared
+ mItems[idx + 5] = "D";
+ break;
+ }
+ // Resolve the prefix if any and report the attribute
+ // NOTE: The attribute does not accept the default namespace.
+ mItems[idx + 0] = (att.chars[0] != 0) ? rslv(att.chars) : "";
+ } else {
+ // A namespace declaration. mPref.name contains prefix and
+ // mPref.value contains namespace URI set by isdecl method.
+ // Report a start of the new mapping
+ newPrefix();
+ // Recursive call to parse the next attribute
+ attr(next);
+ // NOTE: The namespace declaration is not reported.
+ }
+ del(next);
+ break;
+ }
+ }
+
+ /**
+ * Retrieves attribute type.
+ *
+ * This method sets the type of normalization in the attribute
+ * <code>id</code> field and returns the name of attribute type.
+ *
+ * @param att An object which represents current attribute.
+ * @return The name of the attribute type.
+ * @exception Exception is parser specific exception form panic method.
+ */
+ private String atype(Pair att)
+ throws Exception {
+ Pair attr;
+
+ // CDATA-type normalization by default [#3.3.3]
+ att.id = 'c';
+ if (mElm.list == null || (attr = find(mElm.list, att.chars)) == null) {
+ return "CDATA";
+ }
+
+ att.num |= 0x1; // attribute is declared
+
+ // Non-CDATA normalization except when the attribute type is CDATA.
+ att.id = 'i';
+ switch (attr.id) {
+ case 'i':
+ return "ID";
+
+ case 'r':
+ return "IDREF";
+
+ case 'R':
+ return "IDREFS";
+
+ case 'n':
+ return "ENTITY";
+
+ case 'N':
+ return "ENTITIES";
+
+ case 't':
+ return "NMTOKEN";
+
+ case 'T':
+ return "NMTOKENS";
+
+ case 'u':
+ return "NMTOKEN";
+
+ case 'o':
+ return "NOTATION";
+
+ case 'c':
+ att.id = 'c';
+ return "CDATA";
+
+ default:
+ panic(FAULT);
+ }
+ return null;
+ }
+
+ /**
+ * Parses a comment.
+ *
+ * The '<!' part is read in dispatcher so the method starts
+ * with first '-' after '<!'.
+ *
+ * @exception Exception is parser specific exception form panic method.
+ */
+ @SuppressWarnings("fallthrough")
+ private void comm() throws Exception {
+ if (mPh == PH_DOC_START) {
+ mPh = PH_MISC_DTD; // misc before DTD
+ } // '<!' has been already read by dispetcher.
+ char ch;
+ mBuffIdx = -1;
+ for (short st = 0; st >= 0;) {
+ ch = (mChIdx < mChLen) ? mChars[mChIdx++] : getch();
+ if (ch == EOS) {
+ panic(FAULT);
+ }
+ switch (st) {
+ case 0: // first '-' of the comment open
+ if (ch == '-') {
+ st = 1;
+ } else {
+ panic(FAULT);
+ }
+ break;
+
+ case 1: // secind '-' of the comment open
+ if (ch == '-') {
+ st = 2;
+ } else {
+ panic(FAULT);
+ }
+ break;
+
+ case 2: // skip the comment body
+ switch (ch) {
+ case '-':
+ st = 3;
+ break;
+
+ default:
+ bappend(ch);
+ break;
+ }
+ break;
+
+ case 3: // second '-' of the comment close
+ switch (ch) {
+ case '-':
+ st = 4;
+ break;
+
+ default:
+ bappend('-');
+ bappend(ch);
+ st = 2;
+ break;
+ }
+ break;
+
+ case 4: // '>' of the comment close
+ if (ch == '>') {
+ comm(mBuff, mBuffIdx + 1);
+ st = -1;
+ break;
+ }
+ // else - panic [#2.5 compatibility note]
+
+ default:
+ panic(FAULT);
+ }
+ }
+ }
+
+ /**
+ * Parses a processing instruction.
+ *
+ * The '<?' is read in dispatcher so the method starts with
+ * first character of PI target name after '<?'.
+ *
+ * @exception Exception is parser specific exception form panic method.
+ * @exception IOException
+ */
+ private void pi() throws Exception {
+ // '<?' has been already read by dispetcher.
+ char ch;
+ String str = null;
+ mBuffIdx = -1;
+ for (short st = 0; st >= 0;) {
+ ch = getch();
+ if (ch == EOS) {
+ panic(FAULT);
+ }
+ switch (st) {
+ case 0: // read the PI target name
+ switch (chtyp(ch)) {
+ case 'a':
+ case 'A':
+ case '_':
+ case ':':
+ case 'X':
+ bkch();
+ str = name(false);
+ // PI target name may not be empty string [#2.6]
+ // PI target name 'XML' is reserved [#2.6]
+ if ((str.length() == 0)
+ || (mXml.name.equals(str.toLowerCase()) == true)) {
+ panic(FAULT);
+ }
+ // This is processing instruction
+ if (mPh == PH_DOC_START) // the begining of the document
+ {
+ mPh = PH_MISC_DTD; // misc before DTD
+ }
+ wsskip(); // skip spaces after the PI target name
+ st = 1; // accumulate the PI body
+ mBuffIdx = -1;
+ break;
+
+ default:
+ panic(FAULT);
+ }
+ break;
+
+ case 1: // accumulate the PI body
+ switch (ch) {
+ case '?':
+ st = 2; // end of the PI body
+ break;
+
+ default:
+ bappend(ch);
+ break;
+ }
+ break;
+
+ case 2: // end of the PI body
+ switch (ch) {
+ case '>':
+ // PI has been read.
+ pi(str, new String(mBuff, 0, mBuffIdx + 1));
+ st = -1;
+ break;
+
+ case '?':
+ bappend('?');
+ break;
+
+ default:
+ bappend('?');
+ bappend(ch);
+ st = 1; // accumulate the PI body
+ break;
+ }
+ break;
+
+ default:
+ panic(FAULT);
+ }
+ }
+ }
+
+ /**
+ * Parses a character data.
+ *
+ * The '<!' part is read in dispatcher so the method starts
+ * with first '[' after '<!'.
+ *
+ * @exception Exception is parser specific exception form panic method.
+ * @exception IOException
+ */
+ private void cdat()
+ throws Exception {
+ // '<!' has been already read by dispetcher.
+ char ch;
+ mBuffIdx = -1;
+ for (short st = 0; st >= 0;) {
+ ch = getch();
+ switch (st) {
+ case 0: // the first '[' of the CDATA open
+ if (ch == '[') {
+ st = 1;
+ } else {
+ panic(FAULT);
+ }
+ break;
+
+ case 1: // read "CDATA"
+ if (chtyp(ch) == 'A') {
+ bappend(ch);
+ } else {
+ if ("CDATA".equals(
+ new String(mBuff, 0, mBuffIdx + 1)) != true) {
+ panic(FAULT);
+ }
+ bkch();
+ st = 2;
+ }
+ break;
+
+ case 2: // the second '[' of the CDATA open
+ if (ch != '[') {
+ panic(FAULT);
+ }
+ mBuffIdx = -1;
+ st = 3;
+ break;
+
+ case 3: // read data before the first ']'
+ if (ch != ']') {
+ bappend(ch);
+ } else {
+ st = 4;
+ }
+ break;
+
+ case 4: // read the second ']' or continue to read the data
+ if (ch != ']') {
+ bappend(']');
+ bappend(ch);
+ st = 3;
+ } else {
+ st = 5;
+ }
+ break;
+
+ case 5: // read '>' or continue to read the data
+ switch (ch) {
+ case ']':
+ bappend(']');
+ break;
+
+ case '>':
+ bflash();
+ st = -1;
+ break;
+
+ default:
+ bappend(']');
+ bappend(']');
+ bappend(ch);
+ st = 3;
+ break;
+ }
+ break;
+
+ default:
+ panic(FAULT);
+ }
+ }
+ }
+
+ /**
+ * Reads a xml name.
+ *
+ * The xml name must conform "Namespaces in XML" specification. Therefore
+ * the ':' character is not allowed in the name. This method should be used
+ * for PI and entity names which may not have a namespace according to the
+ * specification mentioned above.
+ *
+ * @param ns The true value turns namespace conformance on.
+ * @return The name has been read.
+ * @exception Exception When incorrect character appear in the name.
+ * @exception IOException
+ */
+ protected String name(boolean ns)
+ throws Exception {
+ mBuffIdx = -1;
+ bname(ns);
+ return new String(mBuff, 1, mBuffIdx);
+ }
+
+ /**
+ * Reads a qualified xml name.
+ *
+ * The characters of a qualified name is an array of characters. The first
+ * (chars[0]) character is the index of the colon character which separates
+ * the prefix from the local name. If the index is zero, the name does not
+ * contain separator or the parser works in the namespace unaware mode. The
+ * length of qualified name is the length of the array minus one.
+ *
+ * @param ns The true value turns namespace conformance on.
+ * @return The characters of a qualified name.
+ * @exception Exception When incorrect character appear in the name.
+ * @exception IOException
+ */
+ protected char[] qname(boolean ns)
+ throws Exception {
+ mBuffIdx = -1;
+ bname(ns);
+ char chars[] = new char[mBuffIdx + 1];
+ System.arraycopy(mBuff, 0, chars, 0, mBuffIdx + 1);
+ return chars;
+ }
+
+ /**
+ * Reads the public or/and system identifiers.
+ *
+ * @param inp The input object.
+ * @exception Exception is parser specific exception form panic method.
+ * @exception IOException
+ */
+ private void pubsys(Input inp)
+ throws Exception {
+ Pair pair = pubsys(' ');
+ inp.pubid = pair.name;
+ inp.sysid = pair.value;
+ del(pair);
+ }
+
+ /**
+ * Reads the public or/and system identifiers.
+ *
+ * @param flag The 'N' allows public id be without system id.
+ * @return The public or/and system identifiers pair.
+ * @exception Exception is parser specific exception form panic method.
+ * @exception IOException
+ */
+ @SuppressWarnings("fallthrough")
+ private Pair pubsys(char flag) throws Exception {
+ Pair ids = pair(null);
+ String str = name(false);
+ if ("PUBLIC".equals(str) == true) {
+ bqstr('i'); // non-CDATA normalization [#4.2.2]
+ ids.name = new String(mBuff, 1, mBuffIdx);
+ switch (wsskip()) {
+ case '\"':
+ case '\'':
+ bqstr(' ');
+ ids.value = new String(mBuff, 1, mBuffIdx);
+ break;
+
+ case EOS:
+ panic(FAULT);
+
+ default:
+ if (flag != 'N') // [#4.7]
+ {
+ panic(FAULT);
+ }
+ ids.value = null;
+ break;
+ }
+ return ids;
+ } else if ("SYSTEM".equals(str) == true) {
+ ids.name = null;
+ bqstr(' ');
+ ids.value = new String(mBuff, 1, mBuffIdx);
+ return ids;
+ }
+ panic(FAULT);
+ return null;
+ }
+
+ /**
+ * Reads an attribute value.
+ *
+ * The grammar which this method can read is:<br />
+ * <code>eqstr := S "=" qstr</code><br />
+ * <code>qstr := S ("'" string "'") |
+ * ('"' string '"')</code><br /> This method resolves entities
+ * inside a string unless the parser parses DTD.
+ *
+ * @param flag The '=' character forces the method to accept the '='
+ * character before quoted string and read the following string as not an
+ * attribute ('-'), 'c' - CDATA, 'i' - non CDATA, ' ' - no normalization;
+ * '-' - not an attribute value; 'd' - in DTD context.
+ * @return The content of the quoted strign as a string.
+ * @exception Exception is parser specific exception form panic method.
+ * @exception IOException
+ */
+ protected String eqstr(char flag) throws Exception {
+ if (flag == '=') {
+ wsskip();
+ if (getch() != '=') {
+ panic(FAULT);
+ }
+ }
+ bqstr((flag == '=') ? '-' : flag);
+ return new String(mBuff, 1, mBuffIdx);
+ }
+
+ /**
+ * Resoves an entity.
+ *
+ * This method resolves built-in and character entity references. It is also
+ * reports external entities to the application.
+ *
+ * @param flag The 'x' character forces the method to report a skipped
+ * entity; 'i' character - indicates non-CDATA normalization.
+ * @return Name of unresolved entity or <code>null</code> if entity had been
+ * resolved successfully.
+ * @exception Exception is parser specific exception form panic method.
+ * @exception IOException
+ */
+ @SuppressWarnings("fallthrough")
+ private String ent(char flag) throws Exception {
+ char ch;
+ int idx = mBuffIdx + 1;
+ Input inp = null;
+ String str = null;
+ mESt = 0x100; // reset the built-in entity recognizer
+ bappend('&');
+ for (short st = 0; st >= 0;) {
+ ch = (mChIdx < mChLen) ? mChars[mChIdx++] : getch();
+ switch (st) {
+ case 0: // the first character of the entity name
+ case 1: // read built-in entity name
+ switch (chtyp(ch)) {
+ case 'd':
+ case '.':
+ case '-':
+ if (st != 1) {
+ panic(FAULT);
+ }
+ case 'a':
+ case 'A':
+ case '_':
+ case 'X':
+ bappend(ch);
+ eappend(ch);
+ st = 1;
+ break;
+
+ case ':':
+ if (mIsNSAware != false) {
+ panic(FAULT);
+ }
+ bappend(ch);
+ eappend(ch);
+ st = 1;
+ break;
+
+ case ';':
+ if (mESt < 0x100) {
+ // The entity is a built-in entity
+ mBuffIdx = idx - 1;
+ bappend(mESt);
+ st = -1;
+ break;
+ } else if (mPh == PH_DTD) {
+ // In DTD entity declaration has to resolve character
+ // entities and include "as is" others. [#4.4.7]
+ bappend(';');
+ st = -1;
+ break;
+ }
+ // Convert an entity name to a string
+ str = new String(mBuff, idx + 1, mBuffIdx - idx);
+ inp = mEnt.get(str);
+ // Restore the buffer offset
+ mBuffIdx = idx - 1;
+ if (inp != null) {
+ if (inp.chars == null) {
+ // External entity
+ InputSource is = resolveEnt(str, inp.pubid, inp.sysid);
+ if (is != null) {
+ push(new Input(BUFFSIZE_READER));
+ setinp(is);
+ mInp.pubid = inp.pubid;
+ mInp.sysid = inp.sysid;
+ str = null; // the entity is resolved
+ } else {
+ // Unresolved external entity
+ if (flag != 'x') {
+ panic(FAULT); // unknown entity within marckup
+ } // str is name of unresolved entity
+ }
+ } else {
+ // Internal entity
+ push(inp);
+ str = null; // the entity is resolved
+ }
+ } else {
+ // Unknown or general unparsed entity
+ if (flag != 'x') {
+ panic(FAULT); // unknown entity within marckup
+ } // str is name of unresolved entity
+ }
+ st = -1;
+ break;
+
+ case '#':
+ if (st != 0) {
+ panic(FAULT);
+ }
+ st = 2;
+ break;
+
+ default:
+ panic(FAULT);
+ }
+ break;
+
+ case 2: // read character entity
+ switch (chtyp(ch)) {
+ case 'd':
+ bappend(ch);
+ break;
+
+ case ';':
+ // Convert the character entity to a character
+ try {
+ int i = Integer.parseInt(
+ new String(mBuff, idx + 1, mBuffIdx - idx), 10);
+ if (i >= 0xffff) {
+ panic(FAULT);
+ }
+ ch = (char) i;
+ } catch (NumberFormatException nfe) {
+ panic(FAULT);
+ }
+ // Restore the buffer offset
+ mBuffIdx = idx - 1;
+ if (ch == ' ' || mInp.next != null) {
+ bappend(ch, flag);
+ } else {
+ bappend(ch);
+ }
+ st = -1;
+ break;
+
+ case 'a':
+ // If the entity buffer is empty and ch == 'x'
+ if ((mBuffIdx == idx) && (ch == 'x')) {
+ st = 3;
+ break;
+ }
+ default:
+ panic(FAULT);
+ }
+ break;
+
+ case 3: // read hex character entity
+ switch (chtyp(ch)) {
+ case 'A':
+ case 'a':
+ case 'd':
+ bappend(ch);
+ break;
+
+ case ';':
+ // Convert the character entity to a character
+ try {
+ int i = Integer.parseInt(
+ new String(mBuff, idx + 1, mBuffIdx - idx), 16);
+ if (i >= 0xffff) {
+ panic(FAULT);
+ }
+ ch = (char) i;
+ } catch (NumberFormatException nfe) {
+ panic(FAULT);
+ }
+ // Restore the buffer offset
+ mBuffIdx = idx - 1;
+ if (ch == ' ' || mInp.next != null) {
+ bappend(ch, flag);
+ } else {
+ bappend(ch);
+ }
+ st = -1;
+ break;
+
+ default:
+ panic(FAULT);
+ }
+ break;
+
+ default:
+ panic(FAULT);
+ }
+ }
+
+ return str;
+ }
+
+ /**
+ * Resoves a parameter entity.
+ *
+ * This method resolves a parameter entity references. It is also reports
+ * external entities to the application.
+ *
+ * @param flag The '-' instruct the method to do not set up surrounding
+ * spaces [#4.4.8].
+ * @exception Exception is parser specific exception form panic method.
+ * @exception IOException
+ */
+ @SuppressWarnings("fallthrough")
+ private void pent(char flag) throws Exception {
+ char ch;
+ int idx = mBuffIdx + 1;
+ Input inp = null;
+ String str = null;
+ bappend('%');
+ if (mPh != PH_DTD) // the DTD internal subset
+ {
+ return; // Not Recognized [#4.4.1]
+ } // Read entity name
+ bname(false);
+ str = new String(mBuff, idx + 2, mBuffIdx - idx - 1);
+ if (getch() != ';') {
+ panic(FAULT);
+ }
+ inp = mPEnt.get(str);
+ // Restore the buffer offset
+ mBuffIdx = idx - 1;
+ if (inp != null) {
+ if (inp.chars == null) {
+ // External parameter entity
+ InputSource is = resolveEnt(str, inp.pubid, inp.sysid);
+ if (is != null) {
+ if (flag != '-') {
+ bappend(' '); // tail space
+ }
+ push(new Input(BUFFSIZE_READER));
+ // BUG: there is no leading space! [#4.4.8]
+ setinp(is);
+ mInp.pubid = inp.pubid;
+ mInp.sysid = inp.sysid;
+ } else {
+ // Unresolved external parameter entity
+ skippedEnt("%" + str);
+ }
+ } else {
+ // Internal parameter entity
+ if (flag == '-') {
+ // No surrounding spaces
+ inp.chIdx = 1;
+ } else {
+ // Insert surrounding spaces
+ bappend(' '); // tail space
+ inp.chIdx = 0;
+ }
+ push(inp);
+ }
+ } else {
+ // Unknown parameter entity
+ skippedEnt("%" + str);
+ }
+ }
+
+ /**
+ * Recognizes and handles a namespace declaration.
+ *
+ * This method identifies a type of namespace declaration if any and puts
+ * new mapping on top of prefix stack.
+ *
+ * @param name The attribute qualified name (<code>name.value</code> is a
+ * <code>String</code> object which represents the attribute prefix).
+ * @param value The attribute value.
+ * @return <code>true</code> if a namespace declaration is recognized.
+ */
+ private boolean isdecl(Pair name, String value) {
+ if (name.chars[0] == 0) {
+ if ("xmlns".equals(name.name) == true) {
+ // New default namespace declaration
+ mPref = pair(mPref);
+ mPref.list = mElm; // prefix owner element
+ mPref.value = value;
+ mPref.name = "";
+ mPref.chars = NONS;
+ mElm.num++; // namespace counter
+ return true;
+ }
+ } else {
+ if (name.eqpref(XMLNS) == true) {
+ // New prefix declaration
+ int len = name.name.length();
+ mPref = pair(mPref);
+ mPref.list = mElm; // prefix owner element
+ mPref.value = value;
+ mPref.name = name.name;
+ mPref.chars = new char[len + 1];
+ mPref.chars[0] = (char) (len + 1);
+ name.name.getChars(0, len, mPref.chars, 1);
+ mElm.num++; // namespace counter
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Resolves a prefix.
+ *
+ * @return The namespace assigned to the prefix.
+ * @exception Exception When mapping for specified prefix is not found.
+ */
+ private String rslv(char[] qname)
+ throws Exception {
+ for (Pair pref = mPref; pref != null; pref = pref.next) {
+ if (pref.eqpref(qname) == true) {
+ return pref.value;
+ }
+ }
+ if (qname[0] == 1) { // QNames like ':local'
+ for (Pair pref = mPref; pref != null; pref = pref.next) {
+ if (pref.chars[0] == 0) {
+ return pref.value;
+ }
+ }
+ }
+ panic(FAULT);
+ return null;
+ }
+
+ /**
+ * Skips xml white space characters.
+ *
+ * This method skips white space characters (' ', '\t', '\n', '\r') and
+ * looks ahead not white space character.
+ *
+ * @return The first not white space look ahead character.
+ * @exception IOException
+ */
+ protected char wsskip()
+ throws IOException {
+ char ch;
+ while (true) {
+ // Read next character
+ ch = (mChIdx < mChLen) ? mChars[mChIdx++] : getch();
+ if (ch < 0x80) {
+ if (nmttyp[ch] != 3) // [ \t\n\r]
+ {
+ break;
+ }
+ } else {
+ break;
+ }
+ }
+ mChIdx--; // bkch();
+ return ch;
+ }
+
+ /**
+ * Reports document type.
+ *
+ * @param name The name of the entity.
+ * @param pubid The public identifier of the entity or <code>null</code>.
+ * @param sysid The system identifier of the entity or <code>null</code>.
+ */
+ protected abstract void docType(String name, String pubid, String sysid)
+ throws SAXException;
+
+ /**
+ * Reports a comment.
+ *
+ * @param text The comment text starting from first charcater.
+ * @param length The number of characters in comment.
+ */
+ protected abstract void comm(char[] text, int length);
+
+ /**
+ * Reports a processing instruction.
+ *
+ * @param target The processing instruction target name.
+ * @param body The processing instruction body text.
+ */
+ protected abstract void pi(String target, String body)
+ throws Exception;
+
+ /**
+ * Reports new namespace prefix. The Namespace prefix (
+ * <code>mPref.name</code>) being declared and the Namespace URI (
+ * <code>mPref.value</code>) the prefix is mapped to. An empty string is
+ * used for the default element namespace, which has no prefix.
+ */
+ protected abstract void newPrefix()
+ throws Exception;
+
+ /**
+ * Reports skipped entity name.
+ *
+ * @param name The entity name.
+ */
+ protected abstract void skippedEnt(String name)
+ throws Exception;
+
+ /**
+ * Returns an
+ * <code>InputSource</code> for specified entity or
+ * <code>null</code>.
+ *
+ * @param name The name of the entity.
+ * @param pubid The public identifier of the entity.
+ * @param sysid The system identifier of the entity.
+ */
+ protected abstract InputSource resolveEnt(
+ String name, String pubid, String sysid)
+ throws Exception;
+
+ /**
+ * Reports notation declaration.
+ *
+ * @param name The notation's name.
+ * @param pubid The notation's public identifier, or null if none was given.
+ * @param sysid The notation's system identifier, or null if none was given.
+ */
+ protected abstract void notDecl(String name, String pubid, String sysid)
+ throws Exception;
+
+ /**
+ * Reports unparsed entity name.
+ *
+ * @param name The unparsed entity's name.
+ * @param pubid The entity's public identifier, or null if none was given.
+ * @param sysid The entity's system identifier.
+ * @param notation The name of the associated notation.
+ */
+ protected abstract void unparsedEntDecl(
+ String name, String pubid, String sysid, String notation)
+ throws Exception;
+
+ /**
+ * Notifies the handler about fatal parsing error.
+ *
+ * @param msg The problem description message.
+ */
+ protected abstract void panic(String msg)
+ throws Exception;
+
+ /**
+ * Reads a qualified xml name.
+ *
+ * This is low level routine which leaves a qName in the buffer. The
+ * characters of a qualified name is an array of characters. The first
+ * (chars[0]) character is the index of the colon character which separates
+ * the prefix from the local name. If the index is zero, the name does not
+ * contain separator or the parser works in the namespace unaware mode. The
+ * length of qualified name is the length of the array minus one.
+ *
+ * @param ns The true value turns namespace conformance on.
+ * @exception Exception is parser specific exception form panic method.
+ * @exception IOException
+ */
+ private void bname(boolean ns)
+ throws Exception {
+ char ch;
+ char type;
+ mBuffIdx++; // allocate a char for colon offset
+ int bqname = mBuffIdx;
+ int bcolon = bqname;
+ int bchidx = bqname + 1;
+ int bstart = bchidx;
+ int cstart = mChIdx;
+ short st = (short) ((ns == true) ? 0 : 2);
+ while (true) {
+ // Read next character
+ if (mChIdx >= mChLen) {
+ bcopy(cstart, bstart);
+ getch();
+ mChIdx--; // bkch();
+ cstart = mChIdx;
+ bstart = bchidx;
+ }
+ ch = mChars[mChIdx++];
+ type = (char) 0; // [X]
+ if (ch < 0x80) {
+ type = (char) nmttyp[ch];
+ } else if (ch == EOS) {
+ panic(FAULT);
+ }
+ // Parse QName
+ switch (st) {
+ case 0: // read the first char of the prefix
+ case 2: // read the first char of the suffix
+ switch (type) {
+ case 0: // [aA_X]
+ bchidx++; // append char to the buffer
+ st++; // (st == 0)? 1: 3;
+ break;
+
+ case 1: // [:]
+ mChIdx--; // bkch();
+ st++; // (st == 0)? 1: 3;
+ break;
+
+ default:
+ panic(FAULT);
+ }
+ break;
+
+ case 1: // read the prefix
+ case 3: // read the suffix
+ switch (type) {
+ case 0: // [aA_X]
+ case 2: // [.-d]
+ bchidx++; // append char to the buffer
+ break;
+
+ case 1: // [:]
+ bchidx++; // append char to the buffer
+ if (ns == true) {
+ if (bcolon != bqname) {
+ panic(FAULT); // it must be only one colon
+ }
+ bcolon = bchidx - 1;
+ if (st == 1) {
+ st = 2;
+ }
+ }
+ break;
+
+ default:
+ mChIdx--; // bkch();
+ bcopy(cstart, bstart);
+ mBuff[bqname] = (char) (bcolon - bqname);
+ return;
+ }
+ break;
+
+ default:
+ panic(FAULT);
+ }
+ }
+ }
+
+ /**
+ * Reads a nmtoken.
+ *
+ * This is low level routine which leaves a nmtoken in the buffer.
+ *
+ * @exception Exception is parser specific exception form panic method.
+ * @exception IOException
+ */
+ @SuppressWarnings("fallthrough")
+ private void bntok() throws Exception {
+ char ch;
+ mBuffIdx = -1;
+ bappend((char) 0); // default offset to the colon char
+ while (true) {
+ ch = getch();
+ switch (chtyp(ch)) {
+ case 'a':
+ case 'A':
+ case 'd':
+ case '.':
+ case ':':
+ case '-':
+ case '_':
+ case 'X':
+ bappend(ch);
+ break;
+
+ case 'Z':
+ panic(FAULT);
+
+ default:
+ bkch();
+ return;
+ }
+ }
+ }
+
+ /**
+ * Recognizes a keyword.
+ *
+ * This is low level routine which recognizes one of keywords in the buffer.
+ * Keyword Id ID - i IDREF - r IDREFS - R ENTITY - n ENTITIES - N NMTOKEN -
+ * t NMTOKENS - T ELEMENT - e ATTLIST - a NOTATION - o CDATA - c REQUIRED -
+ * Q IMPLIED - I FIXED - F
+ *
+ * @return an id of a keyword or '?'.
+ * @exception Exception is parser specific exception form panic method.
+ * @exception IOException
+ */
+ private char bkeyword()
+ throws Exception {
+ String str = new String(mBuff, 1, mBuffIdx);
+ switch (str.length()) {
+ case 2: // ID
+ return ("ID".equals(str) == true) ? 'i' : '?';
+
+ case 5: // IDREF, CDATA, FIXED
+ switch (mBuff[1]) {
+ case 'I':
+ return ("IDREF".equals(str) == true) ? 'r' : '?';
+ case 'C':
+ return ("CDATA".equals(str) == true) ? 'c' : '?';
+ case 'F':
+ return ("FIXED".equals(str) == true) ? 'F' : '?';
+ default:
+ break;
+ }
+ break;
+
+ case 6: // IDREFS, ENTITY
+ switch (mBuff[1]) {
+ case 'I':
+ return ("IDREFS".equals(str) == true) ? 'R' : '?';
+ case 'E':
+ return ("ENTITY".equals(str) == true) ? 'n' : '?';
+ default:
+ break;
+ }
+ break;
+
+ case 7: // NMTOKEN, IMPLIED, ATTLIST, ELEMENT
+ switch (mBuff[1]) {
+ case 'I':
+ return ("IMPLIED".equals(str) == true) ? 'I' : '?';
+ case 'N':
+ return ("NMTOKEN".equals(str) == true) ? 't' : '?';
+ case 'A':
+ return ("ATTLIST".equals(str) == true) ? 'a' : '?';
+ case 'E':
+ return ("ELEMENT".equals(str) == true) ? 'e' : '?';
+ default:
+ break;
+ }
+ break;
+
+ case 8: // ENTITIES, NMTOKENS, NOTATION, REQUIRED
+ switch (mBuff[2]) {
+ case 'N':
+ return ("ENTITIES".equals(str) == true) ? 'N' : '?';
+ case 'M':
+ return ("NMTOKENS".equals(str) == true) ? 'T' : '?';
+ case 'O':
+ return ("NOTATION".equals(str) == true) ? 'o' : '?';
+ case 'E':
+ return ("REQUIRED".equals(str) == true) ? 'Q' : '?';
+ default:
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+ return '?';
+ }
+
+ /**
+ * Reads a single or double quotted string in to the buffer.
+ *
+ * This method resolves entities inside a string unless the parser parses
+ * DTD.
+ *
+ * @param flag 'c' - CDATA, 'i' - non CDATA, ' ' - no normalization; '-' -
+ * not an attribute value; 'd' - in DTD context.
+ * @exception Exception is parser specific exception form panic method.
+ * @exception IOException
+ */
+ @SuppressWarnings("fallthrough")
+ private void bqstr(char flag) throws Exception {
+ Input inp = mInp; // remember the original input
+ mBuffIdx = -1;
+ bappend((char) 0); // default offset to the colon char
+ char ch;
+ for (short st = 0; st >= 0;) {
+ ch = (mChIdx < mChLen) ? mChars[mChIdx++] : getch();
+ switch (st) {
+ case 0: // read a single or double quote
+ switch (ch) {
+ case ' ':
+ case '\n':
+ case '\r':
+ case '\t':
+ break;
+
+ case '\'':
+ st = 2; // read a single quoted string
+ break;
+
+ case '\"':
+ st = 3; // read a double quoted string
+ break;
+
+ default:
+ panic(FAULT);
+ break;
+ }
+ break;
+
+ case 2: // read a single quoted string
+ case 3: // read a double quoted string
+ switch (ch) {
+ case '\'':
+ if ((st == 2) && (mInp == inp)) {
+ st = -1;
+ } else {
+ bappend(ch);
+ }
+ break;
+
+ case '\"':
+ if ((st == 3) && (mInp == inp)) {
+ st = -1;
+ } else {
+ bappend(ch);
+ }
+ break;
+
+ case '&':
+ if (flag != 'd') {
+ ent(flag);
+ } else {
+ bappend(ch);
+ }
+ break;
+
+ case '%':
+ if (flag == 'd') {
+ pent('-');
+ } else {
+ bappend(ch);
+ }
+ break;
+
+ case '<':
+ if ((flag == '-') || (flag == 'd')) {
+ bappend(ch);
+ } else {
+ panic(FAULT);
+ }
+ break;
+
+ case EOS: // EOS before single/double quote
+ panic(FAULT);
+
+ case '\r': // EOL processing [#2.11 & #3.3.3]
+ if (flag != ' ' && mInp.next == null) {
+ if (getch() != '\n') {
+ bkch();
+ }
+ ch = '\n';
+ }
+ default:
+ bappend(ch, flag);
+ break;
+ }
+ break;
+
+ default:
+ panic(FAULT);
+ }
+ }
+ // There is maximum one space at the end of the string in
+ // i-mode (non CDATA normalization) and it has to be removed.
+ if ((flag == 'i') && (mBuff[mBuffIdx] == ' ')) {
+ mBuffIdx -= 1;
+ }
+ }
+
+ /**
+ * Reports characters and empties the parser's buffer. This method is called
+ * only if parser is going to return control to the main loop. This means
+ * that this method may use parser buffer to report white space without
+ * copeing characters to temporary buffer.
+ */
+ protected abstract void bflash()
+ throws Exception;
+
+ /**
+ * Reports white space characters and empties the parser's buffer. This
+ * method is called only if parser is going to return control to the main
+ * loop. This means that this method may use parser buffer to report white
+ * space without copeing characters to temporary buffer.
+ */
+ protected abstract void bflash_ws()
+ throws Exception;
+
+ /**
+ * Appends a character to parser's buffer with normalization.
+ *
+ * @param ch The character to append to the buffer.
+ * @param mode The normalization mode.
+ */
+ private void bappend(char ch, char mode) {
+ // This implements attribute value normalization as
+ // described in the XML specification [#3.3.3].
+ switch (mode) {
+ case 'i': // non CDATA normalization
+ switch (ch) {
+ case ' ':
+ case '\n':
+ case '\r':
+ case '\t':
+ if ((mBuffIdx > 0) && (mBuff[mBuffIdx] != ' ')) {
+ bappend(' ');
+ }
+ return;
+
+ default:
+ break;
+ }
+ break;
+
+ case 'c': // CDATA normalization
+ switch (ch) {
+ case '\n':
+ case '\r':
+ case '\t':
+ ch = ' ';
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ default: // no normalization
+ break;
+ }
+ mBuffIdx++;
+ if (mBuffIdx < mBuff.length) {
+ mBuff[mBuffIdx] = ch;
+ } else {
+ mBuffIdx--;
+ bappend(ch);
+ }
+ }
+
+ /**
+ * Appends a character to parser's buffer.
+ *
+ * @param ch The character to append to the buffer.
+ */
+ private void bappend(char ch) {
+ try {
+ mBuff[++mBuffIdx] = ch;
+ } catch (Exception exp) {
+ // Double the buffer size
+ char buff[] = new char[mBuff.length << 1];
+ System.arraycopy(mBuff, 0, buff, 0, mBuff.length);
+ mBuff = buff;
+ mBuff[mBuffIdx] = ch;
+ }
+ }
+
+ /**
+ * Appends (mChIdx - cidx) characters from character buffer (mChars) to
+ * parser's buffer (mBuff).
+ *
+ * @param cidx The character buffer (mChars) start index.
+ * @param bidx The parser buffer (mBuff) start index.
+ */
+ private void bcopy(int cidx, int bidx) {
+ int length = mChIdx - cidx;
+ if ((bidx + length + 1) >= mBuff.length) {
+ // Expand the buffer
+ char buff[] = new char[mBuff.length + length];
+ System.arraycopy(mBuff, 0, buff, 0, mBuff.length);
+ mBuff = buff;
+ }
+ System.arraycopy(mChars, cidx, mBuff, bidx, length);
+ mBuffIdx += length;
+ }
+
+ /**
+ * Recognizes the built-in entities <i>lt</i>, <i>gt</i>, <i>amp</i>,
+ * <i>apos</i>, <i>quot</i>. The initial state is 0x100. Any state belowe
+ * 0x100 is a built-in entity replacement character.
+ *
+ * @param ch the next character of an entity name.
+ */
+ @SuppressWarnings("fallthrough")
+ private void eappend(char ch) {
+ switch (mESt) {
+ case 0x100: // "l" or "g" or "a" or "q"
+ switch (ch) {
+ case 'l':
+ mESt = 0x101;
+ break;
+ case 'g':
+ mESt = 0x102;
+ break;
+ case 'a':
+ mESt = 0x103;
+ break;
+ case 'q':
+ mESt = 0x107;
+ break;
+ default:
+ mESt = 0x200;
+ break;
+ }
+ break;
+
+ case 0x101: // "lt"
+ mESt = (ch == 't') ? '<' : (char) 0x200;
+ break;
+
+ case 0x102: // "gt"
+ mESt = (ch == 't') ? '>' : (char) 0x200;
+ break;
+
+ case 0x103: // "am" or "ap"
+ switch (ch) {
+ case 'm':
+ mESt = 0x104;
+ break;
+ case 'p':
+ mESt = 0x105;
+ break;
+ default:
+ mESt = 0x200;
+ break;
+ }
+ break;
+
+ case 0x104: // "amp"
+ mESt = (ch == 'p') ? '&' : (char) 0x200;
+ break;
+
+ case 0x105: // "apo"
+ mESt = (ch == 'o') ? (char) 0x106 : (char) 0x200;
+ break;
+
+ case 0x106: // "apos"
+ mESt = (ch == 's') ? '\'' : (char) 0x200;
+ break;
+
+ case 0x107: // "qu"
+ mESt = (ch == 'u') ? (char) 0x108 : (char) 0x200;
+ break;
+
+ case 0x108: // "quo"
+ mESt = (ch == 'o') ? (char) 0x109 : (char) 0x200;
+ break;
+
+ case 0x109: // "quot"
+ mESt = (ch == 't') ? '\"' : (char) 0x200;
+ break;
+
+ case '<': // "lt"
+ case '>': // "gt"
+ case '&': // "amp"
+ case '\'': // "apos"
+ case '\"': // "quot"
+ mESt = 0x200;
+ default:
+ break;
+ }
+ }
+
+ /**
+ * Sets up a new input source on the top of the input stack. Note, the first
+ * byte returned by the entity's byte stream has to be the first byte in the
+ * entity. However, the parser does not expect the byte order mask in both
+ * cases when encoding is provided by the input source.
+ *
+ * @param is A new input source to set up.
+ * @exception IOException If any IO errors occur.
+ * @exception Exception is parser specific exception form panic method.
+ */
+ protected void setinp(InputSource is)
+ throws Exception {
+ Reader reader = null;
+ mChIdx = 0;
+ mChLen = 0;
+ mChars = mInp.chars;
+ mInp.src = null;
+ if (mPh < PH_DOC_START) {
+ mIsSAlone = false; // default [#2.9]
+ }
+ mIsSAloneSet = false;
+ if (is.getCharacterStream() != null) {
+ // Ignore encoding in the xml text decl.
+ reader = is.getCharacterStream();
+ xml(reader);
+ } else if (is.getByteStream() != null) {
+ String expenc;
+ if (is.getEncoding() != null) {
+ // Ignore encoding in the xml text decl.
+ expenc = is.getEncoding().toUpperCase();
+ if (expenc.equals("UTF-16")) {
+ reader = bom(is.getByteStream(), 'U'); // UTF-16 [#4.3.3]
+ } else {
+ reader = enc(expenc, is.getByteStream());
+ }
+ xml(reader);
+ } else {
+ // Get encoding from BOM or the xml text decl.
+ reader = bom(is.getByteStream(), ' ');
+ if (reader == null) {
+ // Encoding is defined by the xml text decl.
+ reader = enc("UTF-8", is.getByteStream());
+ expenc = xml(reader);
+ if (expenc.startsWith("UTF-16")) {
+ panic(FAULT); // UTF-16 must have BOM [#4.3.3]
+ }
+ reader = enc(expenc, is.getByteStream());
+ } else {
+ // Encoding is defined by the BOM.
+ xml(reader);
+ }
+ }
+ } else {
+ // There is no support for public/system identifiers.
+ panic(FAULT);
+ }
+ mInp.src = reader;
+ mInp.pubid = is.getPublicId();
+ mInp.sysid = is.getSystemId();
+ }
+
+ /**
+ * Determines the entity encoding.
+ *
+ * This method gets encoding from Byte Order Mask [#4.3.3] if any. Note, the
+ * first byte returned by the entity's byte stream has to be the first byte
+ * in the entity. Also, there is no support for UCS-4.
+ *
+ * @param is A byte stream of the entity.
+ * @param hint An encoding hint, character U means UTF-16.
+ * @return a reader constructed from the BOM or UTF-8 by default.
+ * @exception Exception is parser specific exception form panic method.
+ * @exception IOException
+ */
+ private Reader bom(InputStream is, char hint)
+ throws Exception {
+ int val = is.read();
+ switch (val) {
+ case 0xef: // UTF-8
+ if (hint == 'U') // must be UTF-16
+ {
+ panic(FAULT);
+ }
+ if (is.read() != 0xbb) {
+ panic(FAULT);
+ }
+ if (is.read() != 0xbf) {
+ panic(FAULT);
+ }
+ return new ReaderUTF8(is);
+
+ case 0xfe: // UTF-16, big-endian
+ if (is.read() != 0xff) {
+ panic(FAULT);
+ }
+ return new ReaderUTF16(is, 'b');
+
+ case 0xff: // UTF-16, little-endian
+ if (is.read() != 0xfe) {
+ panic(FAULT);
+ }
+ return new ReaderUTF16(is, 'l');
+
+ case -1:
+ mChars[mChIdx++] = EOS;
+ return new ReaderUTF8(is);
+
+ default:
+ if (hint == 'U') // must be UTF-16
+ {
+ panic(FAULT);
+ }
+ // Read the rest of UTF-8 character
+ switch (val & 0xf0) {
+ case 0xc0:
+ case 0xd0:
+ mChars[mChIdx++] = (char) (((val & 0x1f) << 6) | (is.read() & 0x3f));
+ break;
+
+ case 0xe0:
+ mChars[mChIdx++] = (char) (((val & 0x0f) << 12)
+ | ((is.read() & 0x3f) << 6) | (is.read() & 0x3f));
+ break;
+
+ case 0xf0: // UCS-4 character
+ throw new UnsupportedEncodingException();
+
+ default:
+ mChars[mChIdx++] = (char) val;
+ break;
+ }
+ return null;
+ }
+ }
+
+ /**
+ * Parses the xml text declaration.
+ *
+ * This method gets encoding from the xml text declaration [#4.3.1] if any.
+ * The method assumes the buffer (mChars) is big enough to accomodate whole
+ * xml text declaration.
+ *
+ * @param reader is entity reader.
+ * @return The xml text declaration encoding or default UTF-8 encoding.
+ * @exception Exception is parser specific exception form panic method.
+ * @exception IOException
+ */
+ private String xml(Reader reader)
+ throws Exception {
+ String str = null;
+ String enc = "UTF-8";
+ char ch;
+ int val;
+ short st;
+ // Read the xml text declaration into the buffer
+ if (mChIdx != 0) {
+ // The bom method have read ONE char into the buffer.
+ st = (short) ((mChars[0] == '<') ? 1 : -1);
+ } else {
+ st = 0;
+ }
+ while (st >= 0 && mChIdx < mChars.length) {
+ ch = ((val = reader.read()) >= 0) ? (char) val : EOS;
+ mChars[mChIdx++] = ch;
+ switch (st) {
+ case 0: // read '<' of xml declaration
+ switch (ch) {
+ case '<':
+ st = 1;
+ break;
+
+ case 0xfeff: // the byte order mask
+ ch = ((val = reader.read()) >= 0) ? (char) val : EOS;
+ mChars[mChIdx - 1] = ch;
+ st = (short) ((ch == '<') ? 1 : -1);
+ break;
+
+ default:
+ st = -1;
+ break;
+ }
+ break;
+
+ case 1: // read '?' of xml declaration [#4.3.1]
+ st = (short) ((ch == '?') ? 2 : -1);
+ break;
+
+ case 2: // read 'x' of xml declaration [#4.3.1]
+ st = (short) ((ch == 'x') ? 3 : -1);
+ break;
+
+ case 3: // read 'm' of xml declaration [#4.3.1]
+ st = (short) ((ch == 'm') ? 4 : -1);
+ break;
+
+ case 4: // read 'l' of xml declaration [#4.3.1]
+ st = (short) ((ch == 'l') ? 5 : -1);
+ break;
+
+ case 5: // read white space after 'xml'
+ switch (ch) {
+ case ' ':
+ case '\t':
+ case '\r':
+ case '\n':
+ st = 6;
+ break;
+
+ default:
+ st = -1;
+ break;
+ }
+ break;
+
+ case 6: // read content of xml declaration
+ switch (ch) {
+ case '?':
+ st = 7;
+ break;
+
+ case EOS:
+ st = -2;
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ case 7: // read '>' after '?' of xml declaration
+ switch (ch) {
+ case '>':
+ case EOS:
+ st = -2;
+ break;
+
+ default:
+ st = 6;
+ break;
+ }
+ break;
+
+ default:
+ panic(FAULT);
+ break;
+ }
+ }
+ mChLen = mChIdx;
+ mChIdx = 0;
+ // If there is no xml text declaration, the encoding is default.
+ if (st == -1) {
+ return enc;
+ }
+ mChIdx = 5; // the first white space after "<?xml"
+ // Parse the xml text declaration
+ for (st = 0; st >= 0;) {
+ ch = getch();
+ switch (st) {
+ case 0: // skip spaces after the xml declaration name
+ if (chtyp(ch) != ' ') {
+ bkch();
+ st = 1;
+ }
+ break;
+
+ case 1: // read xml declaration version
+ case 2: // read xml declaration encoding or standalone
+ case 3: // read xml declaration standalone
+ switch (chtyp(ch)) {
+ case 'a':
+ case 'A':
+ case '_':
+ bkch();
+ str = name(false).toLowerCase();
+ if ("version".equals(str) == true) {
+ if (st != 1) {
+ panic(FAULT);
+ }
+ if ("1.0".equals(eqstr('=')) != true) {
+ panic(FAULT);
+ }
+ mInp.xmlver = 0x0100;
+ st = 2;
+ } else if ("encoding".equals(str) == true) {
+ if (st != 2) {
+ panic(FAULT);
+ }
+ mInp.xmlenc = eqstr('=').toUpperCase();
+ enc = mInp.xmlenc;
+ st = 3;
+ } else if ("standalone".equals(str) == true) {
+ if ((st == 1) || (mPh >= PH_DOC_START)) // [#4.3.1]
+ {
+ panic(FAULT);
+ }
+ str = eqstr('=').toLowerCase();
+ // Check the 'standalone' value and use it [#5.1]
+ if (str.equals("yes") == true) {
+ mIsSAlone = true;
+ } else if (str.equals("no") == true) {
+ mIsSAlone = false;
+ } else {
+ panic(FAULT);
+ }
+ mIsSAloneSet = true;
+ st = 4;
+ } else {
+ panic(FAULT);
+ }
+ break;
+
+ case ' ':
+ break;
+
+ case '?':
+ if (st == 1) {
+ panic(FAULT);
+ }
+ bkch();
+ st = 4;
+ break;
+
+ default:
+ panic(FAULT);
+ }
+ break;
+
+ case 4: // end of xml declaration
+ switch (chtyp(ch)) {
+ case '?':
+ if (getch() != '>') {
+ panic(FAULT);
+ }
+ if (mPh <= PH_DOC_START) {
+ mPh = PH_MISC_DTD; // misc before DTD
+ }
+ st = -1;
+ break;
+
+ case ' ':
+ break;
+
+ default:
+ panic(FAULT);
+ }
+ break;
+
+ default:
+ panic(FAULT);
+ }
+ }
+ return enc;
+ }
+
+ /**
+ * Sets up the document reader.
+ *
+ * @param name an encoding name.
+ * @param is the document byte input stream.
+ * @return a reader constructed from encoding name and input stream.
+ * @exception UnsupportedEncodingException
+ */
+ private Reader enc(String name, InputStream is)
+ throws UnsupportedEncodingException {
+ // DO NOT CLOSE current reader if any!
+ if (name.equals("UTF-8")) {
+ return new ReaderUTF8(is);
+ } else if (name.equals("UTF-16LE")) {
+ return new ReaderUTF16(is, 'l');
+ } else if (name.equals("UTF-16BE")) {
+ return new ReaderUTF16(is, 'b');
+ } else {
+ return new InputStreamReader(is, name);
+ }
+ }
+
+ /**
+ * Sets up current input on the top of the input stack.
+ *
+ * @param inp A new input to set up.
+ */
+ protected void push(Input inp) {
+ mInp.chLen = mChLen;
+ mInp.chIdx = mChIdx;
+ inp.next = mInp;
+ mInp = inp;
+ mChars = inp.chars;
+ mChLen = inp.chLen;
+ mChIdx = inp.chIdx;
+ }
+
+ /**
+ * Restores previous input on the top of the input stack.
+ */
+ protected void pop() {
+ if (mInp.src != null) {
+ try {
+ mInp.src.close();
+ } catch (IOException ioe) {
+ }
+ mInp.src = null;
+ }
+ mInp = mInp.next;
+ if (mInp != null) {
+ mChars = mInp.chars;
+ mChLen = mInp.chLen;
+ mChIdx = mInp.chIdx;
+ } else {
+ mChars = null;
+ mChLen = 0;
+ mChIdx = 0;
+ }
+ }
+
+ /**
+ * Maps a character to it's type.
+ *
+ * Possible character type values are:<br /> - ' ' for any kind of white
+ * space character;<br /> - 'a' for any lower case alphabetical character
+ * value;<br /> - 'A' for any upper case alphabetical character value;<br />
+ * - 'd' for any decimal digit character value;<br /> - 'z' for any
+ * character less then ' ' except '\t', '\n', '\r';<br /> - 'X' for any not
+ * ASCII character;<br /> - 'Z' for EOS character.<br /> An ASCII (7 bit)
+ * character which does not fall in any category listed above is mapped to
+ * it self.
+ *
+ * @param ch The character to map.
+ * @return The type of character.
+ */
+ protected char chtyp(char ch) {
+ if (ch < 0x80) {
+ return (char) asctyp[ch];
+ }
+ return (ch != EOS) ? 'X' : 'Z';
+ }
+
+ /**
+ * Retrives the next character in the document.
+ *
+ * @return The next character in the document.
+ */
+ protected char getch()
+ throws IOException {
+ if (mChIdx >= mChLen) {
+ if (mInp.src == null) {
+ pop(); // remove internal entity
+ return getch();
+ }
+ // Read new portion of the document characters
+ int Num = mInp.src.read(mChars, 0, mChars.length);
+ if (Num < 0) {
+ if (mInp != mDoc) {
+ pop(); // restore the previous input
+ return getch();
+ } else {
+ mChars[0] = EOS;
+ mChLen = 1;
+ }
+ } else {
+ mChLen = Num;
+ }
+ mChIdx = 0;
+ }
+ return mChars[mChIdx++];
+ }
+
+ /**
+ * Puts back the last read character.
+ *
+ * This method <strong>MUST NOT</strong> be called more then once after each
+ * call of {@link #getch getch} method.
+ */
+ protected void bkch()
+ throws Exception {
+ if (mChIdx <= 0) {
+ panic(FAULT);
+ }
+ mChIdx--;
+ }
+
+ /**
+ * Sets the current character.
+ *
+ * @param ch The character to set.
+ */
+ protected void setch(char ch) {
+ mChars[mChIdx] = ch;
+ }
+
+ /**
+ * Finds a pair in the pair chain by a qualified name.
+ *
+ * @param chain The first element of the chain of pairs.
+ * @param qname The qualified name.
+ * @return A pair with the specified qualified name or null.
+ */
+ protected Pair find(Pair chain, char[] qname) {
+ for (Pair pair = chain; pair != null; pair = pair.next) {
+ if (pair.eqname(qname) == true) {
+ return pair;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Provedes an instance of a pair.
+ *
+ * @param next The reference to a next pair.
+ * @return An instance of a pair.
+ */
+ protected Pair pair(Pair next) {
+ Pair pair;
+
+ if (mDltd != null) {
+ pair = mDltd;
+ mDltd = pair.next;
+ } else {
+ pair = new Pair();
+ }
+ pair.next = next;
+
+ return pair;
+ }
+
+ /**
+ * Deletes an instance of a pair.
+ *
+ * @param pair The pair to delete.
+ * @return A reference to the next pair in a chain.
+ */
+ protected Pair del(Pair pair) {
+ Pair next = pair.next;
+
+ pair.name = null;
+ pair.value = null;
+ pair.chars = null;
+ pair.list = null;
+ pair.next = mDltd;
+ mDltd = pair;
+
+ return next;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/jdk/internal/util/xml/impl/ParserSAX.java Wed Dec 19 12:09:10 2012 +0000
@@ -0,0 +1,695 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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 General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.util.xml.impl;
+
+import java.io.IOException;
+import java.io.InputStream;
+import jdk.internal.org.xml.sax.ContentHandler;
+import jdk.internal.org.xml.sax.DTDHandler;
+import jdk.internal.org.xml.sax.EntityResolver;
+import jdk.internal.org.xml.sax.ErrorHandler;
+import jdk.internal.org.xml.sax.InputSource;
+import jdk.internal.org.xml.sax.Locator;
+import jdk.internal.org.xml.sax.SAXException;
+import jdk.internal.org.xml.sax.SAXParseException;
+import jdk.internal.org.xml.sax.XMLReader;
+import jdk.internal.org.xml.sax.helpers.DefaultHandler;
+
+/**
+ * XML non-validating push parser.
+ *
+ * This non-validating parser conforms to <a href="http://www.w3.org/TR/REC-xml"
+ * >Extensible Markup Language (XML) 1.0</a> and <a
+ * href="http://www.w3.org/TR/REC-xml-names" >"Namespaces in XML"</a>
+ * specifications. The API supported by the parser are <a
+ * href="http://java.sun.com/aboutJava/communityprocess/final/jsr030/index.html">CLDC
+ * 1.0</a> and <a href="http://www.jcp.org/en/jsr/detail?id=280">JSR-280</a>, a
+ * JavaME subset of <a href="http://java.sun.com/xml/jaxp/index.html">JAXP</a>
+ * and <a href="http://www.saxproject.org/">SAX2</a>.
+ *
+ * @see org.xml.sax.XMLReader
+ */
+
+final class ParserSAX
+ extends Parser implements XMLReader, Locator
+{
+ public final static String FEATURE_NS =
+ "http://xml.org/sax/features/namespaces";
+ public final static String FEATURE_PREF =
+ "http://xml.org/sax/features/namespace-prefixes";
+ // SAX feature flags
+ private boolean mFNamespaces;
+ private boolean mFPrefixes;
+ // SAX handlers
+ private DefaultHandler mHand; // the default handler
+ private ContentHandler mHandCont; // the content handler
+ private DTDHandler mHandDtd; // the DTD handler
+ private ErrorHandler mHandErr; // the error handler
+ private EntityResolver mHandEnt; // the entity resolver
+
+ /**
+ * Constructor.
+ */
+ public ParserSAX() {
+ super();
+
+ // SAX feature defaut values
+ mFNamespaces = true;
+ mFPrefixes = false;
+
+ // Default handler which will be used in case the application
+ // do not set one of handlers.
+ mHand = new DefaultHandler();
+ mHandCont = mHand;
+ mHandDtd = mHand;
+ mHandErr = mHand;
+ mHandEnt = mHand;
+ }
+
+ /**
+ * Return the current content handler.
+ *
+ * @return The current content handler, or null if none has been registered.
+ * @see #setContentHandler
+ */
+ public ContentHandler getContentHandler() {
+ return (mHandCont != mHand) ? mHandCont : null;
+ }
+
+ /**
+ * Allow an application to register a content event handler.
+ *
+ * <p>If the application does not register a content handler, all content
+ * events reported by the SAX parser will be silently ignored.</p>
+ *
+ * <p>Applications may register a new or different handler in the middle of
+ * a parse, and the SAX parser must begin using the new handler
+ * immediately.</p>
+ *
+ * @param handler The content handler.
+ * @exception java.lang.NullPointerException If the handler argument is
+ * null.
+ * @see #getContentHandler
+ */
+ public void setContentHandler(ContentHandler handler) {
+ if (handler == null) {
+ throw new NullPointerException();
+ }
+ mHandCont = handler;
+ }
+
+ /**
+ * Return the current DTD handler.
+ *
+ * @return The current DTD handler, or null if none has been registered.
+ * @see #setDTDHandler
+ */
+ public DTDHandler getDTDHandler() {
+ return (mHandDtd != mHand) ? mHandDtd : null;
+ }
+
+ /**
+ * Allow an application to register a DTD event handler.
+ *
+ * <p>If the application does not register a DTD handler, all DTD events
+ * reported by the SAX parser will be silently ignored.</p>
+ *
+ * <p>Applications may register a new or different handler in the middle of
+ * a parse, and the SAX parser must begin using the new handler
+ * immediately.</p>
+ *
+ * @param handler The DTD handler.
+ * @exception java.lang.NullPointerException If the handler argument is
+ * null.
+ * @see #getDTDHandler
+ */
+ public void setDTDHandler(DTDHandler handler) {
+ if (handler == null) {
+ throw new NullPointerException();
+ }
+ mHandDtd = handler;
+ }
+
+ /**
+ * Return the current error handler.
+ *
+ * @return The current error handler, or null if none has been registered.
+ * @see #setErrorHandler
+ */
+ public ErrorHandler getErrorHandler() {
+ return (mHandErr != mHand) ? mHandErr : null;
+ }
+
+ /**
+ * Allow an application to register an error event handler.
+ *
+ * <p>If the application does not register an error handler, all error
+ * events reported by the SAX parser will be silently ignored; however,
+ * normal processing may not continue. It is highly recommended that all SAX
+ * applications implement an error handler to avoid unexpected bugs.</p>
+ *
+ * <p>Applications may register a new or different handler in the middle of
+ * a parse, and the SAX parser must begin using the new handler
+ * immediately.</p>
+ *
+ * @param handler The error handler.
+ * @exception java.lang.NullPointerException If the handler argument is
+ * null.
+ * @see #getErrorHandler
+ */
+ public void setErrorHandler(ErrorHandler handler) {
+ if (handler == null) {
+ throw new NullPointerException();
+ }
+ mHandErr = handler;
+ }
+
+ /**
+ * Return the current entity resolver.
+ *
+ * @return The current entity resolver, or null if none has been registered.
+ * @see #setEntityResolver
+ */
+ public EntityResolver getEntityResolver() {
+ return (mHandEnt != mHand) ? mHandEnt : null;
+ }
+
+ /**
+ * Allow an application to register an entity resolver.
+ *
+ * <p>If the application does not register an entity resolver, the XMLReader
+ * will perform its own default resolution.</p>
+ *
+ * <p>Applications may register a new or different resolver in the middle of
+ * a parse, and the SAX parser must begin using the new resolver
+ * immediately.</p>
+ *
+ * @param resolver The entity resolver.
+ * @exception java.lang.NullPointerException If the resolver argument is
+ * null.
+ * @see #getEntityResolver
+ */
+ public void setEntityResolver(EntityResolver resolver) {
+ if (resolver == null) {
+ throw new NullPointerException();
+ }
+ mHandEnt = resolver;
+ }
+
+ /**
+ * Return the public identifier for the current document event.
+ *
+ * <p>The return value is the public identifier of the document entity or of
+ * the external parsed entity in which the markup triggering the event
+ * appears.</p>
+ *
+ * @return A string containing the public identifier, or null if none is
+ * available.
+ *
+ * @see #getSystemId
+ */
+ public String getPublicId() {
+ return (mInp != null) ? mInp.pubid : null;
+ }
+
+ /**
+ * Return the system identifier for the current document event.
+ *
+ * <p>The return value is the system identifier of the document entity or of
+ * the external parsed entity in which the markup triggering the event
+ * appears.</p>
+ *
+ * <p>If the system identifier is a URL, the parser must resolve it fully
+ * before passing it to the application.</p>
+ *
+ * @return A string containing the system identifier, or null if none is
+ * available.
+ *
+ * @see #getPublicId
+ */
+ public String getSystemId() {
+ return (mInp != null) ? mInp.sysid : null;
+ }
+
+ /**
+ * Return the line number where the current document event ends.
+ *
+ * @return Always returns -1 indicating the line number is not available.
+ *
+ * @see #getColumnNumber
+ */
+ public int getLineNumber() {
+ return -1;
+ }
+
+ /**
+ * Return the column number where the current document event ends.
+ *
+ * @return Always returns -1 indicating the column number is not available.
+ *
+ * @see #getLineNumber
+ */
+ public int getColumnNumber() {
+ return -1;
+ }
+
+ /**
+ * Parse an XML document from a system identifier (URI).
+ *
+ * <p>This method is a shortcut for the common case of reading a document
+ * from a system identifier. It is the exact equivalent of the
+ * following:</p>
+ *
+ * <pre>
+ * parse(new InputSource(systemId));
+ * </pre>
+ *
+ * <p>If the system identifier is a URL, it must be fully resolved by the
+ * application before it is passed to the parser.</p>
+ *
+ * @param systemId The system identifier (URI).
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly wrapping
+ * another exception.
+ * @exception java.io.IOException An IO exception from the parser, possibly
+ * from a byte stream or character stream supplied by the application.
+ * @see #parse(org.xml.sax.InputSource)
+ */
+ public void parse(String systemId) throws IOException, SAXException {
+ parse(new InputSource(systemId));
+ }
+
+ /**
+ * Parse an XML document.
+ *
+ * <p>The application can use this method to instruct the XML reader to
+ * begin parsing an XML document from any valid input source (a character
+ * stream, a byte stream, or a URI).</p>
+ *
+ * <p>Applications may not invoke this method while a parse is in progress
+ * (they should create a new XMLReader instead for each nested XML
+ * document). Once a parse is complete, an application may reuse the same
+ * XMLReader object, possibly with a different input source.</p>
+ *
+ * <p>During the parse, the XMLReader will provide information about the XML
+ * document through the registered event handlers.</p>
+ *
+ * <p>This method is synchronous: it will not return until parsing has
+ * ended. If a client application wants to terminate parsing early, it
+ * should throw an exception.</p>
+ *
+ * @param is The input source for the top-level of the XML document.
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly wrapping
+ * another exception.
+ * @exception java.io.IOException An IO exception from the parser, possibly
+ * from a byte stream or character stream supplied by the application.
+ * @see org.xml.sax.InputSource
+ * @see #parse(java.lang.String)
+ * @see #setEntityResolver
+ * @see #setDTDHandler
+ * @see #setContentHandler
+ * @see #setErrorHandler
+ */
+ public void parse(InputSource is) throws IOException, SAXException {
+ if (is == null) {
+ throw new IllegalArgumentException("");
+ }
+ // Set up the document
+ mInp = new Input(BUFFSIZE_READER);
+ mPh = PH_BEFORE_DOC; // before parsing
+ try {
+ setinp(is);
+ } catch (SAXException saxe) {
+ throw saxe;
+ } catch (IOException ioe) {
+ throw ioe;
+ } catch (RuntimeException rte) {
+ throw rte;
+ } catch (Exception e) {
+ panic(e.toString());
+ }
+ parse();
+ }
+
+ /**
+ * Parse the content of the given {@link java.io.InputStream} instance as
+ * XML using the specified {@link org.xml.sax.helpers.DefaultHandler}.
+ *
+ * @param src InputStream containing the content to be parsed.
+ * @param handler The SAX DefaultHandler to use.
+ * @exception IOException If any IO errors occur.
+ * @exception IllegalArgumentException If the given InputStream or handler
+ * is null.
+ * @exception SAXException If the underlying parser throws a SAXException
+ * while parsing.
+ * @see org.xml.sax.helpers.DefaultHandler
+ */
+ public void parse(InputStream src, DefaultHandler handler)
+ throws SAXException, IOException {
+ if ((src == null) || (handler == null)) {
+ throw new IllegalArgumentException("");
+ }
+ parse(new InputSource(src), handler);
+ }
+
+ /**
+ * Parse the content given {@link org.xml.sax.InputSource} as XML using the
+ * specified {@link org.xml.sax.helpers.DefaultHandler}.
+ *
+ * @param is The InputSource containing the content to be parsed.
+ * @param handler The SAX DefaultHandler to use.
+ * @exception IOException If any IO errors occur.
+ * @exception IllegalArgumentException If the InputSource or handler is
+ * null.
+ * @exception SAXException If the underlying parser throws a SAXException
+ * while parsing.
+ * @see org.xml.sax.helpers.DefaultHandler
+ */
+ public void parse(InputSource is, DefaultHandler handler)
+ throws SAXException, IOException
+ {
+ if ((is == null) || (handler == null)) {
+ throw new IllegalArgumentException("");
+ }
+ // Set up the handler
+ mHandCont = handler;
+ mHandDtd = handler;
+ mHandErr = handler;
+ mHandEnt = handler;
+ // Set up the document
+ mInp = new Input(BUFFSIZE_READER);
+ mPh = PH_BEFORE_DOC; // before parsing
+ try {
+ setinp(is);
+ } catch (SAXException | IOException | RuntimeException saxe) {
+ throw saxe;
+ } catch (Exception e) {
+ panic(e.toString());
+ }
+ parse();
+ }
+
+ /**
+ * Parse the XML document content using specified handlers and an input
+ * source.
+ *
+ * @exception IOException If any IO errors occur.
+ * @exception SAXException If the underlying parser throws a SAXException
+ * while parsing.
+ */
+ @SuppressWarnings("fallthrough")
+ private void parse() throws SAXException, IOException {
+ init();
+ try {
+ mHandCont.setDocumentLocator(this);
+ mHandCont.startDocument();
+
+ if (mPh != PH_MISC_DTD) {
+ mPh = PH_MISC_DTD; // misc before DTD
+ }
+ int evt = EV_NULL;
+ // XML document prolog
+ do {
+ wsskip();
+ switch (evt = step()) {
+ case EV_ELM:
+ case EV_ELMS:
+ mPh = PH_DOCELM;
+ break;
+
+ case EV_COMM:
+ case EV_PI:
+ break;
+
+ case EV_DTD:
+ if (mPh >= PH_DTD_MISC) {
+ panic(FAULT);
+ }
+ mPh = PH_DTD_MISC; // misc after DTD
+ break;
+
+ default:
+ panic(FAULT);
+ }
+ } while (mPh < PH_DOCELM); // misc before DTD
+ // XML document starting with document's element
+ do {
+ switch (evt) {
+ case EV_ELM:
+ case EV_ELMS:
+ // Report the element
+ if (mIsNSAware == true) {
+ mHandCont.startElement(
+ mElm.value,
+ mElm.name,
+ "",
+ mAttrs);
+ } else {
+ mHandCont.startElement(
+ "",
+ "",
+ mElm.name,
+ mAttrs);
+ }
+ if (evt == EV_ELMS) {
+ evt = step();
+ break;
+ }
+
+ case EV_ELME:
+ // Report the end of element
+ if (mIsNSAware == true) {
+ mHandCont.endElement(mElm.value, mElm.name, "");
+ } else {
+ mHandCont.endElement("", "", mElm.name);
+ }
+ // Restore the top of the prefix stack
+ while (mPref.list == mElm) {
+ mHandCont.endPrefixMapping(mPref.name);
+ mPref = del(mPref);
+ }
+ // Remove the top element tag
+ mElm = del(mElm);
+ if (mElm == null) {
+ mPh = PH_DOCELM_MISC;
+ } else {
+ evt = step();
+ }
+ break;
+
+ case EV_TEXT:
+ case EV_WSPC:
+ case EV_CDAT:
+ case EV_COMM:
+ case EV_PI:
+ case EV_ENT:
+ evt = step();
+ break;
+
+ default:
+ panic(FAULT);
+ }
+ } while (mPh == PH_DOCELM);
+ // Misc after document's element
+ do {
+ if (wsskip() == EOS) {
+ break;
+ }
+
+ switch (step()) {
+ case EV_COMM:
+ case EV_PI:
+ break;
+
+ default:
+ panic(FAULT);
+ }
+ } while (mPh == PH_DOCELM_MISC);
+ mPh = PH_AFTER_DOC; // parsing is completed
+
+ } catch (SAXException saxe) {
+ throw saxe;
+ } catch (IOException ioe) {
+ throw ioe;
+ } catch (RuntimeException rte) {
+ throw rte;
+ } catch (Exception e) {
+ panic(e.toString());
+ } finally {
+ mHandCont.endDocument();
+ cleanup();
+ }
+ }
+
+ /**
+ * Reports document type.
+ *
+ * @param name The name of the entity.
+ * @param pubid The public identifier of the entity or <code>null</code>.
+ * @param sysid The system identifier of the entity or <code>null</code>.
+ */
+ protected void docType(String name, String pubid, String sysid) throws SAXException {
+ mHandDtd.notationDecl(name, pubid, sysid);
+ }
+
+ /**
+ * Reports a comment.
+ *
+ * @param text The comment text starting from first charcater.
+ * @param length The number of characters in comment.
+ */
+ protected void comm(char[] text, int length) {
+ }
+
+ /**
+ * Reports a processing instruction.
+ *
+ * @param target The processing instruction target name.
+ * @param body The processing instruction body text.
+ */
+ protected void pi(String target, String body) throws SAXException {
+ mHandCont.processingInstruction(target, body);
+ }
+
+ /**
+ * Reports new namespace prefix. The Namespace prefix (
+ * <code>mPref.name</code>) being declared and the Namespace URI (
+ * <code>mPref.value</code>) the prefix is mapped to. An empty string is
+ * used for the default element namespace, which has no prefix.
+ */
+ protected void newPrefix() throws SAXException {
+ mHandCont.startPrefixMapping(mPref.name, mPref.value);
+ }
+
+ /**
+ * Reports skipped entity name.
+ *
+ * @param name The entity name.
+ */
+ protected void skippedEnt(String name) throws SAXException {
+ mHandCont.skippedEntity(name);
+ }
+
+ /**
+ * Returns an
+ * <code>InputSource</code> for specified entity or
+ * <code>null</code>.
+ *
+ * @param name The name of the entity.
+ * @param pubid The public identifier of the entity.
+ * @param sysid The system identifier of the entity.
+ */
+ protected InputSource resolveEnt(String name, String pubid, String sysid)
+ throws SAXException, IOException
+ {
+ return mHandEnt.resolveEntity(pubid, sysid);
+ }
+
+ /**
+ * Reports notation declaration.
+ *
+ * @param name The notation's name.
+ * @param pubid The notation's public identifier, or null if none was given.
+ * @param sysid The notation's system identifier, or null if none was given.
+ */
+ protected void notDecl(String name, String pubid, String sysid)
+ throws SAXException
+ {
+ mHandDtd.notationDecl(name, pubid, sysid);
+ }
+
+ /**
+ * Reports unparsed entity name.
+ *
+ * @param name The unparsed entity's name.
+ * @param pubid The entity's public identifier, or null if none was given.
+ * @param sysid The entity's system identifier.
+ * @param notation The name of the associated notation.
+ */
+ protected void unparsedEntDecl(String name, String pubid, String sysid, String notation)
+ throws SAXException
+ {
+ mHandDtd.unparsedEntityDecl(name, pubid, sysid, notation);
+ }
+
+ /**
+ * Notifies the handler about fatal parsing error.
+ *
+ * @param msg The problem description message.
+ */
+ protected void panic(String msg) throws SAXException {
+ SAXParseException spe = new SAXParseException(msg, this);
+ mHandErr.fatalError(spe);
+ throw spe; // [#1.2] fatal error definition
+ }
+
+ /**
+ * Reports characters and empties the parser's buffer. This method is called
+ * only if parser is going to return control to the main loop. This means
+ * that this method may use parser buffer to report white space without
+ * copeing characters to temporary buffer.
+ */
+ protected void bflash() throws SAXException {
+ if (mBuffIdx >= 0) {
+ // Textual data has been read
+ mHandCont.characters(mBuff, 0, (mBuffIdx + 1));
+ mBuffIdx = -1;
+ }
+ }
+
+ /**
+ * Reports white space characters and empties the parser's buffer. This
+ * method is called only if parser is going to return control to the main
+ * loop. This means that this method may use parser buffer to report white
+ * space without copeing characters to temporary buffer.
+ */
+ protected void bflash_ws() throws SAXException {
+ if (mBuffIdx >= 0) {
+ // BUG: With additional info from DTD and xml:space attr [#2.10]
+ // the following call can be supported:
+ // mHandCont.ignorableWhitespace(mBuff, 0, (mBuffIdx + 1));
+
+ // Textual data has been read
+ mHandCont.characters(mBuff, 0, (mBuffIdx + 1));
+ mBuffIdx = -1;
+ }
+ }
+
+ public boolean getFeature(String name) {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ public void setFeature(String name, boolean value) {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ public Object getProperty(String name) {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ public void setProperty(String name, Object value) {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/jdk/internal/util/xml/impl/ReaderUTF16.java Wed Dec 19 12:09:10 2012 +0000
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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 General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.util.xml.impl;
+
+import java.io.Reader;
+import java.io.InputStream;
+import java.io.IOException;
+
+/**
+ * UTF-16 encoded stream reader.
+ */
+public class ReaderUTF16 extends Reader {
+
+ private InputStream is;
+ private char bo;
+
+ /**
+ * Constructor.
+ *
+ * Byte order argument can be: 'l' for little-endian or 'b' for big-endian.
+ *
+ * @param is A byte input stream.
+ * @param bo A byte order in the input stream.
+ */
+ public ReaderUTF16(InputStream is, char bo) {
+ switch (bo) {
+ case 'l':
+ break;
+
+ case 'b':
+ break;
+
+ default:
+ throw new IllegalArgumentException("");
+ }
+ this.bo = bo;
+ this.is = is;
+ }
+
+ /**
+ * Reads characters into a portion of an array.
+ *
+ * @param cbuf Destination buffer.
+ * @param off Offset at which to start storing characters.
+ * @param len Maximum number of characters to read.
+ * @exception IOException If any IO errors occur.
+ */
+ public int read(char[] cbuf, int off, int len) throws IOException {
+ int num = 0;
+ int val;
+ if (bo == 'b') {
+ while (num < len) {
+ if ((val = is.read()) < 0) {
+ return (num != 0) ? num : -1;
+ }
+ cbuf[off++] = (char) ((val << 8) | (is.read() & 0xff));
+ num++;
+ }
+ } else {
+ while (num < len) {
+ if ((val = is.read()) < 0) {
+ return (num != 0) ? num : -1;
+ }
+ cbuf[off++] = (char) ((is.read() << 8) | (val & 0xff));
+ num++;
+ }
+ }
+ return num;
+ }
+
+ /**
+ * Reads a single character.
+ *
+ * @return The character read, as an integer in the range 0 to 65535
+ * (0x0000-0xffff), or -1 if the end of the stream has been reached.
+ * @exception IOException If any IO errors occur.
+ */
+ public int read() throws IOException {
+ int val;
+ if ((val = is.read()) < 0) {
+ return -1;
+ }
+ if (bo == 'b') {
+ val = (char) ((val << 8) | (is.read() & 0xff));
+ } else {
+ val = (char) ((is.read() << 8) | (val & 0xff));
+ }
+ return val;
+ }
+
+ /**
+ * Closes the stream.
+ *
+ * @exception IOException If any IO errors occur.
+ */
+ public void close() throws IOException {
+ is.close();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/jdk/internal/util/xml/impl/ReaderUTF8.java Wed Dec 19 12:09:10 2012 +0000
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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 General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.util.xml.impl;
+
+import java.io.Reader;
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+
+/**
+ * UTF-8 transformed UCS-2 character stream reader.
+ *
+ * This reader converts UTF-8 transformed UCS-2 characters to Java characters.
+ * The UCS-2 subset of UTF-8 transformation is described in RFC-2279 #2
+ * "UTF-8 definition":
+ * 0000 0000-0000 007F 0xxxxxxx
+ * 0000 0080-0000 07FF 110xxxxx 10xxxxxx
+ * 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
+ *
+ * This reader will return incorrect last character on broken UTF-8 stream.
+ */
+public class ReaderUTF8 extends Reader {
+
+ private InputStream is;
+
+ /**
+ * Constructor.
+ *
+ * @param is A byte input stream.
+ */
+ public ReaderUTF8(InputStream is) {
+ this.is = is;
+ }
+
+ /**
+ * Reads characters into a portion of an array.
+ *
+ * @param cbuf Destination buffer.
+ * @param off Offset at which to start storing characters.
+ * @param len Maximum number of characters to read.
+ * @exception IOException If any IO errors occur.
+ * @exception UnsupportedEncodingException If UCS-4 character occur in the stream.
+ */
+ public int read(char[] cbuf, int off, int len) throws IOException {
+ int num = 0;
+ int val;
+ while (num < len) {
+ if ((val = is.read()) < 0) {
+ return (num != 0) ? num : -1;
+ }
+ switch (val & 0xf0) {
+ case 0xc0:
+ case 0xd0:
+ cbuf[off++] = (char) (((val & 0x1f) << 6) | (is.read() & 0x3f));
+ break;
+
+ case 0xe0:
+ cbuf[off++] = (char) (((val & 0x0f) << 12)
+ | ((is.read() & 0x3f) << 6) | (is.read() & 0x3f));
+ break;
+
+ case 0xf0: // UCS-4 character
+ throw new UnsupportedEncodingException("UTF-32 (or UCS-4) encoding not supported.");
+
+ default:
+ cbuf[off++] = (char) val;
+ break;
+ }
+ num++;
+ }
+ return num;
+ }
+
+ /**
+ * Reads a single character.
+ *
+ * @return The character read, as an integer in the range 0 to 65535
+ * (0x00-0xffff), or -1 if the end of the stream has been reached.
+ * @exception IOException If any IO errors occur.
+ * @exception UnsupportedEncodingException If UCS-4 character occur in the stream.
+ */
+ public int read() throws IOException {
+ int val;
+ if ((val = is.read()) < 0) {
+ return -1;
+ }
+ switch (val & 0xf0) {
+ case 0xc0:
+ case 0xd0:
+ val = ((val & 0x1f) << 6) | (is.read() & 0x3f);
+ break;
+
+ case 0xe0:
+ val = ((val & 0x0f) << 12)
+ | ((is.read() & 0x3f) << 6) | (is.read() & 0x3f);
+ break;
+
+ case 0xf0: // UCS-4 character
+ throw new UnsupportedEncodingException();
+
+ default:
+ break;
+ }
+ return val;
+ }
+
+ /**
+ * Closes the stream.
+ *
+ * @exception IOException If any IO errors occur.
+ */
+ public void close() throws IOException {
+ is.close();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/jdk/internal/util/xml/impl/SAXParserImpl.java Wed Dec 19 12:09:10 2012 +0000
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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 General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.util.xml.impl;
+
+import java.io.IOException;
+import java.io.InputStream;
+import jdk.internal.org.xml.sax.InputSource;
+import jdk.internal.org.xml.sax.SAXException;
+import jdk.internal.org.xml.sax.XMLReader;
+import jdk.internal.org.xml.sax.helpers.DefaultHandler;
+import jdk.internal.util.xml.SAXParser;
+
+public class SAXParserImpl extends SAXParser {
+
+ private ParserSAX parser;
+
+ public SAXParserImpl() {
+ super();
+ parser = new ParserSAX();
+ }
+
+ /**
+ * Returns the {@link org.xml.sax.XMLReader} that is encapsulated by the
+ * implementation of this class.
+ *
+ * @return The XMLReader that is encapsulated by the
+ * implementation of this class.
+ *
+ * @throws SAXException If any SAX errors occur during processing.
+ */
+ public XMLReader getXMLReader()
+ throws SAXException {
+ return parser;
+ }
+
+ /**
+ * Indicates whether or not this parser is configured to
+ * understand namespaces.
+ *
+ * @return true if this parser is configured to
+ * understand namespaces; false otherwise.
+ */
+ public boolean isNamespaceAware() {
+ return parser.mIsNSAware;
+ }
+
+ /**
+ * Indicates whether or not this parser is configured to validate
+ * XML documents.
+ *
+ * @return true if this parser is configured to validate XML
+ * documents; false otherwise.
+ */
+ public boolean isValidating() {
+ return false;
+ }
+
+ /**
+ * Parse the content of the given {@link java.io.InputStream}
+ * instance as XML using the specified
+ * {@link org.xml.sax.helpers.DefaultHandler}.
+ *
+ * @param src InputStream containing the content to be parsed.
+ * @param handler The SAX DefaultHandler to use.
+ * @exception IOException If any IO errors occur.
+ * @exception IllegalArgumentException If the given InputStream or handler is null.
+ * @exception SAXException If the underlying parser throws a
+ * SAXException while parsing.
+ * @see org.xml.sax.helpers.DefaultHandler
+ */
+ public void parse(InputStream src, DefaultHandler handler)
+ throws SAXException, IOException
+ {
+ parser.parse(src, handler);
+ }
+
+ /**
+ * Parse the content given {@link org.xml.sax.InputSource}
+ * as XML using the specified
+ * {@link org.xml.sax.helpers.DefaultHandler}.
+ *
+ * @param is The InputSource containing the content to be parsed.
+ * @param handler The SAX DefaultHandler to use.
+ * @exception IOException If any IO errors occur.
+ * @exception IllegalArgumentException If the InputSource or handler is null.
+ * @exception SAXException If the underlying parser throws a
+ * SAXException while parsing.
+ * @see org.xml.sax.helpers.DefaultHandler
+ */
+ public void parse(InputSource is, DefaultHandler handler)
+ throws SAXException, IOException
+ {
+ parser.parse(is, handler);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/jdk/internal/util/xml/impl/XMLStreamWriterImpl.java Wed Dec 19 12:09:10 2012 +0000
@@ -0,0 +1,633 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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 General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.util.xml.impl;
+
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.nio.charset.Charset;
+import java.nio.charset.IllegalCharsetNameException;
+import java.nio.charset.UnsupportedCharsetException;
+import jdk.internal.util.xml.XMLStreamException;
+import jdk.internal.util.xml.XMLStreamWriter;
+
+/**
+ * Implementation of a reduced version of XMLStreamWriter
+ *
+ * @author Joe Wang
+ */
+public class XMLStreamWriterImpl implements XMLStreamWriter {
+ //Document state
+
+ static final int STATE_XML_DECL = 1;
+ static final int STATE_PROLOG = 2;
+ static final int STATE_DTD_DECL = 3;
+ static final int STATE_ELEMENT = 4;
+ //Element state
+ static final int ELEMENT_STARTTAG_OPEN = 10;
+ static final int ELEMENT_STARTTAG_CLOSE = 11;
+ static final int ELEMENT_ENDTAG_OPEN = 12;
+ static final int ELEMENT_ENDTAG_CLOSE = 13;
+ public static final char CLOSE_START_TAG = '>';
+ public static final char OPEN_START_TAG = '<';
+ public static final String OPEN_END_TAG = "</";
+ public static final char CLOSE_END_TAG = '>';
+ public static final String START_CDATA = "<![CDATA[";
+ public static final String END_CDATA = "]]>";
+ public static final String CLOSE_EMPTY_ELEMENT = "/>";
+ public static final String ENCODING_PREFIX = "&#x";
+ public static final char SPACE = ' ';
+ public static final char AMPERSAND = '&';
+ public static final char DOUBLEQUOT = '"';
+ public static final char SEMICOLON = ';';
+ //current state
+ private int _state = 0;
+ private Element _currentEle;
+ private XMLWriter _writer;
+ private String _encoding;
+ /**
+ * This flag can be used to turn escaping off for content. It does
+ * not apply to attribute content.
+ */
+ boolean _escapeCharacters = true;
+ //pretty print by default
+ private boolean _doIndent = true;
+ //The system line separator for writing out line breaks.
+ private char[] _lineSep =
+ System.getProperty("line.separator").toCharArray();
+
+ public XMLStreamWriterImpl(OutputStream os) throws XMLStreamException {
+ this(os, XMLStreamWriter.DEFAULT_ENCODING);
+ }
+
+ public XMLStreamWriterImpl(OutputStream os, String encoding)
+ throws XMLStreamException
+ {
+ Charset cs = null;
+ if (encoding == null) {
+ _encoding = XMLStreamWriter.DEFAULT_ENCODING;
+ } else {
+ try {
+ cs = getCharset(encoding);
+ } catch (UnsupportedEncodingException e) {
+ throw new XMLStreamException(e);
+ }
+
+ this._encoding = encoding;
+ }
+
+ _writer = new XMLWriter(os, encoding, cs);
+ }
+
+ /**
+ * Write the XML Declaration. Defaults the XML version to 1.0, and the
+ * encoding to utf-8.
+ *
+ * @throws XMLStreamException
+ */
+ public void writeStartDocument() throws XMLStreamException {
+ writeStartDocument(_encoding, XMLStreamWriter.DEFAULT_XML_VERSION);
+ }
+
+ /**
+ * Write the XML Declaration. Defaults the encoding to utf-8
+ *
+ * @param version version of the xml document
+ * @throws XMLStreamException
+ */
+ public void writeStartDocument(String version) throws XMLStreamException {
+ writeStartDocument(_encoding, version, null);
+ }
+
+ /**
+ * Write the XML Declaration. Note that the encoding parameter does not set
+ * the actual encoding of the underlying output. That must be set when the
+ * instance of the XMLStreamWriter is created
+ *
+ * @param encoding encoding of the xml declaration
+ * @param version version of the xml document
+ * @throws XMLStreamException If given encoding does not match encoding of the
+ * underlying stream
+ */
+ public void writeStartDocument(String encoding, String version) throws XMLStreamException {
+ writeStartDocument(encoding, version, null);
+ }
+
+ /**
+ * Write the XML Declaration. Note that the encoding parameter does not set
+ * the actual encoding of the underlying output. That must be set when the
+ * instance of the XMLStreamWriter is created
+ *
+ * @param encoding encoding of the xml declaration
+ * @param version version of the xml document
+ * @param standalone indicate if the xml document is standalone
+ * @throws XMLStreamException If given encoding does not match encoding of the
+ * underlying stream
+ */
+ public void writeStartDocument(String encoding, String version, String standalone)
+ throws XMLStreamException
+ {
+ if (_state > 0) {
+ throw new XMLStreamException("XML declaration must be as the first line in the XML document.");
+ }
+ _state = STATE_XML_DECL;
+ String enc = encoding;
+ if (enc == null) {
+ enc = _encoding;
+ } else {
+ //check if the encoding is supported
+ try {
+ getCharset(encoding);
+ } catch (UnsupportedEncodingException e) {
+ throw new XMLStreamException(e);
+ }
+ }
+
+ if (version == null) {
+ version = XMLStreamWriter.DEFAULT_XML_VERSION;
+ }
+
+ _writer.write("<?xml version=\"");
+ _writer.write(version);
+ _writer.write(DOUBLEQUOT);
+
+ if (enc != null) {
+ _writer.write(" encoding=\"");
+ _writer.write(enc);
+ _writer.write(DOUBLEQUOT);
+ }
+
+ if (standalone != null) {
+ _writer.write(" standalone=\"");
+ _writer.write(standalone);
+ _writer.write(DOUBLEQUOT);
+ }
+ _writer.write("?>");
+ writeLineSeparator();
+ }
+
+ /**
+ * Write a DTD section. This string represents the entire doctypedecl production
+ * from the XML 1.0 specification.
+ *
+ * @param dtd the DTD to be written
+ * @throws XMLStreamException
+ */
+ public void writeDTD(String dtd) throws XMLStreamException {
+ if (_currentEle != null && _currentEle.getState() == ELEMENT_STARTTAG_OPEN) {
+ closeStartTag();
+ }
+ _writer.write(dtd);
+ writeLineSeparator();
+ }
+
+ /**
+ * Writes a start tag to the output.
+ * @param localName local name of the tag, may not be null
+ * @throws XMLStreamException
+ */
+ public void writeStartElement(String localName) throws XMLStreamException {
+ if (localName == null || localName.length() == 0) {
+ throw new XMLStreamException("Local Name cannot be null or empty");
+ }
+
+ _state = STATE_ELEMENT;
+ if (_currentEle != null && _currentEle.getState() == ELEMENT_STARTTAG_OPEN) {
+ closeStartTag();
+ }
+
+ _currentEle = new Element(_currentEle, localName, false);
+ openStartTag();
+
+ _writer.write(localName);
+ }
+
+ /**
+ * Writes an empty element tag to the output
+ * @param localName local name of the tag, may not be null
+ * @throws XMLStreamException
+ */
+ public void writeEmptyElement(String localName) throws XMLStreamException {
+ if (_currentEle != null && _currentEle.getState() == ELEMENT_STARTTAG_OPEN) {
+ closeStartTag();
+ }
+
+ _currentEle = new Element(_currentEle, localName, true);
+
+ openStartTag();
+ _writer.write(localName);
+ }
+
+ /**
+ * Writes an attribute to the output stream without a prefix.
+ * @param localName the local name of the attribute
+ * @param value the value of the attribute
+ * @throws IllegalStateException if the current state does not allow Attribute writing
+ * @throws XMLStreamException
+ */
+ public void writeAttribute(String localName, String value) throws XMLStreamException {
+ if (_currentEle.getState() != ELEMENT_STARTTAG_OPEN) {
+ throw new XMLStreamException(
+ "Attribute not associated with any element");
+ }
+
+ _writer.write(SPACE);
+ _writer.write(localName);
+ _writer.write("=\"");
+ writeXMLContent(
+ value,
+ true, // true = escapeChars
+ true); // true = escapeDoubleQuotes
+ _writer.write(DOUBLEQUOT);
+ }
+
+ public void writeEndDocument() throws XMLStreamException {
+ if (_currentEle != null && _currentEle.getState() == ELEMENT_STARTTAG_OPEN) {
+ closeStartTag();
+ }
+
+ /**
+ * close unclosed elements if any
+ */
+ while (_currentEle != null) {
+
+ if (!_currentEle.isEmpty()) {
+ _writer.write(OPEN_END_TAG);
+ _writer.write(_currentEle.getLocalName());
+ _writer.write(CLOSE_END_TAG);
+ }
+
+ _currentEle = _currentEle.getParent();
+ }
+ }
+
+ public void writeEndElement() throws XMLStreamException {
+ if (_currentEle != null && _currentEle.getState() == ELEMENT_STARTTAG_OPEN) {
+ closeStartTag();
+ }
+
+ if (_currentEle == null) {
+ throw new XMLStreamException("No element was found to write");
+ }
+
+ if (_currentEle.isEmpty()) {
+ return;
+ }
+
+ _writer.write(OPEN_END_TAG);
+ _writer.write(_currentEle.getLocalName());
+ _writer.write(CLOSE_END_TAG);
+ writeLineSeparator();
+
+ _currentEle = _currentEle.getParent();
+ }
+
+ public void writeCData(String cdata) throws XMLStreamException {
+ if (cdata == null) {
+ throw new XMLStreamException("cdata cannot be null");
+ }
+
+ if (_currentEle != null && _currentEle.getState() == ELEMENT_STARTTAG_OPEN) {
+ closeStartTag();
+ }
+
+ _writer.write(START_CDATA);
+ _writer.write(cdata);
+ _writer.write(END_CDATA);
+ }
+
+ public void writeCharacters(String data) throws XMLStreamException {
+ if (_currentEle != null && _currentEle.getState() == ELEMENT_STARTTAG_OPEN) {
+ closeStartTag();
+ }
+
+ writeXMLContent(data);
+ }
+
+ public void writeCharacters(char[] data, int start, int len)
+ throws XMLStreamException {
+ if (_currentEle != null && _currentEle.getState() == ELEMENT_STARTTAG_OPEN) {
+ closeStartTag();
+ }
+
+ writeXMLContent(data, start, len, _escapeCharacters);
+ }
+
+ /**
+ * Close this XMLStreamWriter by closing underlying writer.
+ */
+ public void close() throws XMLStreamException {
+ if (_writer != null) {
+ _writer.close();
+ }
+ _writer = null;
+ _currentEle = null;
+ _state = 0;
+ }
+
+ /**
+ * Flush this XMLStreamWriter by flushing underlying writer.
+ */
+ public void flush() throws XMLStreamException {
+ if (_writer != null) {
+ _writer.flush();
+ }
+ }
+
+ /**
+ * Set the flag to indicate if the writer should add line separator
+ * @param doIndent
+ */
+ public void setDoIndent(boolean doIndent) {
+ _doIndent = doIndent;
+ }
+
+ /**
+ * Writes XML content to underlying writer. Escapes characters unless
+ * escaping character feature is turned off.
+ */
+ private void writeXMLContent(char[] content, int start, int length, boolean escapeChars)
+ throws XMLStreamException
+ {
+ if (!escapeChars) {
+ _writer.write(content, start, length);
+ return;
+ }
+
+ // Index of the next char to be written
+ int startWritePos = start;
+
+ final int end = start + length;
+
+ for (int index = start; index < end; index++) {
+ char ch = content[index];
+
+ if (!_writer.canEncode(ch)) {
+ _writer.write(content, startWritePos, index - startWritePos);
+
+ // Escape this char as underlying encoder cannot handle it
+ _writer.write(ENCODING_PREFIX);
+ _writer.write(Integer.toHexString(ch));
+ _writer.write(SEMICOLON);
+ startWritePos = index + 1;
+ continue;
+ }
+
+ switch (ch) {
+ case OPEN_START_TAG:
+ _writer.write(content, startWritePos, index - startWritePos);
+ _writer.write("<");
+ startWritePos = index + 1;
+
+ break;
+
+ case AMPERSAND:
+ _writer.write(content, startWritePos, index - startWritePos);
+ _writer.write("&");
+ startWritePos = index + 1;
+
+ break;
+
+ case CLOSE_START_TAG:
+ _writer.write(content, startWritePos, index - startWritePos);
+ _writer.write(">");
+ startWritePos = index + 1;
+
+ break;
+ }
+ }
+
+ // Write any pending data
+ _writer.write(content, startWritePos, end - startWritePos);
+ }
+
+ private void writeXMLContent(String content) throws XMLStreamException {
+ if ((content != null) && (content.length() > 0)) {
+ writeXMLContent(content,
+ _escapeCharacters, // boolean = escapeChars
+ false); // false = escapeDoubleQuotes
+ }
+ }
+
+ /**
+ * Writes XML content to underlying writer. Escapes characters unless
+ * escaping character feature is turned off.
+ */
+ private void writeXMLContent(
+ String content,
+ boolean escapeChars,
+ boolean escapeDoubleQuotes)
+ throws XMLStreamException
+ {
+
+ if (!escapeChars) {
+ _writer.write(content);
+
+ return;
+ }
+
+ // Index of the next char to be written
+ int startWritePos = 0;
+
+ final int end = content.length();
+
+ for (int index = 0; index < end; index++) {
+ char ch = content.charAt(index);
+
+ if (!_writer.canEncode(ch)) {
+ _writer.write(content, startWritePos, index - startWritePos);
+
+ // Escape this char as underlying encoder cannot handle it
+ _writer.write(ENCODING_PREFIX);
+ _writer.write(Integer.toHexString(ch));
+ _writer.write(SEMICOLON);
+ startWritePos = index + 1;
+ continue;
+ }
+
+ switch (ch) {
+ case OPEN_START_TAG:
+ _writer.write(content, startWritePos, index - startWritePos);
+ _writer.write("<");
+ startWritePos = index + 1;
+
+ break;
+
+ case AMPERSAND:
+ _writer.write(content, startWritePos, index - startWritePos);
+ _writer.write("&");
+ startWritePos = index + 1;
+
+ break;
+
+ case CLOSE_START_TAG:
+ _writer.write(content, startWritePos, index - startWritePos);
+ _writer.write(">");
+ startWritePos = index + 1;
+
+ break;
+
+ case DOUBLEQUOT:
+ _writer.write(content, startWritePos, index - startWritePos);
+ if (escapeDoubleQuotes) {
+ _writer.write(""");
+ } else {
+ _writer.write(DOUBLEQUOT);
+ }
+ startWritePos = index + 1;
+
+ break;
+ }
+ }
+
+ // Write any pending data
+ _writer.write(content, startWritePos, end - startWritePos);
+ }
+
+ /**
+ * marks open of start tag and writes the same into the writer.
+ */
+ private void openStartTag() throws XMLStreamException {
+ _currentEle.setState(ELEMENT_STARTTAG_OPEN);
+ _writer.write(OPEN_START_TAG);
+ }
+
+ /**
+ * marks close of start tag and writes the same into the writer.
+ */
+ private void closeStartTag() throws XMLStreamException {
+ if (_currentEle.isEmpty()) {
+ _writer.write(CLOSE_EMPTY_ELEMENT);
+ } else {
+ _writer.write(CLOSE_START_TAG);
+
+ }
+
+ if (_currentEle.getParent() == null) {
+ writeLineSeparator();
+ }
+
+ _currentEle.setState(ELEMENT_STARTTAG_CLOSE);
+
+ }
+
+ /**
+ * Write a line separator
+ * @throws XMLStreamException
+ */
+ private void writeLineSeparator() throws XMLStreamException {
+ if (_doIndent) {
+ _writer.write(_lineSep, 0, _lineSep.length);
+ }
+ }
+
+ /**
+ * Returns a charset object for the specified encoding
+ * @param encoding
+ * @return a charset object
+ * @throws UnsupportedEncodingException if the encoding is not supported
+ */
+ private Charset getCharset(String encoding) throws UnsupportedEncodingException {
+ if (encoding.equalsIgnoreCase("UTF-32")) {
+ throw new UnsupportedEncodingException("The basic XMLWriter does "
+ + "not support " + encoding);
+ }
+
+ Charset cs;
+ try {
+ cs = Charset.forName(encoding);
+ } catch (IllegalCharsetNameException | UnsupportedCharsetException ex) {
+ throw new UnsupportedEncodingException(encoding);
+ }
+ return cs;
+ }
+
+ /*
+ * Start of Internal classes.
+ *
+ */
+ protected class Element {
+
+ /**
+ * the parent element
+ */
+ protected Element _parent;
+ /**
+ * The size of the stack.
+ */
+ protected short _Depth;
+ /**
+ * indicate if an element is an empty one
+ */
+ boolean _isEmptyElement = false;
+ String _localpart;
+ int _state;
+
+ /**
+ * Default constructor.
+ */
+ public Element() {
+ }
+
+ /**
+ * @param parent the parent of the element
+ * @param localpart name of the element
+ * @param isEmpty indicate if the element is an empty one
+ */
+ public Element(Element parent, String localpart, boolean isEmpty) {
+ _parent = parent;
+ _localpart = localpart;
+ _isEmptyElement = isEmpty;
+ }
+
+ public Element getParent() {
+ return _parent;
+ }
+
+ public String getLocalName() {
+ return _localpart;
+ }
+
+ /**
+ * get the state of the element
+ */
+ public int getState() {
+ return _state;
+ }
+
+ /**
+ * Set the state of the element
+ *
+ * @param state the state of the element
+ */
+ public void setState(int state) {
+ _state = state;
+ }
+
+ public boolean isEmpty() {
+ return _isEmptyElement;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/jdk/internal/util/xml/impl/XMLWriter.java Wed Dec 19 12:09:10 2012 +0000
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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 General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.util.xml.impl;
+
+import java.io.BufferedOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.UnsupportedEncodingException;
+import java.io.Writer;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetEncoder;
+import jdk.internal.util.xml.XMLStreamException;
+
+/**
+ *
+ * @author huizwang
+ */
+public class XMLWriter {
+
+ private Writer _writer;
+ /**
+ * In some cases, this charset encoder is used to determine if a char is
+ * encodable by underlying writer. For example, an 8-bit char from the
+ * extended ASCII set is not encodable by 7-bit ASCII encoder. Unencodable
+ * chars are escaped using XML numeric entities.
+ */
+ private CharsetEncoder _encoder = null;
+
+ public XMLWriter(OutputStream os, String encoding, Charset cs) throws XMLStreamException {
+ _encoder = cs.newEncoder();
+ try {
+ _writer = getWriter(os, encoding, cs);
+ } catch (UnsupportedEncodingException ex) {
+ throw new XMLStreamException(ex);
+ }
+
+ }
+
+ public boolean canEncode(char ch) {
+ if (_encoder == null) {
+ return false;
+ }
+ return (_encoder.canEncode(ch));
+ }
+
+ public void write(String s)
+ throws XMLStreamException {
+ try {
+ _writer.write(s.toCharArray());
+// _writer.write(s.getBytes(Charset.forName(_encoding)));
+ } catch (IOException e) {
+ throw new XMLStreamException("I/O error", e);
+ }
+ }
+
+ public void write(String str, int off, int len)
+ throws XMLStreamException {
+ try {
+ _writer.write(str, off, len);
+ } catch (IOException e) {
+ throw new XMLStreamException("I/O error", e);
+ }
+
+ }
+
+ public void write(char[] cbuf, int off, int len)
+ throws XMLStreamException {
+ try {
+ _writer.write(cbuf, off, len);
+ } catch (IOException e) {
+ throw new XMLStreamException("I/O error", e);
+ }
+
+ }
+
+ void write(int b)
+ throws XMLStreamException {
+ try {
+ _writer.write(b);
+ } catch (IOException e) {
+ throw new XMLStreamException("I/O error", e);
+ }
+ }
+
+ void flush() throws XMLStreamException {
+ try {
+ _writer.flush();
+ } catch (IOException ex) {
+ throw new XMLStreamException(ex);
+ }
+ }
+
+ void close() throws XMLStreamException {
+ try {
+ _writer.close();
+ } catch (IOException ex) {
+ throw new XMLStreamException(ex);
+ }
+ }
+
+ private void nl() throws XMLStreamException {
+ String lineEnd = System.getProperty("line.separator");
+ try {
+ _writer.write(lineEnd);
+ } catch (IOException e) {
+ throw new XMLStreamException("I/O error", e);
+ }
+ }
+
+ /**
+ * Returns a writer for the specified encoding based on an output stream.
+ *
+ * @param output The output stream
+ * @param encoding The encoding
+ * @return A suitable writer
+ * @throws UnsupportedEncodingException There is no convertor to support
+ * this encoding
+ */
+ private Writer getWriter(OutputStream output, String encoding, Charset cs)
+ throws XMLStreamException, UnsupportedEncodingException
+ {
+ if (cs != null) {
+ return (new OutputStreamWriter(new BufferedOutputStream(output), cs));
+ }
+
+ return new OutputStreamWriter(new BufferedOutputStream(output), encoding);
+ }
+}