
org.xmlpull.v1.wrapper.classic.StaticXmlSerializerWrapper Maven / Gradle / Ivy
The newest version!
/* -*- c-basic-offset: 4; indent-tabs-mode: nil; -*- //------100-columns-wide------>|*/
// for license please see accompanying LICENSE.txt file (available also at http://www.xmlpull.org/)
package org.xmlpull.v1.wrapper.classic;
import java.io.IOException;
import java.io.StringReader;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;
import org.xmlpull.v1.wrapper.XmlPullParserWrapper;
import org.xmlpull.v1.wrapper.XmlPullWrapperFactory;
import org.xmlpull.v1.wrapper.XmlSerializerWrapper;
/**
* This class seemlesly extends exisiting serialzier implementation by adding new methods
* (provided by XmlPullUtil) and delegating exisiting methods to parser implementation.
*
* @author Aleksander Slominski
* @author Naresh Bhatia
*/
public class StaticXmlSerializerWrapper extends XmlSerializerDelegate
implements XmlSerializerWrapper
{
private final static String PROPERTY_XMLDECL_STANDALONE =
"http://xmlpull.org/v1/doc/features.html#xmldecl-standalone";
private static final boolean TRACE_SIZING = false;
protected String currentNs;
protected XmlPullWrapperFactory wf;
protected XmlPullParserWrapper fragmentParser;
public StaticXmlSerializerWrapper(XmlSerializer xs, XmlPullWrapperFactory wf) {
super(xs);
this.wf = wf;
}
public String getCurrentNamespaceForElements() { return currentNs; }
public String setCurrentNamespaceForElements(String value)
{
String old = currentNs;
currentNs = value;
return old;
}
public XmlSerializerWrapper attribute (String name, String value)
throws IOException, IllegalArgumentException, IllegalStateException
{
xs.attribute(null, name, value);
return this;
}
public XmlSerializerWrapper startTag (String name)
throws IOException, IllegalArgumentException, IllegalStateException
{
xs.startTag(currentNs, name);
return this;
}
public XmlSerializerWrapper endTag(String name)
throws IOException, IllegalArgumentException, IllegalStateException
{
endTag(currentNs, name);
return this;
}
/** Write simple text element in current namespace */
public XmlSerializerWrapper element(String elementName, String elementText)
throws IOException, XmlPullParserException
{
return element(currentNs, elementName, elementText);
}
public XmlSerializerWrapper element(String namespace, String elementName, String elementText)
throws IOException, XmlPullParserException
{
if (elementName == null) {
throw new XmlPullParserException("name for element can not be null");
}
xs.startTag(namespace, elementName);
if (elementText == null) {
xs.attribute(XSI_NS, "nil", "true");
}
else {
xs.text(elementText);
}
xs.endTag(namespace, elementName);
return this;
}
//namespace stack
//protected int elNamespaceCount[] = new int[ 2 ];
//protected int currentDepth = -1;
protected int namespaceEnd = 0;
protected String namespacePrefix[] = new String[ 8 ];
protected String namespaceUri[] = new String[ namespacePrefix.length ];
protected int namespaceDepth[] = new int[ namespacePrefix.length ];
private void ensureNamespacesCapacity() {
int newSize = namespaceEnd > 7 ? 2 * namespaceEnd : 8;
if(TRACE_SIZING) {
System.err.println(
getClass().getName()+" namespaceSize "+namespacePrefix.length+" ==> "+newSize);
}
String[] newNamespacePrefix = new String[newSize];
String[] newNamespaceUri = new String[newSize];
int[] newNamespaceDepth = new int[newSize];
if(namespacePrefix != null) {
System.arraycopy(namespacePrefix, 0, newNamespacePrefix, 0, namespaceEnd);
System.arraycopy(namespaceUri, 0, newNamespaceUri, 0, namespaceEnd);
System.arraycopy(namespaceDepth, 0, newNamespaceDepth, 0, namespaceEnd);
}
namespacePrefix = newNamespacePrefix;
namespaceUri = newNamespaceUri;
namespaceDepth = newNamespaceDepth;
}
// public XmlSerializer endTag(String namespace, String name) throws IOException
// {
// xs.endTag(currentNs, name);
// namespaceEnd = elNamespaceCount[ getDepth() ];
// return this;
// }
public void setPrefix(String prefix, String namespace)
throws IOException, IllegalArgumentException, IllegalStateException
{
xs.setPrefix(prefix, namespace);
int depth = getDepth();
for(int pos = namespaceEnd - 1; pos >= 0; --pos) {
if(namespaceDepth[ pos ] <= depth) {
break;
}
--namespaceEnd;
}
if(namespaceEnd >= namespacePrefix.length) {
ensureNamespacesCapacity();
}
namespacePrefix[ namespaceEnd ] = prefix;
namespaceUri[ namespaceEnd ] = namespace;
++namespaceEnd;
}
public void fragment(String xmlFragment)
throws IOException, IllegalArgumentException, IllegalStateException, XmlPullParserException
{
StringBuffer buf = new StringBuffer(xmlFragment.length() + namespaceEnd * 30);
buf.append("= 0; --pos) {
String prefix = namespacePrefix[ pos ];
for(int i = namespaceEnd - 1; i > pos; --i) {
if(prefix.equals( namespacePrefix[i] )) {
continue LOOP;
}
}
buf.append(" xmlns");
if(prefix.length() > 0) {
buf.append(':').append(prefix);
}
buf.append("='");
buf.append(escapeAttributeValue(namespaceUri[ pos ]));
buf.append("'");
}
buf.append(">");
buf.append(xmlFragment);
buf.append(" ");
if(fragmentParser == null) {
fragmentParser = wf.newPullParserWrapper();
}
String s = buf.toString();
//System.err.println(getClass().getName()+" fragment XML="+s);
fragmentParser.setInput(new StringReader( s ) );
fragmentParser.nextTag();
fragmentParser.require(XmlPullParser.START_TAG, null, "fragment");
while(true) {
fragmentParser.nextToken();
if(fragmentParser.getDepth() == 1
&& fragmentParser.getEventType() == XmlPullParser.END_TAG)
{
break;
}
event(fragmentParser);
}
fragmentParser.require(XmlPullParser.END_TAG, null, "fragment");
}
public void event(XmlPullParser pp) throws XmlPullParserException, IOException {
int eventType = pp.getEventType();
switch (eventType) {
case XmlPullParser.START_DOCUMENT:
//use Boolean.TRUE to make it standalone
Boolean standalone = (Boolean) pp.getProperty(PROPERTY_XMLDECL_STANDALONE);
startDocument(pp.getInputEncoding(), standalone);
break;
case XmlPullParser.END_DOCUMENT:
endDocument();
break;
case XmlPullParser.START_TAG:
writeStartTag(pp);
break;
case XmlPullParser.END_TAG:
endTag(pp.getNamespace (), pp.getName ());
break;
case XmlPullParser.IGNORABLE_WHITESPACE:
//comment it to remove ignorable whtespaces from XML infoset
String s = pp.getText ();
ignorableWhitespace(s);
break;
case XmlPullParser.TEXT:
if(pp.getDepth() > 0) {
text(pp.getText ());
} else {
ignorableWhitespace(pp.getText ());
}
break;
case XmlPullParser.ENTITY_REF:
entityRef (pp.getName ());
break;
case XmlPullParser.CDSECT:
cdsect( pp.getText () );
break;
case XmlPullParser.PROCESSING_INSTRUCTION:
processingInstruction( pp.getText ());
break;
case XmlPullParser.COMMENT:
comment (pp.getText ());
break;
case XmlPullParser.DOCDECL:
docdecl (pp.getText ());
break;
}
}
private void writeStartTag(XmlPullParser pp) throws XmlPullParserException, IOException {
if (!pp.getFeature (XmlPullParser.FEATURE_REPORT_NAMESPACE_ATTRIBUTES)) {
int nsStart = pp.getNamespaceCount(pp.getDepth()-1);
int nsEnd = pp.getNamespaceCount(pp.getDepth());
for (int i = nsStart; i < nsEnd; i++) {
String prefix = pp.getNamespacePrefix(i);
String ns = pp.getNamespaceUri(i);
setPrefix(prefix, ns);
}
}
startTag(pp.getNamespace(), pp.getName());
for (int i = 0; i < pp.getAttributeCount(); i++) {
attribute
(pp.getAttributeNamespace (i),
pp.getAttributeName (i),
pp.getAttributeValue (i));
}
//ser.closeStartTag();
}
public String escapeAttributeValue(String value)
//protected void writeAttributeValue(String value, Writer out) throws IOException
{
int posLt = value.indexOf('<');
int posAmp = value.indexOf('&');
int posQuot = value.indexOf('"');
int posApos = value.indexOf('\'');
if(posLt == -1 && posAmp == -1 && posQuot == -1 && posApos == -1) {
return value;
}
StringBuffer buf = new StringBuffer(value.length() + 10);
// painful loop ...
for(int pos = 0, len = value.length(); pos < len; ++pos) {
char ch = value.charAt(pos);
switch(ch) {
case '<':
buf.append("<");
break;
case '&':
buf.append("&");
break;
case '\'':
buf.append("'");
break;
case '"':
buf.append(""");
break;
default:
buf.append(ch);
}
}
return buf.toString();
}
//protected void writeElementContent(String text, Writer out) throws IOException
public String escapeText(String text)
{
//<, & esccaped]
//out.write(text);
int posLt = text.indexOf('<');
int posAmp = text.indexOf('&');
if(posLt == -1 && posAmp == -1) { // this is shortcut
return text;
}
StringBuffer buf = new StringBuffer(text.length() + 10);
// painful loop ...
int pos = 0;
while(true) {
if(posLt == -1 && posAmp == -1) { // this is shortcut
buf.append(text.substring(pos));
break;
} else if(posLt == -1
|| (posLt != -1 && posAmp != -1 && posAmp < posLt))
{
if(pos < posAmp) buf.append(text.substring(pos, posAmp));
buf.append("&");
pos = posAmp + 1;
posAmp = text.indexOf('&', pos);
} else if(posAmp == -1
|| (posLt != -1 && posAmp != -1 && posLt < posAmp))
{
if(pos < posLt) buf.append(text.substring(pos, posLt));
buf.append("<");
pos = posLt + 1;
posLt = text.indexOf('<', pos);
} else {
throw new IllegalStateException("wrong state posLt="+posLt
+" posAmp="+posAmp+" for "+text);
}
}
return buf.toString();
}
public void writeDouble(double d)
throws XmlPullParserException, IOException, IllegalArgumentException
{
if(d == Double.POSITIVE_INFINITY) {
xs.text("INF");
} else if(d == Double.NEGATIVE_INFINITY) {
xs.text("-INF");
} else {
xs.text(Double.toString(d));
}
}
public void writeFloat(float f)
throws XmlPullParserException, IOException, IllegalArgumentException
{
if(f == Float.POSITIVE_INFINITY) {
xs.text("INF");
} else if(f == Float.NEGATIVE_INFINITY) {
xs.text("-INF");
} else {
xs.text(Float.toString(f));
}
}
public void writeInt(int i)
throws XmlPullParserException, IOException, IllegalArgumentException
{
xs.text(Integer.toString(i));
}
public void writeString(String s)
throws XmlPullParserException, IOException, IllegalArgumentException
{
if( s == null ) {
throw new IllegalArgumentException("null string can not be written");
}
xs.text(s);
}
public void writeDoubleElement(String namespace, String name, double d)
throws XmlPullParserException, IOException, IllegalArgumentException
{
xs.startTag(namespace, name);
writeDouble(d);
xs.endTag(namespace, name);
}
public void writeFloatElement(String namespace, String name, float f)
throws XmlPullParserException, IOException, IllegalArgumentException
{
xs.startTag(namespace, name);
writeFloat(f);
xs.endTag(namespace, name);
}
public void writeIntElement(String namespace, String name, int i)
throws XmlPullParserException, IOException, IllegalArgumentException
{
xs.startTag(namespace, name);
writeInt(i);
xs.endTag(namespace, name);
}
public void writeStringElement(String namespace, String name, String s)
throws XmlPullParserException, IOException, IllegalArgumentException
{
xs.startTag(namespace, name);
if(s == null) {
xs.attribute(XSD_NS, "nil", "true");
} else {
writeString(s);
}
xs.endTag(namespace, name);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy