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