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