CrytoWriter and when it is broken
authorJaroslav Tulach <jtulach@netbeans.org>
Sat, 14 Jun 2008 09:53:04 +0200
changeset 63cbba5b31d11c
parent 62 02ccc701dcbc
child 64 7b26c64804c2
CrytoWriter and when it is broken
samples/delegatingwriter/src/org/apidesign/delegatingwriter/AltBufferedWriter.java
samples/delegatingwriter/test/org/apidesign/delegatingwriter/BufferedWriterCryptoTest.java
samples/delegatingwriter/test/org/apidesign/delegatingwriter/BufferedWriterOnCDImageTest.java
samples/delegatingwriter/test/org/apidesign/delegatingwriter/CryptoWriter.java
     1.1 --- a/samples/delegatingwriter/src/org/apidesign/delegatingwriter/AltBufferedWriter.java	Sat Jun 14 09:53:03 2008 +0200
     1.2 +++ b/samples/delegatingwriter/src/org/apidesign/delegatingwriter/AltBufferedWriter.java	Sat Jun 14 09:53:04 2008 +0200
     1.3 @@ -20,6 +20,10 @@
     1.4      private final Writer out;
     1.5      private final Behaviour behaviour;
     1.6      
     1.7 +    public AltBufferedWriter(Writer out) {
     1.8 +        // behave exactly like BufferedWriter in 1.5 behaves
     1.9 +        this(out, Behaviour.DELEGATE_TO_SUPER);
    1.10 +    }
    1.11      public AltBufferedWriter(Writer out, Behaviour behaviour) {
    1.12          super(out);
    1.13          this.out = out;
    1.14 @@ -37,8 +41,10 @@
    1.15          }
    1.16      }
    1.17      
    1.18 -    // BEGIN: writer.throw
    1.19      public Writer appendThrowException(CharSequence csq) throws IOException {
    1.20 +        /* in case of real code, this would be part of the regular append method BEGIN: writer.throw
    1.21 +    public Writer append(CharSequence csq) throws IOException {
    1.22 +        /* thrown an exception as this method is new and subclasses need to override it */
    1.23          throw new UnsupportedOperationException();
    1.24      }
    1.25      // END: writer.throw
    1.26 @@ -58,7 +64,7 @@
    1.27      
    1.28      public Writer appendDelegateToUnderlaying(CharSequence csq) throws IOException {
    1.29          // BEGIN: writer.delegateout
    1.30 -        // efficient, yet dangerous delegation skipping methods known to 
    1.31 +        // efficient, yet dangerous delegation skipping methods unknown to 
    1.32          // subclasses that used version 1.4
    1.33          out.append(csq);
    1.34          return this;
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/samples/delegatingwriter/test/org/apidesign/delegatingwriter/BufferedWriterCryptoTest.java	Sat Jun 14 09:53:04 2008 +0200
     2.3 @@ -0,0 +1,48 @@
     2.4 +
     2.5 +package org.apidesign.delegatingwriter;
     2.6 +
     2.7 +import java.io.IOException;
     2.8 +import java.io.StringWriter;
     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 delegating directly
    2.15 + *
    2.16 + * @author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    2.17 + */
    2.18 +public class BufferedWriterCryptoTest {
    2.19 +    private StringWriter writer;
    2.20 +    
    2.21 +    
    2.22 +    public BufferedWriterCryptoTest() {
    2.23 +    }
    2.24 +    
    2.25 +    @Before
    2.26 +    public void setUp() {
    2.27 +        writer = new StringWriter();
    2.28 +    }
    2.29 +
    2.30 +    @Test
    2.31 +    public void testBehaviourOfRealBufferInJDKWorksFine() throws IOException {
    2.32 +        // BEGIN: writer.crypto.ok
    2.33 +        CryptoWriter bufferedWriter = new CryptoWriter(writer);
    2.34 +        bufferedWriter.append("VMS");
    2.35 +        bufferedWriter.flush();
    2.36 +        assertEquals("Converted", "WNT", writer.toString());
    2.37 +        // END: writer.crypto.ok
    2.38 +    }
    2.39 +
    2.40 +    @Test
    2.41 +    public void testBehaviourOfBufferThatDelegatesToAppendFails() throws IOException {
    2.42 +        CryptoWriter bufferedWriter = new CryptoWriter(writer, CryptoWriter.Behaviour.DELEGATE_TO_OUT);
    2.43 +        bufferedWriter.append("VMS");
    2.44 +        bufferedWriter.flush();
    2.45 +        assertEquals("This will fail, as the direct delegation from append to " +
    2.46 +            "the underlaying writer will skip all the crypto methods", 
    2.47 +            "WNT", writer.toString()
    2.48 +        );
    2.49 +    }
    2.50 +
    2.51 +}
    2.52 \ No newline at end of file
     3.1 --- a/samples/delegatingwriter/test/org/apidesign/delegatingwriter/BufferedWriterOnCDImageTest.java	Sat Jun 14 09:53:03 2008 +0200
     3.2 +++ b/samples/delegatingwriter/test/org/apidesign/delegatingwriter/BufferedWriterOnCDImageTest.java	Sat Jun 14 09:53:04 2008 +0200
     3.3 @@ -17,7 +17,7 @@
     3.4      }
     3.5  
     3.6      @Test
     3.7 -    public void testBehaviourOfRealBufferInJDKObviouslyThisIsGoingToThrowOutOfMemoryException() throws IOException {
     3.8 +    public void testBehaviourOfRealBufferInJDKObviouslyThisIsGoingToThrowOutOfMemoryError() throws IOException {
     3.9          // BEGIN: writer.countcd
    3.10          CountingWriter writer = new CountingWriter();
    3.11          CDSequence cdImage = new CDSequence();
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/samples/delegatingwriter/test/org/apidesign/delegatingwriter/CryptoWriter.java	Sat Jun 14 09:53:04 2008 +0200
     4.3 @@ -0,0 +1,92 @@
     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 +/** Writer alters each char from 'A' to 'Z' range with next one just like
    4.11 + * old Romans did.
    4.12 + *
    4.13 + * @author Jaroslav Tulach
    4.14 + */
    4.15 +public class CryptoWriter extends AltBufferedWriter {
    4.16 +    public CryptoWriter(Writer out) {
    4.17 +        super(out);
    4.18 +    }
    4.19 +    public CryptoWriter(Writer out, AltBufferedWriter.Behaviour behaviour) {
    4.20 +        super(out, behaviour);
    4.21 +    }
    4.22 +/* The above code is here to let us simulate different behaviours of the append
    4.23 + * method. In reality, the class would just subclass BufferedWriter, as shown bellow:
    4.24 +BEGIN: writer.CryptoWriter
    4.25 +public class CryptoWriter extends BufferedWriter {
    4.26 +    public CryptoWriter(Writer out) {
    4.27 +        super(out);
    4.28 +    }
    4.29 +    
    4.30 +    /* We need to override all known methods of BufferedWriter and do conversion
    4.31 +    * of the argument char, string or char array.
    4.32 +    */
    4.33 +    
    4.34 +    @Override
    4.35 +    public void write(char[] cbuf, int off, int len) throws IOException {
    4.36 +        char[] arr = new char[len];
    4.37 +        for (int i = 0; i < len; i++) {
    4.38 +            arr[i] = convertChar(cbuf[off + i]);
    4.39 +        }
    4.40 +        super.write(arr, 0, len);
    4.41 +    }
    4.42 +
    4.43 +    @Override
    4.44 +    public void write(int c) throws IOException {
    4.45 +        super.write(convertChar(c));
    4.46 +    }
    4.47 +
    4.48 +    @Override
    4.49 +    public void write(String str, int off, int len) throws IOException {
    4.50 +        StringBuffer sb = new StringBuffer();
    4.51 +        for (int i = 0; i < len; i++) {
    4.52 +            sb.append(convertChar(str.charAt(off + i)));
    4.53 +        }
    4.54 +        super.write(sb.toString(), 0, len);
    4.55 +    }
    4.56 +
    4.57 +    private char convertChar(int c) {
    4.58 +        if (c == 'Z') {
    4.59 +            return 'A';
    4.60 +        }
    4.61 +        if (c == 'z') {
    4.62 +            return 'a';
    4.63 +        }
    4.64 +        return (char)(c + 1);
    4.65 +    }
    4.66 +// END: writer.CryptoWriter
    4.67 +
    4.68 +    /* delegates to write(cbuf, 0, cbuf.length)
    4.69 +    public void write(char[] cbuf) throws IOException {
    4.70 +    }
    4.71 +    */
    4.72 +
    4.73 +    /* delegates to write(str, 0, str.length())
    4.74 +    public void write(String str) throws IOException {
    4.75 +    }
    4.76 +    */
    4.77 +
    4.78 +    
    4.79 +/* As this class was written against the version provided by JDK 1.4, we
    4.80 + * could not override the append methods, as they did not exist at that time.
    4.81 +     
    4.82 +    @Override
    4.83 +    public Writer append(CharSequence csq) throws IOException {
    4.84 +    }
    4.85 +
    4.86 +    @Override
    4.87 +    public Writer append(CharSequence csq, int start, int end) throws IOException {
    4.88 +    }
    4.89 +
    4.90 +    @Override
    4.91 +    public Writer append(char c) throws IOException {
    4.92 +    }
    4.93 +*/
    4.94 +    
    4.95 +}