samples/delegatingwriter/src/org/apidesign/delegatingwriter/AltBufferedWriter.java
author Jaroslav Tulach <jtulach@netbeans.org>
Sat, 14 Jun 2008 09:53:07 +0200
changeset 67 b029a28df444
parent 64 7b26c64804c2
child 69 26ef4b4bbf67
permissions -rw-r--r--
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
     1 /*
     2  * To change this template, choose Tools | Templates
     3  * and open the template in the editor.
     4  */
     5 
     6 package org.apidesign.delegatingwriter;
     7 
     8 import java.io.BufferedWriter;
     9 import java.io.IOException;
    10 import java.io.Writer;
    11 
    12 /**
    13  * This is a regular {@link BufferedWriter}, just its implementation
    14  * of the append method can choose from three options. This allows us to
    15  * simulate the potential pros and cons of various possible implementations.
    16  * 
    17  * @author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    18  */
    19 public class AltBufferedWriter extends BufferedWriter {
    20     private final Writer out;
    21     private final Behaviour behaviour;
    22     
    23     public AltBufferedWriter(Writer out) {
    24         // behave exactly like BufferedWriter in 1.5 behaves
    25         this(out, Behaviour.DELEGATE_TO_SUPER);
    26     }
    27     public AltBufferedWriter(Writer out, Behaviour behaviour) {
    28         super(out);
    29         this.out = out;
    30         this.behaviour = behaviour;
    31     }
    32     
    33     @Override
    34     public Writer append(CharSequence csq) throws IOException {
    35         switch (behaviour) {
    36             case THROW_EXCEPTION: return appendThrowException(csq); 
    37             case DELEGATE_TO_SUPER: return appendDelegateToSuper(csq);
    38             case DELEGATE_TO_OUT: return appendDelegateToUnderlaying(csq);
    39             case DELEGATE_CONDITIONALLY: return appendDelegateConditionally(csq);
    40             default: throw new IllegalStateException("Unknown" + behaviour);
    41         }
    42     }
    43     
    44     public Writer appendThrowException(CharSequence csq) throws IOException {
    45         /* in case of real code, this would be part of the regular append method BEGIN: writer.throw
    46     public Writer append(CharSequence csq) throws IOException {
    47         /* thrown an exception as this method is new and subclasses need to override it */
    48         throw new UnsupportedOperationException();
    49     }
    50     // END: writer.throw
    51     
    52     public Writer appendDelegateToSuper(CharSequence csq) throws IOException {
    53         // non-efficient variant of delegating via converting to String first 
    54         // and using one of methods that existed in 1.4
    55         // BEGIN: writer.throw.client
    56         if (csq == null) {
    57             write("null");
    58         } else {
    59             write(csq.toString());
    60         }
    61         return this;
    62         // END: writer.throw.client
    63     }
    64     
    65     public Writer appendDelegateToUnderlaying(CharSequence csq) throws IOException {
    66         // BEGIN: writer.delegateout
    67         // efficient, yet dangerous delegation skipping methods unknown to 
    68         // subclasses that used version 1.4
    69         if (csq != null && csq.length() < 1024) {
    70             write(csq.toString());
    71         } else {
    72             flush();
    73             out.append(csq);
    74         }
    75         return this;
    76         // END: writer.delegateout
    77     }
    78 
    79     private Writer appendDelegateConditionally(CharSequence csq) throws IOException {
    80         // BEGIN: writer.conditionally
    81         boolean isOverriden = false;
    82         try {
    83             isOverriden = 
    84                 (getClass().getMethod("write", String.class).getDeclaringClass() != Writer.class) ||
    85                 (getClass().getMethod("write", Integer.TYPE).getDeclaringClass() != BufferedWriter.class) ||
    86                 (getClass().getMethod("write", String.class, Integer.TYPE, Integer.TYPE).getDeclaringClass() != BufferedWriter.class);
    87         } catch (Exception ex) {
    88             throw new IOException(ex);
    89         }
    90         
    91         if (isOverriden || (csq != null && csq.length() < 1024)) {
    92             write(csq.toString());
    93         } else {
    94             flush();
    95             out.append(csq);
    96         }
    97         return this;
    98         // END: writer.conditionally
    99     }
   100     
   101     public enum Behaviour {
   102         THROW_EXCEPTION, DELEGATE_TO_SUPER, DELEGATE_TO_OUT, DELEGATE_CONDITIONALLY
   103     }
   104 }