// **********************************************************************
//
// Copyright (c) 2003-2010 ZeroC, Inc. All rights reserved.
//
// This copy of Ice is licensed to you under the terms described in the
// ICE_LICENSE file included in this distribution.
//
// **********************************************************************
package IceUtilInternal;
public class XMLOutput extends OutputBase
{
public
XMLOutput()
{
super();
_se = false;
_text = false;
_sgml = false;
_escape = false;
}
public
XMLOutput(java.io.PrintWriter writer)
{
super(writer);
_se = false;
_text = false;
_sgml = false;
_escape = false;
}
public
XMLOutput(String s)
{
super(s);
_se = false;
_text = false;
_sgml = false;
_escape = false;
}
public void
setSGML(boolean sgml)
{
_sgml = true;
}
public void
print(String s)
{
if(_se)
{
_out.print('>');
_se = false;
}
_text = true;
if(_escape)
{
String escaped = escape(s);
super.print(escaped);
}
else
{
super.print(s);
}
}
public XMLOutput
write(String s)
{
print(s);
return this;
}
public void
nl()
{
if(_se)
{
_se = false;
_out.print('>');
}
super.nl();
}
public XMLOutput
se(String element)
{
nl();
//
// If we're not in SGML mode the output of the '>' character is
// deferred until either the end-element (in which case a /> is
// emitted) or until something is displayed.
//
if(_escape)
{
_out.print('<');
_out.print(escape(element));
}
else
{
_out.print('<');
_out.print(element);
}
_se = true;
_text = false;
int pos = element.indexOf(' ');
if(pos == -1)
{
pos = element.indexOf('\t');
}
if(pos == -1)
{
_elementStack.addFirst(element);
}
else
{
_elementStack.addFirst(element.substring(0, pos));
}
++_pos; // TODO: ???
inc();
_separator = false;
return this;
}
public XMLOutput
ee()
{
String element = _elementStack.removeFirst();
dec();
if(_se)
{
//
// SGML (docbook) doesn't support <foo/>
//
if(_sgml)
{
_out.print("></");
_out.print(element);
_out.print(">");
}
else
{
_out.print("/>");
}
}
else
{
if(!_text)
{
nl();
}
_out.print("</");
_out.print(element);
_out.print(">");
}
--_pos; // TODO: ???
_se = false;
_text = false;
return this;
}
public XMLOutput
attr(String name, String value)
{
//
// Precondition: Attributes can only be attached to elements.
//
assert(_se);
_out.print(" ");
_out.print(name);
_out.print("=\"");
_out.print(escape(value));
_out.print("\"");
return this;
}
public XMLOutput
startEscapes()
{
_escape = true;
return this;
}
public XMLOutput
endEscapes()
{
_escape = false;
return this;
}
public String
currentElement()
{
if(_elementStack.size() > 0)
{
return _elementStack.getFirst();
}
else
{
return "";
}
}
private String
escape(String input)
{
String v = input;
//
// Find out whether there is a reserved character to avoid
// conversion if not necessary.
//
final String allReserved = "<>'\"&";
boolean hasReserved = false;
char[] arr = input.toCharArray();
for(int i = 0; i < arr.length; i++)
{
if(allReserved.indexOf(arr[i]) != -1)
{
hasReserved = true;
break;
}
}
if(hasReserved)
{
//
// First convert all & to &
//
if(v.indexOf('&') != -1)
{
v = v.replaceAll("&", "&");
}
//
// Next convert remaining reserved characters.
//
if(v.indexOf('>') != -1)
{
v = v.replaceAll(">", ">");
}
if(v.indexOf('<') != -1)
{
v = v.replaceAll("<", "<");
}
if(v.indexOf('\'') != -1)
{
v = v.replaceAll("'", "'");
}
if(v.indexOf('"') != -1)
{
v = v.replaceAll("\"", """);
}
}
return v;
}
private java.util.LinkedList<String> _elementStack = new java.util.LinkedList<String>();
boolean _se;
boolean _text;
private boolean _sgml;
private boolean _escape;
}