blob: 4578cf43099a536f1a1aa127379c3d9a6d66b5a0 [file] [log] [blame]
//
// ========================================================================
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.xml;
import java.io.Closeable;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.Map;
import java.util.Stack;
import org.eclipse.jetty.util.StringUtil;
public class XmlAppendable
{
private final String SPACES=" ";
private final Appendable _out;
private final int _indent;
private final Stack<String> _tags = new Stack<>();
private String _space="";
public XmlAppendable(OutputStream out,String encoding) throws IOException
{
this(new OutputStreamWriter(out,encoding),encoding);
}
public XmlAppendable(Appendable out) throws IOException
{
this(out,2);
}
public XmlAppendable(Appendable out,String encoding) throws IOException
{
this(out,2,encoding);
}
public XmlAppendable(Appendable out, int indent) throws IOException
{
this(out,indent,"utf-8");
}
public XmlAppendable(Appendable out, int indent, String encoding) throws IOException
{
_out=out;
_indent=indent;
_out.append("<?xml version=\"1.0\" encoding=\""+encoding+"\"?>\n");
}
public XmlAppendable openTag(String tag, Map<String,String> attributes) throws IOException
{
_out.append(_space).append('<').append(tag);
attributes(attributes);
_out.append(">\n");
_space=_space+SPACES.substring(0,_indent);
_tags.push(tag);
return this;
}
public XmlAppendable openTag(String tag) throws IOException
{
_out.append(_space).append('<').append(tag).append(">\n");
_space=_space+SPACES.substring(0,_indent);
_tags.push(tag);
return this;
}
public XmlAppendable content(String s) throws IOException
{
if (s!=null)
_out.append(StringUtil.sanitizeXmlString(s));
return this;
}
public XmlAppendable cdata(String s) throws IOException
{
_out.append("<![CDATA[").append(s).append("]]>");
return this;
}
public XmlAppendable tag(String tag) throws IOException
{
_out.append(_space).append('<').append(tag).append("/>\n");
return this;
}
public XmlAppendable tag(String tag, Map<String,String> attributes) throws IOException
{
_out.append(_space).append('<').append(tag);
attributes(attributes);
_out.append("/>\n");
return this;
}
public XmlAppendable tag(String tag,String content) throws IOException
{
_out.append(_space).append('<').append(tag).append('>');
content(content);
_out.append("</").append(tag).append(">\n");
return this;
}
public XmlAppendable tagCDATA(String tag,String data) throws IOException
{
_out.append(_space).append('<').append(tag).append('>');
cdata(data);
_out.append("</").append(tag).append(">\n");
return this;
}
public XmlAppendable tag(String tag, Map<String,String> attributes,String content) throws IOException
{
_out.append(_space).append('<').append(tag);
attributes(attributes);
_out.append('>');
content(content);
_out.append("</").append(tag).append(">\n");
return this;
}
public XmlAppendable closeTag() throws IOException
{
if (_tags.isEmpty())
throw new IllegalStateException("Tags closed");
String tag=_tags.pop();
_space=_space.substring(0,_space.length()-_indent);
_out.append(_space).append("</").append(tag).append(">\n");
if (_tags.isEmpty() && _out instanceof Closeable)
((Closeable)_out).close();
return this;
}
private void attributes(Map<String,String> attributes) throws IOException
{
for (String k:attributes.keySet())
{
String v = attributes.get(k);
_out.append(' ').append(k).append("=\"");
content(v);
_out.append('"');
}
}
public void literal(String xml) throws IOException
{
_out.append(xml);
}
}