Skip to content

Instantly share code, notes, and snippets.

@aliteralmind
Last active January 3, 2016 17:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aliteralmind/8494917 to your computer and use it in GitHub Desktop.
Save aliteralmind/8494917 to your computer and use it in GitHub Desktop.
Creates a new java.io.Writer that wraps around a java.lang.Appendable. It properly flushes and closes appendables that happened to also be java.io.Flushables and/or java.io.Closeables. This uses instanceof only in the constructor, and a (Java 1.5) delta in flush() and close(), which avoids having to use any logic or reflection after object const…
/*
XBN-Java is released under the LGPL 2.1
XBN-Java is a collection of generically-useful non-GUI programming utilities, featuring shareable self-returning method chains, "Listify"-ers, regular expression convenience classes, ValidateValue and AlterValue, highly-configurable output for strings and lists, and unit-testing example code.
Copyright (C) 2013 Jeff Epstein
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*)
*/
import java.io.Closeable;
import java.io.Flushable;
import java.io.IOException;
import java.io.Writer;
/**
<P>{@code java NewWriterForAppendable}.</P>
@author Copyright (C) 2013 Jeff Epstein, with asistance by Marc Baumbach for {@code newWriterForAppendable(apbl)}. Released under the LPGL 2.1. <CODE><A HREF="http://xbnjava.jeffyepstein.com">http://xbnjava.jeffyepstein.com</A></CODE>, <CODE><A HREF="https://github.com/aliteralmind/xbnjava">https://github.com/aliteralmind/xbnjava</A></CODE>
**/
public class NewWriterForAppendable {
/**
<P>Demonstrates {@code newWriterForAppendable(apbl)} for creating a new {@code Writer} that wraps around {@code System.out} (writes to the console).</P>
**/
public static final void main(String[] igno_red) {
try {
NewWriterForAppendable.newWriterForAppendable(System.out).write("hello");
} catch(IOException iox) {
throw new RuntimeException("WriterForAppendableXmpl", iox);
}
}
/**
<P>A {@code Flushable} whose {@code flush()} function does nothing. This is used by {@link #newWriterForAppendable(Appendable ap_bl) newWriterForAppendable}{@code (apbl)} as a (Java 1.5) delta.</P>
@see #newWriterForAppendable(Appendable) newWriterForAppendable(apbl)
**/
public static final Flushable FLUSHABLE_DO_NOTHING = new Flushable() {
public void flush() {
}
};
/**
<P>A {@code Closeable} whose {@code close()} function does nothing. This is used by {@link #newWriterForAppendable(Appendable ap_bl) newWriterForAppendable}{@code (apbl)} as a (Java 1.5) delta.</P>
@see #newWriterForAppendable(Appendable) newWriterForAppendable(apbl)
**/
public static final Closeable CLOSEABLE_DO_NOTHING = new Closeable() {
public void close() {
}
};
/**
<P>Creates a new {@code java.io.Writer} that wraps around a {@code java.lang.Appendable}. It properly {@link java.io.Writer#flush() flush}es and {@link java.io.Writer#close() close}s appendables that happened to also be {@link java.io.Flushable}s and/or {@link java.io.Closeable Closeable}s. This uses {@code instanceof} only in the constructor, and a (Java 1.5) delta in {@code flush()} and {@code close()}, which avoids having to use any logic or reflection after object construction.</P>
<P>This function is released as a <A HREF="https://gist.github.com/aliteralmind/8494917">gist</A>, and is an example of the <A HREF="http://en.wikipedia.org/wiki/Adapter_pattern#Object_Adapter_pattern">Object Adapter pattern</A>. Thanks to <A HREF="http://stackoverflow.com/users/1211906/marc-baumbach">Marc Baumbach</A> on <A HREF="http://stackoverflow.com">{@code stackoverflow}</A> for the assistance. See (viewed 1/18/2014)
<BR> &nbsp; &nbsp; <CODE><A HREF="http://stackoverflow.com/questions/21200421/how-to-wrap-a-java-lang-appendable-into-a-java-io-writer">http://stackoverflow.com/questions/21200421/how-to-wrap-a-java-lang-appendable-into-a-java-io-writer</A></CODE></P>
@return A new writer that uses an appendable to do its output.
@see #FLUSHABLE_DO_NOTHING
@see #CLOSEABLE_DO_NOTHING
**/
public static final Writer newWriterForAppendable(Appendable ap_bl) {
return (new WFA(ap_bl));
}
private NewWriterForAppendable() {
throw new IllegalStateException("constructor: Do not instantiate.");
}
}
class WFA extends Writer {
private final Appendable apbl;
private final Flushable flbl;
private final Closeable clbl;
public WFA(Appendable ap_bl) {
if(ap_bl == null) {
throw new NullPointerException("newWriterForAppendable: ap_bl");
}
apbl = ap_bl;
//Avoids instanceof at every call to flush() and close()
flbl = (Flushable)((ap_bl instanceof Flushable) ? ap_bl
: NewWriterForAppendable.FLUSHABLE_DO_NOTHING);
clbl = (Closeable)((ap_bl instanceof Closeable) ? ap_bl
: NewWriterForAppendable.CLOSEABLE_DO_NOTHING);
}
@Override
public void write(char[] a_c, int i_ndexStart, int i_ndexEndX) throws IOException {
apbl.append(String.valueOf(a_c), i_ndexStart, i_ndexEndX);
}
@Override
public Writer append(char c_c) throws IOException {
apbl.append(c_c);
return this;
}
@Override
public Writer append(CharSequence c_q) throws IOException {
apbl.append(c_q);
return this;
}
@Override
public Writer append(CharSequence c_q, int i_ndexStart, int i_ndexEndX) throws IOException {
apbl.append(c_q, i_ndexStart, i_ndexEndX);
return this;
}
@Override
public void flush() throws IOException {
flbl.flush();
}
@Override
public void close() throws IOException {
flush();
clbl.close();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment