1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/samples/delegatingwriter/src/org/apidesign/delegatingwriter/AltBufferedWriter.java Sat Jun 14 09:53:03 2008 +0200
1.3 @@ -0,0 +1,75 @@
1.4 +/*
1.5 + * To change this template, choose Tools | Templates
1.6 + * and open the template in the editor.
1.7 + */
1.8 +
1.9 +package org.apidesign.delegatingwriter;
1.10 +
1.11 +import java.io.BufferedWriter;
1.12 +import java.io.IOException;
1.13 +import java.io.Writer;
1.14 +
1.15 +/**
1.16 + * This is a regular {@link BufferedWriter}, just its implementation
1.17 + * of the append method can choose from three options. This allows us to
1.18 + * simulate the potential pros and cons of various possible implementations.
1.19 + *
1.20 + * @author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
1.21 + */
1.22 +public class AltBufferedWriter extends BufferedWriter {
1.23 + private final Writer out;
1.24 + private final Behaviour behaviour;
1.25 +
1.26 + public AltBufferedWriter(Writer out, Behaviour behaviour) {
1.27 + super(out);
1.28 + this.out = out;
1.29 + this.behaviour = behaviour;
1.30 + }
1.31 +
1.32 + @Override
1.33 + public Writer append(CharSequence csq) throws IOException {
1.34 + switch (behaviour) {
1.35 + case THROW_EXCEPTION: return appendThrowException(csq);
1.36 + case DELEGATE_TO_SUPER: return appendDelegateToSuper(csq);
1.37 + case DELEGATE_TO_OUT: return appendDelegateToUnderlaying(csq);
1.38 + case DELEGATE_CONDITIONALLY: return appendDelegateConditionally(csq);
1.39 + default: throw new IllegalStateException("Unknown" + behaviour);
1.40 + }
1.41 + }
1.42 +
1.43 + // BEGIN: writer.throw
1.44 + public Writer appendThrowException(CharSequence csq) throws IOException {
1.45 + throw new UnsupportedOperationException();
1.46 + }
1.47 + // END: writer.throw
1.48 +
1.49 + public Writer appendDelegateToSuper(CharSequence csq) throws IOException {
1.50 + // non-efficient variant of delegating via converting to String first
1.51 + // and using one of methods that existed in 1.4
1.52 + // BEGIN: writer.throw.client
1.53 + if (csq == null) {
1.54 + write("null");
1.55 + } else {
1.56 + write(csq.toString());
1.57 + }
1.58 + return this;
1.59 + // END: writer.throw.client
1.60 + }
1.61 +
1.62 + public Writer appendDelegateToUnderlaying(CharSequence csq) throws IOException {
1.63 + // BEGIN: writer.delegateout
1.64 + // efficient, yet dangerous delegation skipping methods known to
1.65 + // subclasses that used version 1.4
1.66 + out.append(csq);
1.67 + return this;
1.68 + // END: writer.delegateout
1.69 + }
1.70 +
1.71 + private Writer appendDelegateConditionally(CharSequence csq) {
1.72 + throw new UnsupportedOperationException("Not yet implemented");
1.73 + }
1.74 +
1.75 + public enum Behaviour {
1.76 + THROW_EXCEPTION, DELEGATE_TO_SUPER, DELEGATE_TO_OUT, DELEGATE_CONDITIONALLY
1.77 + }
1.78 +}
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/samples/delegatingwriter/test/org/apidesign/delegatingwriter/BufferedWriterOnCDImageTest.java Sat Jun 14 09:53:03 2008 +0200
2.3 @@ -0,0 +1,84 @@
2.4 +
2.5 +package org.apidesign.delegatingwriter;
2.6 +
2.7 +import java.io.BufferedWriter;
2.8 +import java.io.IOException;
2.9 +import java.io.StringWriter;
2.10 +import org.junit.Before;
2.11 +import org.junit.Test;
2.12 +import static org.junit.Assert.*;
2.13 +
2.14 +/** Emulates what goes wrong when one wants to process really large character
2.15 + * sequence.
2.16 + *
2.17 + * @author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
2.18 + */
2.19 +public class BufferedWriterOnCDImageTest {
2.20 +
2.21 + public BufferedWriterOnCDImageTest() {
2.22 + }
2.23 +
2.24 + @Test
2.25 + public void testBehaviourOfRealBufferInJDKObviouslyThisIsGoingToThrowOutOfMemoryException() throws IOException {
2.26 + // BEGIN: writer.countcd
2.27 + CountingWriter writer = new CountingWriter();
2.28 + CDSequence cdImage = new CDSequence();
2.29 + BufferedWriter bufferedWriter = new BufferedWriter(writer);
2.30 + bufferedWriter.append(cdImage);
2.31 + assertEquals("Correct number of writes delegated", cdImage.length(), writer.getCharacterCount());
2.32 + // END: writer.countcd
2.33 + }
2.34 +
2.35 + @Test
2.36 + public void testBehaviourOfBufferThatDelegatesToAppend() throws IOException {
2.37 + CountingWriter writer = new CountingWriter();
2.38 + CDSequence cdImage = new CDSequence();
2.39 + BufferedWriter bufferedWriter = new AltBufferedWriter(writer, AltBufferedWriter.Behaviour.DELEGATE_TO_OUT);
2.40 + bufferedWriter.append(cdImage);
2.41 + assertEquals("Correct number of writes delegated", cdImage.length(), writer.getCharacterCount());
2.42 + }
2.43 +
2.44 +// BEGIN: writer.bigseq
2.45 + /** A "lazy" sequence of characters, for example one that can represent
2.46 + * content of a CD, read it lazily, do not fit all into memory at once.
2.47 + */
2.48 + private static final class CDSequence implements CharSequence {
2.49 + private final int start;
2.50 + private final int end;
2.51 +
2.52 + public CDSequence() {
2.53 + this(0, 647 * 1024 * 1024);
2.54 + }
2.55 +
2.56 + private CDSequence(int start, int end) {
2.57 + this.start = start;
2.58 + this.end = end;
2.59 + }
2.60 +
2.61 +
2.62 + public int length() {
2.63 + return end - start;
2.64 + }
2.65 +// END: writer.bigseq
2.66 +
2.67 + public char charAt(int index) {
2.68 + int ch = index % ('Z' - 'A' + 1);
2.69 + return (char) ('A' + ch);
2.70 + }
2.71 +
2.72 + public CharSequence subSequence(int start, int end) {
2.73 + return new CDSequence(start, end);
2.74 + }
2.75 +
2.76 + @Override
2.77 + public String toString() {
2.78 + char[] arr = new char[length()];
2.79 + for (int i = 0; i < length(); i++) {
2.80 + arr[i] = charAt(i);
2.81 + }
2.82 + return new String(arr);
2.83 + }
2.84 +
2.85 +
2.86 + } // end of CharSequence
2.87 +}
2.88 \ No newline at end of file
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/samples/delegatingwriter/test/org/apidesign/delegatingwriter/BufferedWriterThrowingExceptionTest.java Sat Jun 14 09:53:03 2008 +0200
3.3 @@ -0,0 +1,57 @@
3.4 +
3.5 +package org.apidesign.delegatingwriter;
3.6 +
3.7 +import java.io.BufferedWriter;
3.8 +import java.io.IOException;
3.9 +import java.io.StringWriter;
3.10 +import java.io.Writer;
3.11 +import org.junit.After;
3.12 +import org.junit.Before;
3.13 +import org.junit.Test;
3.14 +import static org.junit.Assert.*;
3.15 +
3.16 +/**
3.17 + *
3.18 + * @author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
3.19 + */
3.20 +public class BufferedWriterThrowingExceptionTest {
3.21 + private StringWriter writer;
3.22 +
3.23 + public BufferedWriterThrowingExceptionTest() {
3.24 + }
3.25 +
3.26 + @Before
3.27 + public void setUp() {
3.28 + writer = new StringWriter();
3.29 + }
3.30 +
3.31 + @Test
3.32 + public void testBehaviourOfRealBufferInJDK() throws IOException {
3.33 + BufferedWriter bufferedWriter = new BufferedWriter(writer);
3.34 + doAppendHello(bufferedWriter, "Hello!");
3.35 + bufferedWriter.flush();
3.36 +
3.37 + assertEquals("Hello!", writer.toString());
3.38 + }
3.39 +
3.40 + @Test
3.41 + public void testBehaviourOfBufferThatThrowsExceptionWhenAppendIsCalled() throws IOException {
3.42 + BufferedWriter bufferedWriter = new AltBufferedWriter(writer, AltBufferedWriter.Behaviour.THROW_EXCEPTION);
3.43 + doAppendHello(bufferedWriter, "Hello!");
3.44 + bufferedWriter.flush();
3.45 +
3.46 + assertEquals("Hello!", writer.toString());
3.47 + }
3.48 +
3.49 +
3.50 + private void doAppendHello(BufferedWriter bufferedWriter, CharSequence what) throws IOException {
3.51 + // BEGIN: writer.throw.client
3.52 + try {
3.53 + bufferedWriter.append(what);
3.54 + } catch (UnsupportedOperationException ex) {
3.55 + bufferedWriter.write(what.toString());
3.56 + }
3.57 + // END: writer.throw.client
3.58 + }
3.59 +
3.60 +}
3.61 \ No newline at end of file
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/samples/delegatingwriter/test/org/apidesign/delegatingwriter/CountingWriter.java Sat Jun 14 09:53:03 2008 +0200
4.3 @@ -0,0 +1,72 @@
4.4 +
4.5 +package org.apidesign.delegatingwriter;
4.6 +
4.7 +import java.io.IOException;
4.8 +import java.io.Writer;
4.9 +
4.10 +// BEGIN: writer.CountingWriter
4.11 +/** Writer that counts the number of written in characters.
4.12 + *
4.13 + * @author Jaroslav Tulach
4.14 + */
4.15 +public class CountingWriter extends Writer {
4.16 + private int counter;
4.17 +
4.18 +
4.19 + public int getCharacterCount() {
4.20 + return counter;
4.21 + }
4.22 +
4.23 + @Override
4.24 + public void write(char[] cbuf, int off, int len) throws IOException {
4.25 + counter += len;
4.26 + }
4.27 +
4.28 + @Override
4.29 + public Writer append(CharSequence csq) throws IOException {
4.30 + counter += csq.length();
4.31 + return this;
4.32 + }
4.33 +// END: writer.CountingWriter
4.34 +
4.35 + @Override
4.36 + public Writer append(CharSequence csq, int start, int end) throws IOException {
4.37 + counter += (end - start);
4.38 + return this;
4.39 + }
4.40 +
4.41 + @Override
4.42 + public Writer append(char c) throws IOException {
4.43 + counter++;
4.44 + return this;
4.45 + }
4.46 +
4.47 + @Override
4.48 + public void write(int c) throws IOException {
4.49 + counter++;
4.50 + }
4.51 +
4.52 + @Override
4.53 + public void write(char[] cbuf) throws IOException {
4.54 + counter += cbuf.length;
4.55 + }
4.56 +
4.57 + @Override
4.58 + public void write(String str) throws IOException {
4.59 + counter += str.length();
4.60 + }
4.61 +
4.62 + @Override
4.63 + public void write(String str, int off, int len) throws IOException {
4.64 + counter += len;
4.65 + }
4.66 +
4.67 + @Override
4.68 + public void flush() throws IOException {
4.69 + }
4.70 +
4.71 + @Override
4.72 + public void close() throws IOException {
4.73 + }
4.74 +
4.75 +}