# HG changeset patch # User Jaroslav Tulach # Date 1213429984 -7200 # Node ID cbba5b31d11c0a92418fd5921ab7f6e60d14fa2d # Parent 02ccc701dcbc3a95fde2f1d0d4f50cdff2bd8ee3 CrytoWriter and when it is broken diff -r 02ccc701dcbc -r cbba5b31d11c samples/delegatingwriter/src/org/apidesign/delegatingwriter/AltBufferedWriter.java --- a/samples/delegatingwriter/src/org/apidesign/delegatingwriter/AltBufferedWriter.java Sat Jun 14 09:53:03 2008 +0200 +++ b/samples/delegatingwriter/src/org/apidesign/delegatingwriter/AltBufferedWriter.java Sat Jun 14 09:53:04 2008 +0200 @@ -20,6 +20,10 @@ private final Writer out; private final Behaviour behaviour; + public AltBufferedWriter(Writer out) { + // behave exactly like BufferedWriter in 1.5 behaves + this(out, Behaviour.DELEGATE_TO_SUPER); + } public AltBufferedWriter(Writer out, Behaviour behaviour) { super(out); this.out = out; @@ -37,8 +41,10 @@ } } - // BEGIN: writer.throw public Writer appendThrowException(CharSequence csq) throws IOException { + /* in case of real code, this would be part of the regular append method BEGIN: writer.throw + public Writer append(CharSequence csq) throws IOException { + /* thrown an exception as this method is new and subclasses need to override it */ throw new UnsupportedOperationException(); } // END: writer.throw @@ -58,7 +64,7 @@ public Writer appendDelegateToUnderlaying(CharSequence csq) throws IOException { // BEGIN: writer.delegateout - // efficient, yet dangerous delegation skipping methods known to + // efficient, yet dangerous delegation skipping methods unknown to // subclasses that used version 1.4 out.append(csq); return this; diff -r 02ccc701dcbc -r cbba5b31d11c samples/delegatingwriter/test/org/apidesign/delegatingwriter/BufferedWriterCryptoTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/samples/delegatingwriter/test/org/apidesign/delegatingwriter/BufferedWriterCryptoTest.java Sat Jun 14 09:53:04 2008 +0200 @@ -0,0 +1,48 @@ + +package org.apidesign.delegatingwriter; + +import java.io.IOException; +import java.io.StringWriter; +import java.io.StringWriter; +import org.junit.Before; +import org.junit.Test; +import static org.junit.Assert.*; + +/** Emulates what goes wrong when delegating directly + * + * @author Jaroslav Tulach + */ +public class BufferedWriterCryptoTest { + private StringWriter writer; + + + public BufferedWriterCryptoTest() { + } + + @Before + public void setUp() { + writer = new StringWriter(); + } + + @Test + public void testBehaviourOfRealBufferInJDKWorksFine() throws IOException { + // BEGIN: writer.crypto.ok + CryptoWriter bufferedWriter = new CryptoWriter(writer); + bufferedWriter.append("VMS"); + bufferedWriter.flush(); + assertEquals("Converted", "WNT", writer.toString()); + // END: writer.crypto.ok + } + + @Test + public void testBehaviourOfBufferThatDelegatesToAppendFails() throws IOException { + CryptoWriter bufferedWriter = new CryptoWriter(writer, CryptoWriter.Behaviour.DELEGATE_TO_OUT); + bufferedWriter.append("VMS"); + bufferedWriter.flush(); + assertEquals("This will fail, as the direct delegation from append to " + + "the underlaying writer will skip all the crypto methods", + "WNT", writer.toString() + ); + } + +} \ No newline at end of file diff -r 02ccc701dcbc -r cbba5b31d11c samples/delegatingwriter/test/org/apidesign/delegatingwriter/BufferedWriterOnCDImageTest.java --- a/samples/delegatingwriter/test/org/apidesign/delegatingwriter/BufferedWriterOnCDImageTest.java Sat Jun 14 09:53:03 2008 +0200 +++ b/samples/delegatingwriter/test/org/apidesign/delegatingwriter/BufferedWriterOnCDImageTest.java Sat Jun 14 09:53:04 2008 +0200 @@ -17,7 +17,7 @@ } @Test - public void testBehaviourOfRealBufferInJDKObviouslyThisIsGoingToThrowOutOfMemoryException() throws IOException { + public void testBehaviourOfRealBufferInJDKObviouslyThisIsGoingToThrowOutOfMemoryError() throws IOException { // BEGIN: writer.countcd CountingWriter writer = new CountingWriter(); CDSequence cdImage = new CDSequence(); diff -r 02ccc701dcbc -r cbba5b31d11c samples/delegatingwriter/test/org/apidesign/delegatingwriter/CryptoWriter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/samples/delegatingwriter/test/org/apidesign/delegatingwriter/CryptoWriter.java Sat Jun 14 09:53:04 2008 +0200 @@ -0,0 +1,92 @@ + +package org.apidesign.delegatingwriter; + +import java.io.IOException; +import java.io.Writer; + +/** Writer alters each char from 'A' to 'Z' range with next one just like + * old Romans did. + * + * @author Jaroslav Tulach + */ +public class CryptoWriter extends AltBufferedWriter { + public CryptoWriter(Writer out) { + super(out); + } + public CryptoWriter(Writer out, AltBufferedWriter.Behaviour behaviour) { + super(out, behaviour); + } +/* The above code is here to let us simulate different behaviours of the append + * method. In reality, the class would just subclass BufferedWriter, as shown bellow: +BEGIN: writer.CryptoWriter +public class CryptoWriter extends BufferedWriter { + public CryptoWriter(Writer out) { + super(out); + } + + /* We need to override all known methods of BufferedWriter and do conversion + * of the argument char, string or char array. + */ + + @Override + public void write(char[] cbuf, int off, int len) throws IOException { + char[] arr = new char[len]; + for (int i = 0; i < len; i++) { + arr[i] = convertChar(cbuf[off + i]); + } + super.write(arr, 0, len); + } + + @Override + public void write(int c) throws IOException { + super.write(convertChar(c)); + } + + @Override + public void write(String str, int off, int len) throws IOException { + StringBuffer sb = new StringBuffer(); + for (int i = 0; i < len; i++) { + sb.append(convertChar(str.charAt(off + i))); + } + super.write(sb.toString(), 0, len); + } + + private char convertChar(int c) { + if (c == 'Z') { + return 'A'; + } + if (c == 'z') { + return 'a'; + } + return (char)(c + 1); + } +// END: writer.CryptoWriter + + /* delegates to write(cbuf, 0, cbuf.length) + public void write(char[] cbuf) throws IOException { + } + */ + + /* delegates to write(str, 0, str.length()) + public void write(String str) throws IOException { + } + */ + + +/* As this class was written against the version provided by JDK 1.4, we + * could not override the append methods, as they did not exist at that time. + + @Override + public Writer append(CharSequence csq) throws IOException { + } + + @Override + public Writer append(CharSequence csq, int start, int end) throws IOException { + } + + @Override + public Writer append(char c) throws IOException { + } +*/ + +}