
com.tangosol.run.xml.SimpleDocument Maven / Gradle / Ivy
/*
* Copyright (c) 2000, 2021, Oracle and/or its affiliates.
*
* Licensed under the Universal Permissive License v 1.0 as shown at
* http://oss.oracle.com/licenses/upl.
*/
package com.tangosol.run.xml;
import com.tangosol.io.Utf8Writer;
import com.tangosol.io.pof.PofReader;
import com.tangosol.io.pof.PofWriter;
import java.io.CharArrayWriter;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.Externalizable;
import java.io.IOException;
import java.io.NotActiveException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.io.OutputStream;
import java.io.PrintWriter;
/**
* A simple implementation of the XmlElement interface. Protected methods are
* provided to support inheriting classes.
*
* @author cp 2000.10.20
*/
public class SimpleDocument
extends SimpleElement
implements XmlDocument, Externalizable
{
// ----- constructors ---------------------------------------------------
/**
* Construct an empty SimpleDocument.
*
* Note: this constructor is needed only to comply with the
* requirements for the Externalizable and ExternalizableLite interfaces.
*/
public SimpleDocument()
{
super();
}
/**
* Construct a SimpleDocument.
*
* @param sName the name of the root element
*/
public SimpleDocument(String sName)
{
super(sName);
}
/**
* Construct a SimpleDocument.
*
* @param sName the name of the root element
* @param sDtdUri the URI of the DTD (system identifier)
* @param sDtdName the name of the DTD (public identifier); may be null
*/
public SimpleDocument(String sName, String sDtdUri, String sDtdName)
{
super(sName);
setDtdUri(sDtdUri);
setDtdName(sDtdName);
}
// ----- XmlDocument interface -------------------------------------------
/**
* Get the URI of the DTD (DOCTYPE) for the document. This is referred to
* as the System Identifier by the XML specification.
*
* For example:
* http://java.sun.com/j2ee/dtds/web-app_2_2.dtd
*
* @return the document type URI
*/
public String getDtdUri()
{
return m_sDtdUri;
}
/**
* Set the URI of the DTD (DOCTYPE) for the document. This is referred to
* as the System Identifier by the XML specification.
*
* @param sUri the document type URI
*/
public void setDtdUri(String sUri)
{
checkMutable();
m_sDtdUri = sUri;
}
/**
* Get the public identifier of the DTD (DOCTYPE) for the document.
*
* For example:
* -//Sun Microsystems, Inc.//DTD Web Application 1.2//EN
*
* @return the DTD public identifier
*/
public String getDtdName()
{
return m_sDtdName;
}
/**
* Set the public identifier of the DTD (DOCTYPE) for the document.
*
* @param sName the DTD public identifier
*/
public void setDtdName(String sName)
{
checkMutable();
if (sName != null && sName.length() == 0)
{
sName = null;
}
if (sName != null && !XmlHelper.isPublicIdentifierValid(sName))
{
throw new IllegalArgumentException(
"illegal xml dtd public id: " + sName);
}
m_sDtdName = sName;
}
/**
* Get the encoding string for the XML document. Documents that are parsed
* may or may not have the encoding string from the persistent form of the
* document.
*
* @return the encoding set for the document
*/
public String getEncoding()
{
return m_sEncoding;
}
/**
* Set the encoding string for the XML document.
*
* @param sEncoding the encoding that the document will use
*/
public void setEncoding(String sEncoding)
{
checkMutable();
if (sEncoding != null && sEncoding.length() == 0)
{
sEncoding = null;
}
if (sEncoding != null && !XmlHelper.isEncodingValid(sEncoding))
{
throw new IllegalArgumentException(
"illegal xml document encoding: " + sEncoding);
}
m_sEncoding = sEncoding;
}
/**
* Get the XML comment that appears outside of the root element. This
* differs from the Comment property of this object, which refers to
* the comment within the root element.
*
* @return the document comment
*/
public String getDocumentComment()
{
return m_sComment;
}
/**
* Set the XML comment that appears outside of the root element. This
* differs from the Comment property of this object, which refers to
* the comment within the root element.
*
* @param sComment the document comment
*/
public void setDocumentComment(String sComment)
{
checkMutable();
if (sComment != null && sComment.length() == 0)
{
sComment = null;
}
if (sComment != null && !XmlHelper.isCommentValid(sComment))
{
throw new IllegalArgumentException(
"illegal xml comment: " + sComment);
}
m_sComment = sComment;
}
/**
* Write the XML document, including an XML header and DOCTYPE if one
* exists. This overrides the contract of the XmlElement super interface.
*
* @param out a PrintWriter object to use to write to
* @param fPretty true to specify that the output is intended to be as
* human readable as possible
*/
public void writeXml(PrintWriter out, boolean fPretty)
{
String sDtdUri = getDtdUri();
String sDtdName = getDtdName();
String sEncoding = getEncoding();
String sComment = getDocumentComment();
out.print(" 0)
{
out.print(" encoding=" + XmlHelper.quote(sEncoding));
}
out.print("?>");
if (fPretty)
{
out.println();
}
if (sDtdUri != null && sDtdUri.length() > 0)
{
out.print(" 0)
{
out.print("PUBLIC");
if (fPretty)
{
out.println();
}
out.print(' ');
out.print(XmlHelper.quote(sDtdName));
}
else
{
out.print("SYSTEM");
}
if (fPretty)
{
out.println();
}
out.print(' ');
out.print(XmlHelper.quote(XmlHelper.encodeUri(sDtdUri)));
out.print('>');
if (fPretty)
{
out.println();
}
else
{
out.print(' ');
}
}
if (sComment != null && sComment.length() > 0)
{
out.print("");
if (fPretty)
{
out.println();
}
else
{
out.print(' ');
}
}
super.writeXml(out, fPretty);
if (fPretty)
{
out.println();
}
}
// ----- Object methods -------------------------------------------------
/**
* Provide a hash value for this XML document and all of its contained
* information. Note that this overrides the contract of the hashCode
* method in the super interface XmlElement. The hash value is defined
* as a xor of the following:
*
* - the hashCode from the root element
*
- the hashCode from the document type (uri and optional name)
*
* @return the hash value for this XML document
*/
public int hashCode()
{
int n = super.hashCode();
String sUri = getDtdUri();
if (sUri != null && sUri.length() > 0)
{
n ^= sUri.hashCode();
String sName = getDtdName();
if (sName != null && sName.length() > 0)
{
n ^= sName.hashCode();
}
}
return n;
}
/**
* Compare this XML document and all of its contained information with
* another XML document for equality. Note that this overrides the
* contract of the equals method in the super interface XmlElement.
*
* @return true if the documents are equal, false otherwise
*/
public boolean equals(Object o)
{
if (o instanceof XmlDocument)
{
XmlDocument that = (XmlDocument) o;
if (!super.equals(that))
{
return false;
}
return equals(this.getDtdUri() , that.getDtdUri() )
&& equals(this.getDtdName() , that.getDtdName() )
&& equals(this.getEncoding() , that.getEncoding() )
&& equals(this.getDocumentComment(), that.getDocumentComment());
}
return false;
}
/**
* Creates and returns a copy of this XmlDocument.
*
* @return a clone of this instance.
*/
public Object clone()
{
// there is no deep cloning that must be performed at this level
return super.clone();
}
// ----- Externalizable interface ---------------------------------------
/**
* The object implements the writeExternal method to save its contents
* by calling the methods of DataOutput for its primitive values or
* calling the writeObject method of ObjectOutput for objects, strings,
* and arrays.
*
* @param out the stream to write the object to
*
* @exception IOException Includes any I/O exceptions that may occur
*/
public void writeExternal(ObjectOutput out)
throws IOException
{
CharArrayWriter cw = new CharArrayWriter(1024);
PrintWriter pw = new PrintWriter(cw);
writeXml(pw, false);
pw.flush();
out.writeInt(cw.size());
cw.writeTo(new Utf8Writer((OutputStream) out));
}
/**
* The object implements the readExternal method to restore its
* contents by calling the methods of DataInput for primitive
* types and readObject for objects, strings and arrays. The
* readExternal method must read the values in the same sequence
* and with the same types as were written by writeExternal.
*
* @param in the stream to read data from in order to restore the object
*
* @exception IOException if I/O errors occur
* @exception ClassNotFoundException If the class for an object being
* restored cannot be found.
*/
public void readExternal(ObjectInput in)
throws IOException, ClassNotFoundException
{
char[] ach = readCharArray(in);
// Bug 31045382 - Do not validate the XML to prevent XXE (XML eXternal Entity) injection
XmlHelper.loadXml(new String(ach), this, /* fValidate */ false);
}
// ----- ExternalizableLite interface -----------------------------------
/**
* {@inheritDoc}
*/
public void readExternal(DataInput in)
throws IOException
{
if (m_sDtdUri != null || m_sDtdName != null || m_sEncoding != null || m_sComment != null)
{
throw new NotActiveException();
}
super.readExternal(in);
if (in.readBoolean())
{
m_sDtdUri = readUTF(in);
}
if (in.readBoolean())
{
m_sDtdName = readUTF(in);
}
if (in.readBoolean())
{
m_sEncoding = readUTF(in);
}
if (in.readBoolean())
{
m_sComment = readUTF(in);
}
}
/**
* {@inheritDoc}
*/
public void writeExternal(DataOutput out)
throws IOException
{
super.writeExternal(out);
String sDtdUri = m_sDtdUri;
String sDtdName = m_sDtdName;
String sEncoding = m_sEncoding;
String sComment = m_sComment;
boolean fDtdUri = sDtdUri != null;
boolean fDtdName = sDtdName != null;
boolean fEncoding = sEncoding != null;
boolean fComment = sComment != null;
out.writeBoolean(fDtdUri);
if (fDtdUri)
{
writeUTF(out, m_sDtdUri);
}
out.writeBoolean(fDtdName);
if (fDtdName)
{
writeUTF(out, m_sDtdName);
}
out.writeBoolean(fEncoding);
if (fEncoding)
{
writeUTF(out, m_sEncoding);
}
out.writeBoolean(fComment);
if (fComment)
{
writeUTF(out, m_sComment);
}
}
// ----- PortableObject interface --------------------------------------
/**
* {@inheritDoc}
*/
public void readExternal(PofReader in)
throws IOException
{
if (m_sDtdUri != null || m_sDtdName != null || m_sEncoding != null || m_sComment != null)
{
throw new NotActiveException();
}
super.readExternal(in);
if (in.readBoolean(12))
{
m_sDtdUri = in.readString(13);
}
if (in.readBoolean(14))
{
m_sDtdName = in.readString(15);
}
if (in.readBoolean(16))
{
m_sEncoding = in.readString(17);
}
if (in.readBoolean(18))
{
m_sComment = in.readString(19);
}
}
/**
* {@inheritDoc}
*/
public void writeExternal(PofWriter out)
throws IOException
{
super.writeExternal(out);
String sDtdUri = m_sDtdUri;
String sDtdName = m_sDtdName;
String sEncoding = m_sEncoding;
String sComment = m_sComment;
boolean fDtdUri = sDtdUri != null;
boolean fDtdName = sDtdName != null;
boolean fEncoding = sEncoding != null;
boolean fComment = sComment != null;
out.writeBoolean(12, fDtdUri);
if (fDtdUri)
{
out.writeString(13, m_sDtdUri);
}
out.writeBoolean(14, fDtdName);
if (fDtdName)
{
out.writeString(15, m_sDtdName);
}
out.writeBoolean(16, fEncoding);
if (fEncoding)
{
out.writeString(17, m_sEncoding);
}
out.writeBoolean(18, fComment);
if (fComment)
{
out.writeString(19, m_sComment);
}
}
// ----- XmlSerializable interface --------------------------------------
/**
* Serialize the object into an XmlElement.
*
* @return an XmlElement that contains the serialized form of the object
*/
public XmlElement toXml()
{
return super.toXml();
}
/**
* Deserialize the object from an XmlElement.
*
* This method can throw one of several RuntimeExceptions.
*
* @param xml an XmlElement that contains the serialized form of the
* object
*
* @throws UnsupportedOperationException if this element is immutable
*/
public void fromXml(XmlElement xml)
{
super.fromXml(xml);
if (xml instanceof XmlDocument)
{
XmlDocument xmlDoc = (XmlDocument) xml;
m_sDtdUri = xmlDoc.getDtdUri();
m_sDtdName = xmlDoc.getDtdName();
m_sEncoding = xmlDoc.getEncoding();
m_sComment = xmlDoc.getComment();
}
}
// ----- helpers --------------------------------------------------------
/**
* Validates that the document is mutable, otherwise throws an
* UnsupportedOperationException.
*
* @exception UnsupportedOperationException if the document is immutable
*/
protected void checkMutable()
{
if (!isMutable())
{
throw new UnsupportedOperationException(
"document \"" + getName() + "\" is not mutable");
}
}
// ----- data members ---------------------------------------------------
private String m_sDtdUri;
private String m_sDtdName;
private String m_sEncoding;
private String m_sComment;
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy