Home | History | Annotate | Download | only in util
      1 
      2 /*
      3  *******************************************************************************
      4  * Copyright (C) 2002-2012, International Business Machines Corporation and    *
      5  * others. All Rights Reserved.                                                *
      6  *******************************************************************************
      7  */
      8 package com.ibm.icu.dev.util;
      9 
     10 import java.util.ArrayList;
     11 import java.util.List;
     12 
     13 public abstract class Tabber {
     14     public static final byte LEFT = 0, CENTER = 1, RIGHT = 2;
     15     private static final String[] ALIGNMENT_NAMES = {"Left", "Center", "Right"};
     16 
     17     /**
     18      * Repeats a string n times
     19      * @param source
     20      * @param times
     21      */
     22     // TODO - optimize repeats using doubling?
     23     public static String repeat(String source, int times) {
     24         if (times <= 0) return "";
     25         if (times == 1) return source;
     26         StringBuffer result = new StringBuffer();
     27         for (; times > 0; --times) {
     28             result.append(source);
     29         }
     30         return result.toString();
     31     }
     32 
     33     public String process(String source) {
     34         StringBuffer result = new StringBuffer();
     35         int lastPos = 0;
     36         for (int count = 0; lastPos < source.length(); ++count) {
     37             int pos = source.indexOf('\t', lastPos);
     38             if (pos < 0) pos = source.length();
     39             process_field(count, source, lastPos, pos, result);
     40             lastPos = pos+1;
     41         }
     42         return prefix + result.toString() + postfix;
     43     }
     44 
     45     private String prefix = "";
     46     private String postfix = "";
     47 
     48     public abstract void process_field(int count, String source, int start, int limit, StringBuffer output);
     49 
     50     public Tabber clear() {
     51         return this;
     52     }
     53 
     54     public static class MonoTabber extends Tabber {
     55         int minGap = 0;
     56 
     57         private List stops = new ArrayList();
     58         private List types = new ArrayList();
     59 
     60         public Tabber clear() {
     61             stops.clear();
     62             types.clear();
     63             minGap = 0;
     64             return this;
     65         }
     66 
     67         public String toString() {
     68             StringBuffer buffer = new StringBuffer();
     69             for (int i = 0; i < stops.size(); ++i) {
     70                 if (i != 0) buffer.append("; ");
     71                 buffer
     72                 .append(ALIGNMENT_NAMES[((Integer)types.get(i)).intValue()])
     73                 .append(",")
     74                 .append(stops.get(i));
     75             }
     76             return buffer.toString();
     77         }
     78 
     79         /**
     80          * Adds tab stop and how to align the text UP TO that stop
     81          * @param tabPos
     82          * @param type
     83          */
     84         public MonoTabber addAbsolute(int tabPos, int type) {
     85             stops.add(new Integer(tabPos));
     86             types.add(new Integer(type));
     87             return this;
     88         }
     89 
     90         /**
     91          * Adds relative tab stop and how to align the text UP TO that stop
     92          */
     93         public Tabber add(int fieldWidth, byte type) {
     94             int last = getStop(stops.size()-1);
     95             stops.add(new Integer(last + fieldWidth));
     96             types.add(new Integer(type));
     97             return this;
     98         }
     99 
    100         public int getStop(int fieldNumber) {
    101             if (fieldNumber < 0) return 0;
    102             if (fieldNumber >= stops.size()) fieldNumber = stops.size() - 1;
    103             return ((Integer)stops.get(fieldNumber)).intValue();
    104         }
    105         public int getType(int fieldNumber) {
    106             if (fieldNumber < 0) return LEFT;
    107             if (fieldNumber >= stops.size()) return LEFT;
    108             return ((Integer)types.get(fieldNumber)).intValue();
    109         }
    110         /*
    111         public String process(String source) {
    112             StringBuffer result = new StringBuffer();
    113             int lastPos = 0;
    114             int count = 0;
    115             for (count = 0; lastPos < source.length() && count < stops.size(); count++) {
    116                 int pos = source.indexOf('\t', lastPos);
    117                 if (pos < 0) pos = source.length();
    118                 String piece = source.substring(lastPos, pos);
    119                 int stopPos = getStop(count);
    120                 if (result.length() < stopPos) {
    121                     result.append(repeat(" ", stopPos - result.length()));
    122                     // TODO fix type
    123                 }
    124                 result.append(piece);
    125                 lastPos = pos+1;
    126             }
    127             if (lastPos < source.length()) {
    128                 result.append(source.substring(lastPos));
    129             }
    130             return result.toString();
    131         }
    132         */
    133 
    134         public void process_field(int count, String source, int start, int limit, StringBuffer output) {
    135             String piece = source.substring(start, limit);
    136             int startPos = getStop(count-1);
    137             int endPos = getStop(count) - minGap;
    138             int type = getType(count);
    139             switch (type) {
    140                 case LEFT:
    141                     break;
    142                 case RIGHT:
    143                     startPos = endPos - piece.length();
    144                     break;
    145                 case CENTER:
    146                     startPos = (startPos + endPos - piece.length() + 1)/2;
    147                     break;
    148             }
    149 
    150             int gap = startPos - output.length();
    151             if (count != 0 && gap < minGap) gap = minGap;
    152             if (gap > 0) output.append(repeat(" ", gap));
    153             output.append(piece);
    154         }
    155 
    156     }
    157 
    158     public static Tabber NULL_TABBER = new Tabber() {
    159         public void process_field(int count, String source, int start, int limit, StringBuffer output) {
    160             if (count > 0) output.append( "\t");
    161             output.append(source.substring(start, limit));
    162         }
    163     };
    164 
    165     public static class HTMLTabber extends Tabber {
    166         private List<String> parameters = new ArrayList();
    167         private String element = "td";
    168         {
    169             setPrefix("<tr>");
    170             setPostfix("</tr>");
    171         }
    172         public HTMLTabber setParameters(int count, String params) {
    173             // fill in
    174             while (parameters.size() <= count) {
    175                 parameters.add(null);
    176             }
    177             parameters.set(count,params);
    178             return this;
    179         }
    180 
    181         public String getElement() {
    182             return element;
    183         }
    184 
    185         public HTMLTabber setElement(String element) {
    186             this.element = element;
    187             return this;
    188         }
    189 
    190         public void process_field(int count, String source, int start, int limit, StringBuffer output) {
    191             output.append("<" + element);
    192             String params = null;
    193             if (count < parameters.size()) {
    194                 params = parameters.get(count);
    195             }
    196             if (params != null) {
    197                 output.append(' ');
    198                 output.append(params);
    199             }
    200             output.append(">");
    201             output.append(source.substring(start, limit));
    202             // TODO Quote string
    203             output.append("</" + element + ">");
    204         }
    205     }
    206     /**
    207      */
    208     public String getPostfix() {
    209         return postfix;
    210     }
    211 
    212     /**
    213      */
    214     public String getPrefix() {
    215         return prefix;
    216     }
    217 
    218     /**
    219      * @param string
    220      */
    221     public Tabber setPostfix(String string) {
    222         postfix = string;
    223         return this;
    224     }
    225 
    226     /**
    227      * @param string
    228      */
    229     public Tabber setPrefix(String string) {
    230         prefix = string;
    231         return this;
    232     }
    233 
    234     public Tabber add(int i, byte left2) {
    235         // does nothing unless overridden
    236         return this;
    237     }
    238 
    239 }
    240