org.jfree.util.SortedConfigurationWriter Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jcommon Show documentation
Show all versions of jcommon Show documentation
JCommon is a free general purpose Java class library that is used in several projects at www.jfree.org, including JFreeChart and JFreeReport.
/* ========================================================================
* JCommon : a free general purpose class library for the Java(tm) platform
* ========================================================================
*
* (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
*
* Project Info: http://www.jfree.org/jcommon/index.html
*
* This library 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 2.1 of the License, or
* (at your option) any later version.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
* [Java is a trademark or registered trademark of Sun Microsystems, Inc.
* in the United States and other countries.]
*
* ------------------------------
* SortedConfigurationWriter.java
* ------------------------------
* (C)opyright 2003, 2004, by Thomas Morgner and Contributors.
*
* Original Author: Thomas Morgner;
* Contributor(s): -;
*
* $Id: SortedConfigurationWriter.java,v 1.4 2005/11/03 09:55:27 mungady Exp $
*
* Changes
* -------
*
*/
package org.jfree.util;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
/**
* Writes a Configuration
instance into a property file, where
* the keys are sorted by their name. Writing sorted keys make it easier for
* users to find and change properties in the file.
*
* @author Thomas Morgner
*/
public class SortedConfigurationWriter {
/**
* A constant defining that text should be escaped in a way
* which is suitable for property keys.
*/
private static final int ESCAPE_KEY = 0;
/**
* A constant defining that text should be escaped in a way
* which is suitable for property values.
*/
private static final int ESCAPE_VALUE = 1;
/**
* A constant defining that text should be escaped in a way
* which is suitable for property comments.
*/
private static final int ESCAPE_COMMENT = 2;
/** The system-dependent End-Of-Line separator. */
private static final String END_OF_LINE = StringUtils.getLineSeparator();
/**
* The default constructor, does nothing.
*/
public SortedConfigurationWriter() {
}
/**
* Returns a description for the given key. This implementation returns
* null to indicate that no description should be written. Subclasses can
* overwrite this method to provide comments for every key. These descriptions
* will be included as inline comments.
*
* @param key the key for which a description should be printed.
* @return the description or null if no description should be printed.
*/
protected String getDescription(final String key) {
return null;
}
/**
* Saves the given configuration into a file specified by the given
* filename.
*
* @param filename the filename
* @param config the configuration
* @throws IOException if an IOError occurs.
*/
public void save(final String filename, final Configuration config)
throws IOException {
save(new File(filename), config);
}
/**
* Saves the given configuration into a file specified by the given
* file object.
*
* @param file the target file
* @param config the configuration
* @throws IOException if an IOError occurs.
*/
public void save(final File file, final Configuration config)
throws IOException {
final BufferedOutputStream out =
new BufferedOutputStream(new FileOutputStream(file));
save(out, config);
out.close();
}
/**
* Writes the configuration into the given output stream.
*
* @param outStream the target output stream
* @param config the configuration
* @throws IOException if writing fails.
*/
public void save(final OutputStream outStream, final Configuration config)
throws IOException {
final ArrayList names = new ArrayList();
// clear all previously set configuration settings ...
final Iterator defaults = config.findPropertyKeys("");
while (defaults.hasNext()) {
final String key = (String) defaults.next();
names.add(key);
}
Collections.sort(names);
final OutputStreamWriter out =
new OutputStreamWriter(outStream, "iso-8859-1");
for (int i = 0; i < names.size(); i++) {
final String key = (String) names.get(i);
final String value = config.getConfigProperty(key);
final String description = getDescription(key);
if (description != null) {
writeDescription(description, out);
}
saveConvert(key, ESCAPE_KEY, out);
out.write("=");
saveConvert(value, ESCAPE_VALUE, out);
out.write(END_OF_LINE);
}
out.flush();
}
/**
* Writes a descriptive comment into the given print writer.
*
* @param text the text to be written. If it contains more than
* one line, every line will be prepended by the comment character.
* @param writer the writer that should receive the content.
* @throws IOException if writing fails
*/
private void writeDescription(final String text, final Writer writer)
throws IOException {
// check if empty content ... this case is easy ...
if (text.length() == 0) {
return;
}
writer.write("# ");
writer.write(END_OF_LINE);
final LineBreakIterator iterator = new LineBreakIterator(text);
while (iterator.hasNext()) {
writer.write("# ");
saveConvert((String) iterator.next(), ESCAPE_COMMENT, writer);
writer.write(END_OF_LINE);
}
}
/**
* Performs the necessary conversion of an java string into a property
* escaped string.
*
* @param text the text to be escaped
* @param escapeMode the mode that should be applied.
* @param writer the writer that should receive the content.
* @throws IOException if writing fails
*/
private void saveConvert(final String text, final int escapeMode,
final Writer writer)
throws IOException {
final char[] string = text.toCharArray();
for (int x = 0; x < string.length; x++) {
final char aChar = string[x];
switch (aChar) {
case ' ':
{
if ((escapeMode != ESCAPE_COMMENT)
&& (x == 0 || escapeMode == ESCAPE_KEY)) {
writer.write('\\');
}
writer.write(' ');
break;
}
case '\\':
{
writer.write('\\');
writer.write('\\');
break;
}
case '\t':
{
if (escapeMode == ESCAPE_COMMENT) {
writer.write(aChar);
}
else {
writer.write('\\');
writer.write('t');
}
break;
}
case '\n':
{
writer.write('\\');
writer.write('n');
break;
}
case '\r':
{
writer.write('\\');
writer.write('r');
break;
}
case '\f':
{
if (escapeMode == ESCAPE_COMMENT) {
writer.write(aChar);
}
else {
writer.write('\\');
writer.write('f');
}
break;
}
case '#':
case '"':
case '!':
case '=':
case ':':
{
if (escapeMode == ESCAPE_COMMENT) {
writer.write(aChar);
}
else {
writer.write('\\');
writer.write(aChar);
}
break;
}
default:
if ((aChar < 0x0020) || (aChar > 0x007e)) {
writer.write('\\');
writer.write('u');
writer.write(HEX_CHARS[(aChar >> 12) & 0xF]);
writer.write(HEX_CHARS[(aChar >> 8) & 0xF]);
writer.write(HEX_CHARS[(aChar >> 4) & 0xF]);
writer.write(HEX_CHARS[aChar & 0xF]);
}
else {
writer.write(aChar);
}
}
}
}
/** A lookup-table. */
private static final char[] HEX_CHARS =
{'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
}