/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* 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.
*/
/**
* This class implements a StAX XMLStreamWriter. It extends
* <code>AbstractMap</code> in order to support a getter for
* implementation-specific properties. For example, you can get
* the underlying <code>OutputStream</code> by casting an instance
* of this class to <code>Map</code> and calling
* <code>getProperty(OUTPUTSTREAM_PROPERTY)</code>.
*
* @author Neeraj Bajaj
* @author K.Venugopal
* @author Santiago.Pericas-Geertsen@sun.com
* @author Sunitha.Reddy@sun.com
*/
/**
* This flag can be used to turn escaping off for content. It does
* not apply to attribute content.
*/
boolean fEscapeCharacters = true;
/**
* Flag for the value of repairNamespace property
*/
private boolean fIsRepairingNamespace = false;
/**
* Underlying Writer to which characters are written.
*/
/**
* Underlying OutputStream to which <code>fWriter</code>
* writes to. May be null if unknown.
*/
/**
* Collects attributes when the writer is in reparing mode.
*/
/**
* Collects namespace declarations when the writer is in reparing mode.
*/
/**
* Namespace context encapsulating user specified context
* and context built by the writer
*/
/**
* Reference to PropertyManager
*/
/**
* Flag to track if start tag is opened
*/
private boolean fStartTagOpened = false;
/**
* Boolean flag to indicate, if instance can be reused
*/
private boolean fReuse;
/**
* 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.
*/
/**
* This is used to hold the namespace for attributes which happen to have
* the same uri as the default namespace; It's added to avoid changing the
* current impl. which has many redundant code for the repair mode
*/
/**
* Creates a new instance of XMLStreamWriterImpl. Uses platform's default
* encoding.
*
* @param outputStream Underlying stream to write the bytes to
* @param props Properties used by this writer
*/
throws IOException {
// cannot call this(outputStream, null, props); for constructor,
// OutputStreamWriter charsetName cannot be null
// use default encoding
}
/**
* Creates a new instance of XMLStreamWriterImpl.
*
* @param outputStream Underlying stream to write the bytes
* @param encoding Encoding used to convert chars into bytes
* @param props Properties used by this writer
*/
}
/**
* Creates a new instance of XMLStreamWriterImpl using a Writer.
*
* @param writer Underlying writer to which chars are written
* @param props Properties used by this writer
*/
}
/**
* Creates a new instance of XMLStreamWriterImpl using a StreamResult.
* A StreamResult encasupates an OutputStream, a Writer or a SystemId.
*
* @param writer Underlying writer to which chars are written
* @param props Properties used by this writer
*/
init();
}
/**
* Initialize an instance of this XMLStreamWriter. Allocate new instances
* for all the data structures. Set internal flags based on property values.
*/
private void init() {
fReuse = false;
fNamespaceDecls = new ArrayList();
fPrefixGen = new Random();
fAttributeCache = new ArrayList();
fNamespaceContext = new NamespaceContextImpl();
// Set internal state based on property values
}
/**
* Reset this instance so that it can be re-used. Do not read properties
* again. The method <code>setOutput(StreamResult, encoding)</code> must
* be called after this one.
*/
public void reset() {
reset(false);
}
/**
* Reset this instance so that it can be re-used. Clears but does not
* re-allocate internal data structures.
*
* @param resetProperties Indicates if properties should be read again
*/
if (!fReuse) {
"close() Must be called before calling reset()");
}
fReuse = false;
// reset Element/NamespaceContext stacks
fStartTagOpened = false;
if (resetProperties) {
}
}
/**
* Use a StreamResult to initialize the output for this XMLStreamWriter. Check
* for OutputStream, Writer and then systemId, in that order.
*
* @param sr StreamResult encapsulating output information
* @param encoding Encoding to be used except when a Writer is available
*/
throws IOException {
}
}
encoding);
}
}
throws IOException
{
if (writer instanceof OutputStreamWriter) {
}
}
}
/**
* Utility method to create a writer when passed an OutputStream. Make
* sure to wrap an <code>OutputStreamWriter</code> using an
* <code>XMLWriter</code> for performance reasons.
*
* @param os Underlying OutputStream
* @param encoding Encoding used to convert chars into bytes
*/
throws IOException {
fOutputStream = os;
}
else {
}
} else {
} else {
}
}
}
/** Can this instance be reused
*
* @return boolean boolean value to indicate if this instance can be reused or not
*/
public boolean canReuse() {
return fReuse;
}
}
public boolean getEscapeCharacters() {
return fEscapeCharacters;
}
/**
* Close this XMLStreamWriter by closing underlying writer.
*/
try {
//fWriter.close();
} catch (IOException e) {
throw new XMLStreamException(e);
}
}
fReuse = true;
fStartTagOpened = false;
}
/**
* Flush this XMLStreamWriter by flushin underlying writer.
*/
try {
} catch (IOException e) {
throw new XMLStreamException(e);
}
}
/**
* Return <code>NamespaceContext</code> being used by the writer.
*
* @return NamespaceContext
*/
return fNamespaceContext;
}
/**
* Return a prefix associated with specified uri, or null if the
* uri is unknown.
*
* @param uri The namespace uri
* @throws XMLStreamException if uri specified is "" or null
*/
}
/**
* Returns value associated with the specified property name.
*
* @param str Property name
* @throws IllegalArgumentException if the specified property is not supported
* @return value associated with the specified property.
*/
throws IllegalArgumentException {
throw new NullPointerException();
}
"' is not supported");
}
}
/**
* Set the specified URI as default namespace in the current namespace context.
*
* @param uri Namespace URI
*/
}
if (fIsRepairingNamespace) {
if (isDefaultNamespace(uri)) {
return;
}
} else {
}
}
/**
* Sets the current <code>NamespaceContext</code> for prefix and uri bindings.
* This context becomes the root namespace context for writing and
* will replace the current root namespace context. Subsequent calls
* to setPrefix and setDefaultNamespace will bind namespaces using
* the context passed to the method as the root context for resolving
* namespaces. This method may only be called once at the start of the
* document. It does not cause the namespaces to be declared. If a
* namespace URI to prefix mapping is found in the namespace context
* it is treated as declared and the prefix may be used by the
* <code>XMLStreamWriter</code>.
*
* @param namespaceContext the namespace context to use for this writer, may not be null
* @throws XMLStreamException
*/
throws XMLStreamException {
}
/**
* Sets the prefix the uri is bound to. This prefix is bound in the scope of
* the current START_ELEMENT / END_ELEMENT pair. If this method is called before
* a START_ELEMENT has been written the prefix is bound in the root scope.
*
* @param prefix
* @param uri
* @throws XMLStreamException
*/
throw new XMLStreamException("Prefix cannot be null");
}
throw new XMLStreamException("URI cannot be null");
}
if (fIsRepairingNamespace) {
return;
}
return;
return;
}
}
throws XMLStreamException {
try {
if (!fStartTagOpened) {
throw new XMLStreamException(
"Attribute not associated with any element");
}
if (fIsRepairingNamespace) {
return;
}
true, // true = escapeChars
true); // true = escapeDoubleQuotes
} catch (IOException e) {
throw new XMLStreamException(e);
}
}
try {
if (!fStartTagOpened) {
throw new XMLStreamException(
"Attribute not associated with any element");
}
if (namespaceURI == null) {
throw new XMLStreamException("NamespaceURI cannot be null");
}
if (!fIsRepairingNamespace) {
throw new XMLStreamException("Prefix cannot be null");
}
} else {
}
} catch (IOException e) {
throw new XMLStreamException(e);
}
}
}
true, // true = escapeChars
true); // true = escapeDoubleQuotes
}
try {
if (!fStartTagOpened) {
throw new XMLStreamException(
"Attribute not associated with any element");
}
if (namespaceURI == null) {
throw new XMLStreamException("NamespaceURI cannot be null");
}
throw new XMLStreamException("Local name cannot be null");
}
if (!fIsRepairingNamespace) {
throw new XMLStreamException("prefix cannot be null or empty");
} else {
return;
}
}
"already bound to "+tmpURI+
}
}
}
} else {
}
}
} catch (IOException e) {
throw new XMLStreamException(e);
}
}
try {
throw new XMLStreamException("cdata cannot be null");
}
if (fStartTagOpened) {
}
} catch (IOException e) {
throw new XMLStreamException(e);
}
}
try {
if (fStartTagOpened) {
}
} catch (IOException e) {
throw new XMLStreamException(e);
}
}
throws XMLStreamException {
try {
if (fStartTagOpened) {
}
} catch (IOException e) {
throw new XMLStreamException(e);
}
}
try {
if (fStartTagOpened) {
}
}
} catch (IOException e) {
throw new XMLStreamException(e);
}
}
try {
if (fStartTagOpened) {
}
} catch (IOException e) {
throw new XMLStreamException(e);
}
}
/*
* Write default Namespace.
*
* If namespaceURI == null,
* then it is assumed to be equivilent to {@link XMLConstants.NULL_NS_URI},
* i.e. there is no Namespace.
*
* @param namespaceURI NamespaceURI to declare.
*
* @throws XMLStreamException
*
* @see <a href="http://www.w3.org/TR/REC-xml-names/#defaulting">
* Namespaces in XML, 5.2 Namespace Defaulting</a>
*/
throws XMLStreamException {
// normalize namespaceURI
if (namespaceURI == null) {
} else {
}
try {
if (!fStartTagOpened) {
throw new IllegalStateException(
"Namespace Attribute not associated with any element");
}
if (fIsRepairingNamespace) {
return;
}
throw new XMLStreamException(
"xmlns has been already bound to " +tmp +
". Rebinding it to "+ namespaceURINormalized +
" is an error");
}
}
// use common namespace code with a prefix == null for xmlns="..."
} catch (IOException e) {
throw new XMLStreamException(e);
}
}
try {
if (fStartTagOpened) {
}
openStartTag();
if (!fIsRepairingNamespace) {
}
} catch (IOException e) {
throw new XMLStreamException(e);
}
}
throws XMLStreamException {
if (namespaceURI == null) {
throw new XMLStreamException("NamespaceURI cannot be null");
}
}
try {
throw new XMLStreamException("Local Name cannot be null");
}
if (namespaceURI == null) {
throw new XMLStreamException("NamespaceURI cannot be null");
}
}
if (fStartTagOpened) {
}
openStartTag();
if (!fIsRepairingNamespace) {
throw new XMLStreamException("NamespaceURI " +
namespaceURI + " has not been bound to any prefix");
}
} else {
return;
}
}
} catch (IOException e) {
throw new XMLStreamException(e);
}
}
try {
if (fStartTagOpened) {
}
while (!fElementStack.empty()) {
//fWriter.write(CLOSE_EMPTY_ELEMENT);
} else {
}
}
}
} catch (IOException e) {
throw new XMLStreamException(e);
} catch (ArrayIndexOutOfBoundsException e) {
throw new XMLStreamException("No more elements to write");
}
}
try {
if (fStartTagOpened) {
}
if (currentElement == null) {
throw new XMLStreamException("No element was found to write");
}
if (currentElement.isEmpty) {
//fWriter.write(CLOSE_EMPTY_ELEMENT);
return;
}
}
} catch (IOException e) {
throw new XMLStreamException(e);
} catch (ArrayIndexOutOfBoundsException e) {
throw new XMLStreamException(
"No element was found to write: "
+ e.toString(), e);
}
}
try {
if (fStartTagOpened) {
}
} catch (IOException e) {
throw new XMLStreamException(e);
}
}
/**
* Write a Namespace declaration.
*
* If namespaceURI == null,
* then it is assumed to be equivilent to {@link XMLConstants.NULL_NS_URI},
* i.e. there is no Namespace.
*
* @param prefix Prefix to bind.
* @param namespaceURI NamespaceURI to declare.
*
* @throws XMLStreamException
*
* @see <a href="http://www.w3.org/TR/REC-xml-names/#defaulting">
* Namespaces in XML, 5.2 Namespace Defaulting</a>
*/
throws XMLStreamException {
// normalize namespaceURI
if (namespaceURI == null) {
} else {
}
try {
if (!fStartTagOpened) {
throw new IllegalStateException(
"Invalid state: start tag is not opened at writeNamespace("
+ prefix
+ ", "
+ ")");
}
// is this the default Namespace?
return;
}
if (prefix.equals(XMLConstants.XML_NS_PREFIX) && namespaceURINormalized.equals(XMLConstants.XML_NS_URI))
return;
if (fIsRepairingNamespace) {
return;
}
return;
}
" has been already bound to " +tmp +
". Rebinding it to "+ namespaceURINormalized+
" is an error");
}
}
} catch (IOException e) {
throw new XMLStreamException(e);
}
}
throws IOException {
}
true, // true = escapeChars
true); // true = escapeDoubleQuotes
}
throws XMLStreamException {
try {
if (fStartTagOpened) {
}
return;
}
} catch (IOException e) {
throw new XMLStreamException(e);
}
throw new XMLStreamException("PI target cannot be null");
}
/**
* @param target
* @param data
* @throws XMLStreamException
*/
throws XMLStreamException {
try {
if (fStartTagOpened) {
}
throw new XMLStreamException("PI target cannot be null");
}
} catch (IOException e) {
throw new XMLStreamException(e);
}
}
/**
* @throws XMLStreamException
*/
try {
} catch (IOException ex) {
throw new XMLStreamException(ex);
}
}
/**
* @param version
* @throws XMLStreamException
*/
try {
return;
}
//fWriter.write(DEFAULT_ENCODING);
} catch (IOException ex) {
throw new XMLStreamException(ex);
}
}
/**
* @param encoding
* @param version
* @throws XMLStreamException
*/
throws XMLStreamException {
//Revisit : What about standalone ?
try {
return;
}
return;
}
if (fWriter instanceof OutputStreamWriter) {
}
else if (fWriter instanceof UTF8OutputStreamWriter) {
}
}
// If the equality check failed, check for charset encoding aliases
boolean foundAlias = false;
foundAlias = true;
}
}
// If no alias matches the encoding name, then report error
if (!foundAlias) {
throw new XMLStreamException("Underlying stream encoding '"
+ "' and input paramter for writeStartDocument() method '"
+ encoding + "' do not match.");
}
}
} else {
}
}
} catch (IOException ex) {
throw new XMLStreamException(ex);
}
}
/**
* @param localName
* @throws XMLStreamException
*/
try {
throw new XMLStreamException("Local Name cannot be null");
}
if (fStartTagOpened) {
}
openStartTag();
if (fIsRepairingNamespace) {
return;
}
} catch (IOException ex) {
throw new XMLStreamException(ex);
}
}
/**
* @param namespaceURI
* @param localName
* @throws XMLStreamException
*/
throws XMLStreamException {
throw new XMLStreamException("Local Name cannot be null");
}
if (namespaceURI == null) {
throw new XMLStreamException("NamespaceURI cannot be null");
}
if (!fIsRepairingNamespace) {
}
}
}
/**
* @param prefix
* @param localName
* @param namespaceURI
* @throws XMLStreamException
*/
try {
throw new XMLStreamException("Local Name cannot be null");
}
if (namespaceURI == null) {
throw new XMLStreamException("NamespaceURI cannot be null");
}
if (!fIsRepairingNamespace) {
throw new XMLStreamException("Prefix cannot be null");
}
}
if (fStartTagOpened) {
}
openStartTag();
}
}
if (fIsRepairingNamespace) {
return;
}
return;
}
}
} catch (IOException ex) {
throw new XMLStreamException(ex);
}
}
/**
* Writes XML content to underlying writer. Escapes characters unless
* escaping character feature is turned off.
*/
boolean escapeChars) throws IOException {
if (!escapeChars) {
return;
}
// Index of the next char to be written
int startWritePos = start;
// Escape this char as underlying encoder cannot handle it
continue;
}
switch (ch) {
case '<':
break;
case '&':
break;
case '>':
break;
}
}
// Write any pending data
}
fEscapeCharacters, // boolean = escapeChars
false); // false = escapeDoubleQuotes
}
}
/**
* Writes XML content to underlying writer. Escapes characters unless
* escaping character feature is turned off.
*/
private void writeXMLContent(
boolean escapeChars,
boolean escapeDoubleQuotes)
throws IOException {
if (!escapeChars) {
return;
}
// Index of the next char to be written
int startWritePos = 0;
// Escape this char as underlying encoder cannot handle it
continue;
}
switch (ch) {
case '<':
break;
case '&':
break;
case '>':
break;
case '"':
if (escapeDoubleQuotes) {
} else {
}
break;
}
}
// Write any pending data
}
/**
* marks close of start tag and writes the same into the writer.
*/
try {
if (fIsRepairingNamespace) {
repair();
}
for (int i = 0; i < len; i++) {
}
}
}
}
} else {
}
}
}
}
}
}
if (currentElement.isEmpty) {
fElementStack.pop();
} else {
}
fStartTagOpened = false;
} catch (IOException ex) {
fStartTagOpened = false;
throw new XMLStreamException(ex);
}
}
/**
* marks open of start tag and writes the same into the writer.
*/
fStartTagOpened = true;
}
/**
*
* @param uri
* @return
*/
boolean isSpecialCaseURI = false;
return;
}
return;
return;
}
}
return;
}
//the uri happens to be the same as that of the default namespace
isSpecialCaseURI = true;
}
}
for (int i = 0; i < 1; i++) {
}
} else {
}
if (isSpecialCaseURI) {
} else {
}
}
}
}
/**
* return the prefix if the attribute has an uri the same as that of the default namespace
*/
if (fAttrNamespace != null) {
}
return null;
}
if (fAttrNamespace == null) {
fAttrNamespace = new HashMap();
}
}
/**
* @param uri
* @return
*/
if (uri == defaultNamespace) {
return true;
}
return false;
}
/**
* @param prefix
* @param uri
* @return
*/
return true;
}
}
return false;
}
/**
* Correct's namespaces as per requirements of isReparisingNamespace property.
*/
protected void repair() {
if((attr.prefix != null && !attr.prefix.equals("")) || (attr.uri != null && !attr.uri.equals(""))) {
}
}
if (!isDeclared(currentElement)) {
}
}
}
}
}
}
int i = 0;
/* If 'attr' is an attribute and it is in no namespace(which means that prefix="", uri=""), attr's
namespace should not be redinded. See [http://www.w3.org/TR/REC-xml-names/#defaulting].
*/
}
}
}
}
}
}
/*
*are bound to different namespace URIs and are using the same prefix then
*the element or the first occurring attribute retains the original prefix
*and the following attributes have their prefixes replaced with a new prefix
*that is bound to the namespace URIs of those attributes.
*/
boolean done = false;
} else {
return;
}
}
//No namespace mapping found , so declare prefix.
for (int k = 0; k < 1; k++) {
}
}
}
}
}
void removeDuplicateDecls(){
// QName.equals relies on identity equality, so we can't use it,
// because prefixes aren't interned
}
}
}
}
/*
*If an element or attribute name is bound to a prefix and there is a namespace
*declaration that binds that prefix to a different URI then that namespace declaration
*is either removed if the correct mapping is inherited from the parent context of that element,
*or changed to the namespace URI of the element or attribute using that prefix.
*
*/
//check for null prefix.
//see if you need to add to symbole table.
} else {
}
}
}
}
}
}
return true;
}
}
return true;
}
}
return false;
}
/*
* Start of Internal classes.
*
*/
protected class ElementStack {
/** The stack data. */
/** The size of the stack. */
protected short fDepth;
/** Default constructor. */
public ElementStack() {
fElements[i] = new ElementState();
}
}
/**
* Pushes an element on the stack.
* <p>
* <strong>Note:</strong> The QName values are copied into the
* stack. In other words, the caller does <em>not</em> orphan
* the element to the stack. Also, the QName object returned
* is <em>not</em> orphaned to the caller. It should be
* considered read-only.
*
* @param element The element to push onto the stack.
*
* @return Returns the actual QName object that stores the
*/
fElements[i] = new ElementState();
}
}
}
/**
*
* @param prefix
* @param localpart
* @param rawname
* @param uri
* @param isEmpty
* @return
*/
fElements[i] = new ElementState();
}
}
}
/**
* Pops an element off of the stack by setting the values of
* the specified QName.
* <p>
* <strong>Note:</strong> The object returned is <em>not</em>
* orphaned to the caller. Therefore, the caller should consider
* the object to be read-only.
*/
}
/** Clears the stack without throwing away existing QName objects. */
public void clear() {
fDepth = 0;
}
/**
* This function is as a result of optimization done for endElement --
* we dont need to set the value for every end element we encouter.
* For Well formedness checks we can have the same QName object that was pushed.
* the values will be set only if application need to know about the endElement
* -- neeraj.bajaj@sun.com
*/
}
/**
*
* @return
*/
public boolean empty() {
return (fDepth > 0) ? false : true;
}
}
/**
* Maintains element state . localName for now.
*/
public boolean isEmpty = false;
public ElementState() {}
}
}
}
/**
* Attributes
*/
super();
}
}
/**
* Implementation of NamespaceContext .
*
*/
//root namespace context set by user.
//context built by the writer.
}
if (internalContext != null) {
return uri;
}
}
if (userContext != null) {
return uri;
}
return null;
}
}
if (internalContext != null) {
return prefix;
}
}
if (userContext != null) {
}
return null;
}
}
if (userContext != null) {
}
if (internalContext != null) {
}
return itr;
}
}
}
}
return fReadOnlyIterator;
}
}
// -- Map Interface --------------------------------------------------
public int size() {
return 1;
}
public boolean isEmpty() {
return false;
}
}
/**
* Returns the value associated to an implementation-specific
* property.
*/
return fOutputStream;
}
return null;
}
throw new UnsupportedOperationException();
}
/**
* Overrides the method defined in AbstractMap which is
* not completely implemented. Calling toString() in
* AbstractMap would cause an unsupported exection to
* be thrown.
*/
}
/**
* Overrides the method defined in AbstractMap
* This is required by the toString() method
*/
public int hashCode() {
return fElementStack.hashCode();
}
/**
* Overrides the method defined in AbstractMap
* This is required to satisfy the contract for hashCode.
*/
return (this == obj);
}
}