org.jfree.xml.writer.XMLWriterSupport Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jtstand-common Show documentation
Show all versions of jtstand-common Show documentation
jtstand-common is a library derived from jcommon, used by jtstand-chart, which is derived from jfreechart
/*
* Copyright (c) 2009 Albert Kurucz.
*
* This file, XMLWriterSupport.java is part of JTStand.
*
* JTStand is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* JTStand is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with GTStand. If not, see .
*/
package org.jfree.xml.writer;
import java.io.IOException;
import java.io.Writer;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Properties;
/**
* A support class for writing XML files.
*
* @author Thomas Morgner
*/
public class XMLWriterSupport {
/** A constant for controlling the indent function. */
public static final int OPEN_TAG_INCREASE = 1;
/** A constant for controlling the indent function. */
public static final int CLOSE_TAG_DECREASE = 2;
/** A constant for controlling the indent function. */
public static final int INDENT_ONLY = 3;
/** A constant for close. */
public static final boolean CLOSE = true;
/** A constant for open. */
public static final boolean OPEN = false;
/** The line separator. */
private static String lineSeparator;
/** A list of safe tags. */
private SafeTagList safeTags;
/** The indent level for that writer. */
private int indentLevel;
/** The indent string. */
private String indentString;
/**
* A flag indicating whether to force a linebreak before printing the next
* tag.
*/
private boolean newLineOk;
/**
* Default Constructor. The created XMLWriterSupport will not have no safe
* tags and starts with an indention level of 0.
*/
public XMLWriterSupport() {
this(new SafeTagList(), 0);
}
/**
* Creates a new support instance.
*
* @param safeTags tags that are safe for line breaks.
* @param indentLevel the index level.
*/
public XMLWriterSupport(final SafeTagList safeTags, final int indentLevel) {
this(safeTags, indentLevel, " ");
}
/**
* Creates a new support instance.
*
* @param safeTags the tags that are safe for line breaks.
* @param indentLevel the indent level.
* @param indentString the indent string.
*/
public XMLWriterSupport(final SafeTagList safeTags, final int indentLevel,
final String indentString) {
if (indentString == null) {
throw new NullPointerException("IndentString must not be null");
}
this.safeTags = safeTags;
this.indentLevel = indentLevel;
this.indentString = indentString;
}
/**
* Starts a new block by increasing the indent level.
*
* @throws IOException if an IO error occurs.
*/
public void startBlock() throws IOException {
this.indentLevel++;
allowLineBreak();
}
/**
* Ends the current block by decreasing the indent level.
*
* @throws IOException if an IO error occurs.
*/
public void endBlock() throws IOException {
this.indentLevel--;
allowLineBreak();
}
/**
* Forces a linebreak on the next call to writeTag or writeCloseTag.
*
* @throws IOException if an IO error occurs.
*/
public void allowLineBreak() throws IOException {
this.newLineOk = true;
}
/**
* Returns the line separator.
*
* @return the line separator.
*/
public static String getLineSeparator() {
if (lineSeparator == null) {
try {
lineSeparator = System.getProperty("line.separator", "\n");
}
catch (SecurityException se) {
lineSeparator = "\n";
}
}
return lineSeparator;
}
/**
* Writes an opening XML tag that has no attributes.
*
* @param w the writer.
* @param name the tag name.
*
* @throws java.io.IOException if there is an I/O problem.
*/
public void writeTag(final Writer w, final String name) throws IOException {
if (this.newLineOk) {
w.write(getLineSeparator());
}
indent(w, OPEN_TAG_INCREASE);
w.write("<");
w.write(name);
w.write(">");
if (getSafeTags().isSafeForOpen(name)) {
w.write(getLineSeparator());
}
}
/**
* Writes a closing XML tag.
*
* @param w the writer.
* @param tag the tag name.
*
* @throws java.io.IOException if there is an I/O problem.
*/
public void writeCloseTag(final Writer w, final String tag)
throws IOException {
// check whether the tag contains CData - we ma not indent such tags
if (this.newLineOk || getSafeTags().isSafeForOpen(tag)) {
if (this.newLineOk) {
w.write(getLineSeparator());
}
indent(w, CLOSE_TAG_DECREASE);
}
else {
decreaseIndent();
}
w.write("");
w.write(tag);
w.write(">");
if (getSafeTags().isSafeForClose(tag)) {
w.write(getLineSeparator());
}
this.newLineOk = false;
}
/**
* Writes an opening XML tag with an attribute/value pair.
*
* @param w the writer.
* @param name the tag name.
* @param attributeName the attribute name.
* @param attributeValue the attribute value.
* @param close controls whether the tag is closed.
*
* @throws java.io.IOException if there is an I/O problem.
*/
public void writeTag(final Writer w, final String name,
final String attributeName, final String attributeValue,
final boolean close) throws IOException {
final AttributeList attr = new AttributeList();
if (attributeName != null) {
attr.setAttribute(attributeName, attributeValue);
}
writeTag(w, name, attr, close);
}
/**
* Writes an opening XML tag along with a list of attribute/value pairs.
*
* @param w the writer.
* @param name the tag name.
* @param attributes the attributes.
* @param close controls whether the tag is closed.
*
* @throws java.io.IOException if there is an I/O problem.
* @deprecated use the attribute list instead of the properties.
*/
public void writeTag(final Writer w, final String name,
final Properties attributes, final boolean close)
throws IOException {
final AttributeList attList = new AttributeList();
final Enumeration keys = attributes.keys();
while (keys.hasMoreElements()) {
final String key = (String) keys.nextElement();
attList.setAttribute(key, attributes.getProperty(key));
}
writeTag(w, name, attList, close);
}
/**
* Writes an opening XML tag along with a list of attribute/value pairs.
*
* @param w the writer.
* @param name the tag name.
* @param attributes the attributes.
* @param close controls whether the tag is closed.
*
* @throws java.io.IOException if there is an I/O problem.
*/
public void writeTag(final Writer w, final String name,
final AttributeList attributes, final boolean close)
throws IOException {
if (this.newLineOk) {
w.write(getLineSeparator());
this.newLineOk = false;
}
indent(w, OPEN_TAG_INCREASE);
w.write("<");
w.write(name);
final Iterator keys = attributes.keys();
while (keys.hasNext()) {
final String key = (String) keys.next();
final String value = attributes.getAttribute(key);
w.write(" ");
w.write(key);
w.write("=\"");
w.write(normalize(value));
w.write("\"");
}
if (close) {
w.write("/>");
if (getSafeTags().isSafeForClose(name)) {
w.write(getLineSeparator());
}
decreaseIndent();
}
else {
w.write(">");
if (getSafeTags().isSafeForOpen(name)) {
w.write(getLineSeparator());
}
}
}
/**
* Normalises a string, replacing certain characters with their escape
* sequences so that the XML text is not corrupted.
*
* @param s the string.
*
* @return the normalised string.
*/
public static String normalize(final String s) {
if (s == null) {
return "";
}
final StringBuffer str = new StringBuffer();
final int len = s.length();
for (int i = 0; i < len; i++) {
final char ch = s.charAt(i);
switch (ch) {
case '<':
{
str.append("<");
break;
}
case '>':
{
str.append(">");
break;
}
case '&':
{
str.append("&");
break;
}
case '"':
{
str.append(""");
break;
}
case '\n':
{
if (i > 0) {
final char lastChar = str.charAt(str.length() - 1);
if (lastChar != '\r') {
str.append(getLineSeparator());
}
else {
str.append('\n');
}
}
else {
str.append(getLineSeparator());
}
break;
}
default :
{
str.append(ch);
}
}
}
return (str.toString());
}
/**
* Indent the line. Called for proper indenting in various places.
*
* @param writer the writer which should receive the indentention.
* @param increase the current indent level.
* @throws java.io.IOException if writing the stream failed.
*/
public void indent(final Writer writer, final int increase)
throws IOException {
if (increase == CLOSE_TAG_DECREASE) {
decreaseIndent();
}
for (int i = 0; i < this.indentLevel; i++) {
writer.write(this.indentString); // 4 spaces, we could also try tab,
// but I do not know whether this works
// with our XML edit pane
}
if (increase == OPEN_TAG_INCREASE) {
increaseIndent();
}
}
/**
* Returns the current indent level.
*
* @return the current indent level.
*/
public int getIndentLevel() {
return this.indentLevel;
}
/**
* Increases the indention by one level.
*/
protected void increaseIndent() {
this.indentLevel++;
}
/**
* Decreates the indention by one level.
*/
protected void decreaseIndent() {
this.indentLevel--;
}
/**
* Returns the list of safe tags.
*
* @return The list.
*/
public SafeTagList getSafeTags() {
return this.safeTags;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy