Demo for writer throwing an exception; and also writing out CD content
authorJaroslav Tulach <jtulach@netbeans.org>
Sat, 14 Jun 2008 09:53:03 +0200
changeset 6159df94cee246
parent 60 bea28c7c6653
child 62 02ccc701dcbc
Demo for writer throwing an exception; and also writing out CD content
samples/delegatingwriter/src/org/apidesign/delegatingwriter/AltBufferedWriter.java
samples/delegatingwriter/test/org/apidesign/delegatingwriter/BufferedWriterOnCDImageTest.java
samples/delegatingwriter/test/org/apidesign/delegatingwriter/BufferedWriterThrowingExceptionTest.java
samples/delegatingwriter/test/org/apidesign/delegatingwriter/CountingWriter.java
     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 +}