io.milton.http.XmlWriter Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of milton-server-ce Show documentation
Show all versions of milton-server-ce Show documentation
Milton Community Edition: Supports DAV level 1 and is available on Apache2 license
The newest version!
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package io.milton.http;
import java.io.IOException;
import java.io.OutputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.nio.charset.Charset;
/**
* Lightweight XML generation. Gives the programmer fine grained control of the
* generated xml, including whitespace.
*
* The XML is not guaranteed to be parseable.
*
* @author brad
*/
public class XmlWriter {
private Logger log = LoggerFactory.getLogger(XmlWriter.class);
public static Charset utf8() {
return Charset.forName("UTF-8");
}
public enum Type {
OPENING,
CLOSING,
NO_CONTENT
}
private boolean allowNewlines = false;
protected final OutputStream out;
protected final Charset charset;
public XmlWriter(OutputStream out, Charset charset) {
this.out = out;
this.charset = charset;
}
public XmlWriter(OutputStream out) {
this.out = out;
this.charset = XmlWriter.utf8();
}
/**
* Append the given raw String to the ouput. No encoding is applied
*
* @param value
*/
private void append(String value) {
try {
byte[] arr = value.getBytes(charset);
out.write(arr);
} catch (IOException ex) {
throw new RuntimeException(ex);
}
}
/**
* Append the given character to the output. No encoding is applied
*
* @param c
*/
private void append(char c) {
try {
out.write(c);
} catch (IOException ex) {
throw new RuntimeException(ex);
}
}
/**
* Convenience method to write a single element containing a piece of text
*
*
* @param namespace - optional, namespace prefix
* @param namespaceInfo - optional, namespace url
* @param name - the local name of the element to create
* @param value - the raw text to insert into the element
*/
public void writeProperty(String namespace, String namespaceInfo, String name, String value) {
writeElement(namespace, namespaceInfo, name, Type.OPENING);
append(value);
writeElement(namespace, namespaceInfo, name, Type.CLOSING);
}
public void writeProperty(String namespace, String name, String value) {
if (value == null) {
writeProperty(namespace, name);
} else {
writeElement(namespace, name, Type.OPENING);
append(value);
writeElement(namespace, name, Type.CLOSING);
}
}
public void writeProperty(String namespace, String name) {
writeElement(namespace, name, Type.NO_CONTENT);
}
public void writeProperty(String name) {
writeElement(null, name, Type.NO_CONTENT);
}
public void writeElement(String namespace, String name, Type type) {
writeElement(namespace, null, name, type);
}
/**
* Write an opening tag
*
* @param namespace
* @param name
*/
public void open(String namespace, String name) {
writeElement(namespace, name, Type.OPENING);
}
/**
* Write a closing tag, Eg
*
* @param namespace
* @param name
*/
public void close(String namespace, String name) {
writeElement(namespace, name, Type.CLOSING);
}
/**
* Write an opening tag
*
* @param name
*/
public void open(String name) {
writeElement(null, name, Type.OPENING);
}
/**
* Write a closing tag for the given name
*
* @param name
*/
public void close(String name) {
writeElement(null, name, Type.CLOSING);
}
/**
* Represents an element which is currently being written
*
*/
public class Element {
private final Element parent;
private final String nsPrefix;
private final String name;
private boolean openEnded;
/**
* Create the element and write the first part of the opening tag
*
* Eg
*
* @return
*/
public Element open() {
return open(true);
}
public Element open(boolean newline) {
openEnded = true;
append(">");
if (newline) {
newLine();
}
return this;
}
/**
* Closes the tag by determining its current state. Can close with a
* no-content tag if no content has been written, or with write
* a close tag
*
* @return - the parent element
*/
public Element close() {
return close(false);
}
public Element close(boolean newline) {
if (openEnded) {
if (nsPrefix != null) {
append("" + nsPrefix + ":" + name + ">");
newLine();
} else {
append("" + name + ">");
newLine();
}
if (newline) {
newLine();
}
return parent;
} else {
if (newline) {
newLine();
}
return noContent();
}
}
/**
* Write a self closing tag, eg />
*
* @return - the parent element
*/
public Element noContent() {
append("/>");
newLine();
return parent;
}
public Element noContent(boolean newLine) {
append("/>");
if (newLine) {
newLine();
}
return parent;
}
/**
* Start a new element, completing the open tag if required
*
* @param name
* @return
*/
public Element begin(String name) {
return begin(null, name);
}
public Element begin(String prefix, String name) {
return begin(prefix, name, true);
}
public Element begin(String prefix, String name, boolean newLine) {
if (!openEnded) {
open(newLine);
}
return new Element(this, prefix, name);
}
public Element begin(String uri, String prefix, String name) {
if (!openEnded) {
open();
}
return new Element(this, uri, prefix, name);
}
/**
* Write a property element like - value
*
* @param name
* @param value
* @return
*/
public Element prop(String name, String value) {
begin(name).writeText(value, false).close(true);
return this;
}
public Element prop(String name, Integer value) {
if (value != null) {
prop(name, value.toString());
} else {
begin(name).noContent();
}
return this;
}
}
public Element begin(String name) {
return new Element(null, name);
}
public Element begin(String nsPrefix, String name) {
return new Element(null, nsPrefix, name);
}
public void writeElement(String nsPrefix, String nsUrl, String name, Type type) {
if ((nsPrefix != null) && (nsPrefix.length() > 0)) {
switch (type) {
case OPENING:
if (nsUrl != null) {
append("<" + nsPrefix + ":" + name + " xmlns:" + nsPrefix + "=\"" + nsUrl + "\">");
} else {
append("<" + nsPrefix + ":" + name + ">");
}
break;
case CLOSING:
append("" + nsPrefix + ":" + name + ">");
newLine();
break;
case NO_CONTENT:
default:
if (nsUrl != null) {
append("<" + nsPrefix + ":" + name + " xmlns:" + nsPrefix + "=\"" + nsUrl + "\"/>");
} else {
append("<" + nsPrefix + ":" + name + "/>");
}
break;
}
} else {
switch (type) {
case OPENING:
append("<" + name + ">");
break;
case CLOSING:
append("" + name + ">\n");
break;
case NO_CONTENT:
default:
append("<" + name + "/>");
break;
}
}
}
/**
* Append plain text.
*
* @param text Text to append
*/
public void writeText(String text) {
append(text);
}
/**
* Write a CDATA segment.
*
* @param data Data to append
*/
public void writeData(String data) {
append("");
}
public void writeXMLHeader() {
append("\n");
}
/**
* Send data and reinitializes buffer.
*/
public void flush() {
try {
out.flush();
} catch (IOException ex) {
throw new RuntimeException(ex);
}
}
public void newLine() {
if (allowNewlines) {
append("\n");
}
}
public boolean isAllowNewlines() {
return allowNewlines;
}
public void setAllowNewlines(boolean allowNewlines) {
this.allowNewlines = allowNewlines;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy