001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2007, GeoTools Project Managment Committee (PMC)
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation;
009: * version 2.1 of the License.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: */
016: package org.geotools.io;
017:
018: // Standard I/O
019: import java.io.FilterWriter;
020: import java.io.IOException;
021: import java.io.Writer;
022:
023: // Geotools dependencies
024: import org.geotools.resources.Utilities;
025:
026: /**
027: * A writer that put some spaces in front of every line. The indentation is initially set
028: * to 0 spaces. Users must invoke {@link #setIndentation} in order to set a different value.
029: *
030: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/metadata/src/main/java/org/geotools/io/IndentedLineWriter.java $
031: * @version $Id: IndentedLineWriter.java 24164 2007-02-03 05:10:58Z desruisseaux $
032: * @author Martin Desruisseaux
033: *
034: * @since 2.4
035: */
036: public class IndentedLineWriter extends FilterWriter {
037: /**
038: * A string with a length equals to the indentation.
039: */
040: private String margin = "";
041:
042: /**
043: * {@code true} if we are about to write a new line.
044: */
045: private boolean newLine = true;
046:
047: /**
048: * {@code true} if we are waiting for a '\n' character.
049: */
050: private boolean waitLF;
051:
052: /**
053: * Constructs a stream which will add spaces in front of each line.
054: *
055: * @param out The underlying stream to write to.
056: */
057: public IndentedLineWriter(final Writer out) {
058: super (out);
059: }
060:
061: /**
062: * Returns the current indentation.
063: */
064: public int getIdentation() {
065: return margin.length();
066: }
067:
068: /**
069: * Sets the indentation to the specified value.
070: */
071: public void setIndentation(final int width) {
072: synchronized (lock) {
073: margin = Utilities.spaces(width);
074: }
075: }
076:
077: /**
078: * Invoked when a new line is begining. The default implementation writes the
079: * amount of spaces specified by the last call to {@link #setIndentation}.
080: *
081: * @throws IOException If an I/O error occurs
082: */
083: protected void beginNewLine() throws IOException {
084: out.write(margin);
085: }
086:
087: /**
088: * Write the specified character.
089: *
090: * @throws IOException If an I/O error occurs
091: */
092: private void doWrite(final int c) throws IOException {
093: assert Thread.holdsLock(lock);
094: if (newLine && (c != '\n' || !waitLF)) {
095: beginNewLine();
096: }
097: out.write(c);
098: if ((newLine = (c == '\r' || c == '\n')) == true) {
099: waitLF = (c == '\r');
100: }
101: }
102:
103: /**
104: * Writes a single character.
105: *
106: * @throws IOException If an I/O error occurs
107: */
108: public void write(final int c) throws IOException {
109: synchronized (lock) {
110: doWrite(c);
111: }
112: }
113:
114: /**
115: * Writes a portion of an array of characters.
116: *
117: * @param buffer Buffer of characters to be written
118: * @param offset Offset from which to start reading characters
119: * @param length Number of characters to be written
120: * @throws IOException If an I/O error occurs
121: */
122: public void write(final char[] buffer, int offset, final int length)
123: throws IOException {
124: final int upper = offset + length;
125: synchronized (lock) {
126: check: while (offset < upper) {
127: if (newLine) {
128: doWrite(buffer[offset++]);
129: continue;
130: }
131: final int lower = offset;
132: do {
133: final char c = buffer[offset];
134: if (c == '\r' || c == '\n') {
135: out.write(buffer, lower, offset - lower);
136: doWrite(c);
137: offset++;
138: continue check;
139: }
140: } while (++offset < upper);
141: out.write(buffer, lower, offset - lower);
142: break;
143: }
144: }
145: }
146:
147: /**
148: * Writes a portion of a string.
149: *
150: * @param string String to be written
151: * @param offset Offset from which to start reading characters
152: * @param length Number of characters to be written
153: * @throws IOException If an I/O error occurs
154: */
155: public void write(final String string, int offset, final int length)
156: throws IOException {
157: final int upper = offset + length;
158: synchronized (lock) {
159: check: while (offset < upper) {
160: if (newLine) {
161: doWrite(string.charAt(offset++));
162: continue;
163: }
164: final int lower = offset;
165: do {
166: final char c = string.charAt(offset);
167: if (c == '\r' || c == '\n') {
168: out.write(string, lower, offset - lower);
169: doWrite(c);
170: offset++;
171: continue check;
172: }
173: } while (++offset < upper);
174: out.write(string, lower, offset - lower);
175: break;
176: }
177: }
178: }
179: }
|