As the purpose of buffer is to "buffer", let's modify our example to delegate to appendable methods directly only if the appendable is too big
authorJaroslav Tulach <jtulach@netbeans.org>
Sat, 14 Jun 2008 09:53:07 +0200
changeset 67b029a28df444
parent 66 8379bb7c0dff
child 68 a2de5429d581
As the purpose of buffer is to "buffer", let's modify our example to delegate to appendable methods directly only if the appendable is too big
samples/delegatingwriter/src/org/apidesign/delegatingwriter/AltBufferedWriter.java
samples/delegatingwriter/test/org/apidesign/delegatingwriter/BufferedWriterCryptoTest.java
samples/delegatingwriter/test/org/apidesign/delegatingwriter/BufferedWriterThrowingExceptionTest.java
samples/delegatingwriterfinal/src-api1.0/api/SimpleBuffer.java
samples/delegatingwriterfinal/src-api1.0/api/Writer.java
samples/delegatingwriterfinal/src-api2.0/api/SimpleBuffer.java
samples/delegatingwriterfinal/src-api2.0/api/Writer.java
samples/delegatingwriterfinal/src-test1.0/api/usage/CryptoWriter.java
     1.1 --- a/samples/delegatingwriter/src/org/apidesign/delegatingwriter/AltBufferedWriter.java	Sat Jun 14 09:53:06 2008 +0200
     1.2 +++ b/samples/delegatingwriter/src/org/apidesign/delegatingwriter/AltBufferedWriter.java	Sat Jun 14 09:53:07 2008 +0200
     1.3 @@ -66,7 +66,12 @@
     1.4          // BEGIN: writer.delegateout
     1.5          // efficient, yet dangerous delegation skipping methods unknown to 
     1.6          // subclasses that used version 1.4
     1.7 -        out.append(csq);
     1.8 +        if (csq != null && csq.length() < 1024) {
     1.9 +            write(csq.toString());
    1.10 +        } else {
    1.11 +            flush();
    1.12 +            out.append(csq);
    1.13 +        }
    1.14          return this;
    1.15          // END: writer.delegateout
    1.16      }
    1.17 @@ -83,13 +88,10 @@
    1.18              throw new IOException(ex);
    1.19          }
    1.20          
    1.21 -        if (isOverriden) {
    1.22 -            if (csq == null) {
    1.23 -                write("null");
    1.24 -            } else {
    1.25 -                write(csq.toString());
    1.26 -            }
    1.27 +        if (isOverriden || (csq != null && csq.length() < 1024)) {
    1.28 +            write(csq.toString());
    1.29          } else {
    1.30 +            flush();
    1.31              out.append(csq);
    1.32          }
    1.33          return this;
     2.1 --- a/samples/delegatingwriter/test/org/apidesign/delegatingwriter/BufferedWriterCryptoTest.java	Sat Jun 14 09:53:06 2008 +0200
     2.2 +++ b/samples/delegatingwriter/test/org/apidesign/delegatingwriter/BufferedWriterCryptoTest.java	Sat Jun 14 09:53:07 2008 +0200
     2.3 @@ -14,7 +14,8 @@
     2.4   */
     2.5  public class BufferedWriterCryptoTest {
     2.6      private StringWriter writer;
     2.7 -    
     2.8 +    private String fromCode;
     2.9 +    private String toCode;
    2.10      
    2.11      public BufferedWriterCryptoTest() {
    2.12      }
    2.13 @@ -22,6 +23,14 @@
    2.14      @Before
    2.15      public void setUp() {
    2.16          writer = new StringWriter();
    2.17 +        StringBuffer f = new StringBuffer();
    2.18 +        StringBuffer t = new StringBuffer();
    2.19 +        for (int i = 0; i < 500; i++) {
    2.20 +            f.append("VMS");
    2.21 +            t.append("WNT");
    2.22 +        }
    2.23 +        fromCode = f.toString();
    2.24 +        toCode = t.toString();
    2.25      }
    2.26  
    2.27      @Test
    2.28 @@ -35,13 +44,21 @@
    2.29      }
    2.30  
    2.31      @Test
    2.32 +    public void testBehaviourOfRealBufferInJDKWorksFineOnLongSentences() throws IOException {
    2.33 +        CryptoWriter bufferedWriter = new CryptoWriter(writer);
    2.34 +        bufferedWriter.append(fromCode);
    2.35 +        bufferedWriter.flush();
    2.36 +        assertEquals("Converted", toCode, writer.toString());
    2.37 +    }
    2.38 +
    2.39 +    @Test
    2.40      public void testBehaviourOfBufferThatDelegatesToAppendFails() throws IOException {
    2.41          CryptoWriter bufferedWriter = new CryptoWriter(writer, CryptoWriter.Behaviour.DELEGATE_TO_OUT);
    2.42 -        bufferedWriter.append("VMS");
    2.43 +        bufferedWriter.append(fromCode);
    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 +            toCode, writer.toString()
    2.49          );
    2.50      }
    2.51  
     3.1 --- a/samples/delegatingwriter/test/org/apidesign/delegatingwriter/BufferedWriterThrowingExceptionTest.java	Sat Jun 14 09:53:06 2008 +0200
     3.2 +++ b/samples/delegatingwriter/test/org/apidesign/delegatingwriter/BufferedWriterThrowingExceptionTest.java	Sat Jun 14 09:53:07 2008 +0200
     3.3 @@ -4,8 +4,6 @@
     3.4  import java.io.BufferedWriter;
     3.5  import java.io.IOException;
     3.6  import java.io.StringWriter;
     3.7 -import java.io.Writer;
     3.8 -import org.junit.After;
     3.9  import org.junit.Before;
    3.10  import org.junit.Test;
    3.11  import static org.junit.Assert.*;
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/samples/delegatingwriterfinal/src-api1.0/api/SimpleBuffer.java	Sat Jun 14 09:53:07 2008 +0200
     4.3 @@ -0,0 +1,36 @@
     4.4 +package api;
     4.5 +
     4.6 +import java.io.IOException;
     4.7 +
     4.8 +/**
     4.9 + *
    4.10 + * @author Jaroslav Tulach
    4.11 + */
    4.12 +final class SimpleBuffer implements Writer.Impl {
    4.13 +    private final Writer out;
    4.14 +    private final StringBuffer sb = new StringBuffer();
    4.15 +    
    4.16 +    public SimpleBuffer(Writer out) {
    4.17 +        this.out = out;
    4.18 +    }
    4.19 +
    4.20 +    public void close() throws IOException {
    4.21 +        flush();
    4.22 +        out.close();
    4.23 +    }
    4.24 +
    4.25 +    public void flush() throws IOException {
    4.26 +        out.write(sb.toString());
    4.27 +        sb.setLength(0);
    4.28 +        out.flush();
    4.29 +    }
    4.30 +
    4.31 +    public void write(String str, int off, int len) throws IOException {
    4.32 +        sb.append(str, len, len);
    4.33 +    }
    4.34 +
    4.35 +    public void write(char[] arr, int off, int len) throws IOException {
    4.36 +        sb.append(arr, len, len);
    4.37 +    }
    4.38 +
    4.39 +}
     5.1 --- a/samples/delegatingwriterfinal/src-api1.0/api/Writer.java	Sat Jun 14 09:53:06 2008 +0200
     5.2 +++ b/samples/delegatingwriterfinal/src-api1.0/api/Writer.java	Sat Jun 14 09:53:07 2008 +0200
     5.3 @@ -1,6 +1,5 @@
     5.4  package api;
     5.5  
     5.6 -import java.io.BufferedWriter;
     5.7  import java.io.IOException;
     5.8  
     5.9  /** Fixing the problem caused by mixing subclassing and delegation in 
    5.10 @@ -63,24 +62,7 @@
    5.11      }
    5.12      
    5.13      public static Writer createBuffered(final Writer out) {
    5.14 -        class Delegate extends java.io.Writer {
    5.15 -            @Override
    5.16 -            public void write(char[] cbuf, int off, int len) throws IOException {
    5.17 -                out.write(cbuf, off, len);
    5.18 -            }
    5.19 -
    5.20 -            @Override
    5.21 -            public void flush() throws IOException {
    5.22 -                out.flush();
    5.23 -            }
    5.24 -
    5.25 -            @Override
    5.26 -            public void close() throws IOException {
    5.27 -                out.close();
    5.28 -            }
    5.29 -            
    5.30 -        }
    5.31 -        return create(new BufferedWriter(new Delegate()));
    5.32 +        return create(new SimpleBuffer(out));
    5.33      }
    5.34  
    5.35      
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/samples/delegatingwriterfinal/src-api2.0/api/SimpleBuffer.java	Sat Jun 14 09:53:07 2008 +0200
     6.3 @@ -0,0 +1,39 @@
     6.4 +package api;
     6.5 +
     6.6 +import java.io.IOException;
     6.7 +
     6.8 +/**
     6.9 + *
    6.10 + * @author Jaroslav Tulach
    6.11 + */
    6.12 +final class SimpleBuffer implements Writer.ImplSeq {
    6.13 +    private final Writer out;
    6.14 +    private final StringBuffer sb = new StringBuffer();
    6.15 +    
    6.16 +    public SimpleBuffer(Writer out) {
    6.17 +        this.out = out;
    6.18 +    }
    6.19 +
    6.20 +    public void close() throws IOException {
    6.21 +        flush();
    6.22 +        out.close();
    6.23 +    }
    6.24 +
    6.25 +    public void flush() throws IOException {
    6.26 +        if (sb.length() > 0) {
    6.27 +            out.write(sb.toString());
    6.28 +            sb.setLength(0);
    6.29 +            out.flush();
    6.30 +        }
    6.31 +    }
    6.32 +
    6.33 +    public void write(CharSequence seq) throws IOException {
    6.34 +        if (seq.length() < 1024) {
    6.35 +            sb.append(seq);
    6.36 +        } else {
    6.37 +            flush();
    6.38 +            out.append(seq);
    6.39 +        }
    6.40 +    }
    6.41 +
    6.42 +}
     7.1 --- a/samples/delegatingwriterfinal/src-api2.0/api/Writer.java	Sat Jun 14 09:53:06 2008 +0200
     7.2 +++ b/samples/delegatingwriterfinal/src-api2.0/api/Writer.java	Sat Jun 14 09:53:07 2008 +0200
     7.3 @@ -8,7 +8,7 @@
     7.4   *
     7.5   * @author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
     7.6   */
     7.7 -public final class Writer {
     7.8 +public final class Writer implements Appendable {
     7.9      private final Impl impl;
    7.10      private final ImplSeq seq;
    7.11      
    7.12 @@ -69,6 +69,27 @@
    7.13          }
    7.14      }
    7.15  
    7.16 +    
    7.17 +    
    7.18 +    public final Writer append(CharSequence csq) throws IOException {
    7.19 +        if (impl != null) {
    7.20 +            String s = csq == null ? "null" : csq.toString();
    7.21 +            impl.write(s, 0, s.length());
    7.22 +        } else {
    7.23 +            seq.write(csq);
    7.24 +        }
    7.25 +        return this;
    7.26 +    }
    7.27 +
    7.28 +    public final Writer append(CharSequence csq, int start, int end) throws IOException {
    7.29 +        return append(csq.subSequence(start, end));
    7.30 +    }
    7.31 +
    7.32 +    public final Writer append(char c) throws IOException {
    7.33 +        write(c);
    7.34 +        return this;
    7.35 +    }
    7.36 +
    7.37      public static Writer create(Impl impl) {
    7.38          return new Writer(impl, null);
    7.39      }
    7.40 @@ -78,13 +99,9 @@
    7.41      }
    7.42      
    7.43      public static Writer create(final java.io.Writer w) {
    7.44 -        return new Writer(new Impl() {
    7.45 -            public void write(String str, int off, int len) throws IOException {
    7.46 -                w.write(str, off, len);
    7.47 -            }
    7.48 -
    7.49 -            public void write(char[] arr, int off, int len) throws IOException {
    7.50 -                w.write(arr, off, len);
    7.51 +        return new Writer(null, new ImplSeq() {
    7.52 +            public void write(CharSequence seq) throws IOException {
    7.53 +                w.append(seq);
    7.54              }
    7.55  
    7.56              public void close() throws IOException {
    7.57 @@ -94,28 +111,11 @@
    7.58              public void flush() throws IOException {
    7.59                  w.flush();
    7.60              }
    7.61 -        }, null);
    7.62 +        });
    7.63      }
    7.64      
    7.65      public static Writer createBuffered(final Writer out) {
    7.66 -        class Delegate extends java.io.Writer {
    7.67 -            @Override
    7.68 -            public void write(char[] cbuf, int off, int len) throws IOException {
    7.69 -                out.write(cbuf, off, len);
    7.70 -            }
    7.71 -
    7.72 -            @Override
    7.73 -            public void flush() throws IOException {
    7.74 -                out.flush();
    7.75 -            }
    7.76 -
    7.77 -            @Override
    7.78 -            public void close() throws IOException {
    7.79 -                out.close();
    7.80 -            }
    7.81 -            
    7.82 -        }
    7.83 -        return create(new BufferedWriter(new Delegate()));
    7.84 +        return create(new SimpleBuffer(out));
    7.85      }
    7.86      
    7.87      
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/samples/delegatingwriterfinal/src-test1.0/api/usage/CryptoWriter.java	Sat Jun 14 09:53:07 2008 +0200
     8.3 @@ -0,0 +1,60 @@
     8.4 +
     8.5 +package api.usage;
     8.6 +
     8.7 +import api.Writer;
     8.8 +import java.io.IOException;
     8.9 +
    8.10 +
    8.11 +/** Writer alters each char from 'A' to 'Z' range with next one just like
    8.12 + * old Romans did.
    8.13 + *
    8.14 + * @author Jaroslav Tulach
    8.15 + */
    8.16 +public class CryptoWriter implements Writer.Impl {
    8.17 +    private Writer out;
    8.18 +    
    8.19 +    private CryptoWriter(Writer out) {
    8.20 +        this.out = out;
    8.21 +    }
    8.22 +    
    8.23 +    
    8.24 +    public static Writer create(Writer out) {
    8.25 +        return Writer.create(new CryptoWriter(out));
    8.26 +    }
    8.27 +    
    8.28 +    @Override
    8.29 +    public void write(char[] cbuf, int off, int len) throws IOException {
    8.30 +        char[] arr = new char[len];
    8.31 +        for (int i = 0; i < len; i++) {
    8.32 +            arr[i] = convertChar(cbuf[off + i]);
    8.33 +        }
    8.34 +        out.write(arr, 0, len);
    8.35 +    }
    8.36 +
    8.37 +    @Override
    8.38 +    public void write(String str, int off, int len) throws IOException {
    8.39 +        StringBuffer sb = new StringBuffer();
    8.40 +        for (int i = 0; i < len; i++) {
    8.41 +            sb.append(convertChar(str.charAt(off + i)));
    8.42 +        }
    8.43 +        out.write(sb.toString(), 0, len);
    8.44 +    }
    8.45 +
    8.46 +    private char convertChar(int c) {
    8.47 +        if (c == 'Z') {
    8.48 +            return 'A';
    8.49 +        }
    8.50 +        if (c == 'z') {
    8.51 +            return 'a';
    8.52 +        }
    8.53 +        return (char)(c + 1);
    8.54 +    }
    8.55 +
    8.56 +    public void close() throws IOException {
    8.57 +        out.close();
    8.58 +    }
    8.59 +
    8.60 +    public void flush() throws IOException {
    8.61 +        out.flush();
    8.62 +    }
    8.63 +}