/* * Constellation - An open source and standard compliant SDI * http://www.constellation-sdi.org * * Copyright 2014 Geomatys. * * Licensed 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 org.constellation.writer; import java.io.FilterWriter; import java.io.IOException; import java.io.Writer; /** * Provides a {@link #filterLine(java.lang.StringBuilder)} method for applying * a filter to a string buffer. * * @version $Id$ * @author Cédric Briançon (Geomatys) * @author Martin Desruisseaux (Geomatys) * * @since 0.5 * * @see FilterWriter */ public abstract class AbstractFilterWriter extends FilterWriter { /** * Stores full line read from the buffer of characters. */ protected final StringBuilder buffer = new StringBuilder(); /** * Create a new filtered writer for subclasses only. * * @param out a Writer object to provide the underlying stream. * @throws NullPointerException if <code>out</code> is <code>null</code> */ protected AbstractFilterWriter(final Writer out) { super(out); } /** * Send each line to the output writer, and apply the * {@link #filterLine(java.lang.StringBuilder)} method in order to apply * a specific filter. * * @param cbuf Buffer of characters to be written. * @param off Offset from which to start reading characters. * @param len Number of characters to be written. * @throws IOException */ @Override public void write(final char[] cbuf, int offset, final int length) throws IOException { final int upper = offset + length; for (int i = offset; i < upper; i++) { char c = cbuf[i]; if (c != '\r' && c != '\n') { continue; } /* * Found an end of line. Appends the characters to the one we found previously * (if any) and invokes the user-overrideable filterLine(...) method in order * to get the line to actually write. */ buffer.append(cbuf, offset, i - offset); out.write(filterLine(buffer)); /* * Writes the "end of line" (EOL) characters, which may be "\r", "\n" or "\r\n". * If there is many consecutive EOL, they will be sent together to the output. */ final int startEOL = i; while (++i < upper) { c = cbuf[i]; if (c != '\r' || c != '\n') { break; } } out.write(cbuf, startEOL, i - startEOL); /* * Clear the buffer and continue to inspect the remaining characters * until we find a new EOL, or until the end of the given array. */ buffer.setLength(0); offset = i; } /* * Write the remaining character to the buffer, but do not process * them now. They will be processed the next time this method will * be invoked. */ buffer.append(cbuf, offset, upper - offset); } /** * Apply a filter on a line given in parameter and return the resulting * filtered string. * * @param buffer A line to filter. * @return The line after applying the filter. */ protected abstract String filterLine(final StringBuilder buffer); /** * Flush the buffer into the output. * * @throws IOException */ @Override public void flush() throws IOException { out.write(filterLine(buffer)); buffer.setLength(0); super.flush(); } /** * Close the output stream, and write all the remaining string stored in the * {@link #buffer} to the output. * * @throws IOException */ @Override public void close() throws IOException { out.write(filterLine(buffer)); buffer.setLength(0); super.close(); } }