001: /*
002: *******************************************************************************
003: * Copyright (C) 2002-2006, International Business Machines Corporation and *
004: * others. All Rights Reserved. *
005: *******************************************************************************
006: */
007: package com.ibm.icu.dev.test.util;
008:
009: import java.util.ArrayList;
010: import java.util.List;
011:
012: public abstract class Tabber {
013: public static final byte LEFT = 0, CENTER = 1, RIGHT = 2;
014: private static final String[] ALIGNMENT_NAMES = { "Left", "Center",
015: "Right" };
016:
017: /**
018: * Repeats a string n times
019: * @param source
020: * @param times
021: */
022: // TODO - optimize repeats using doubling?
023: public static String repeat(String source, int times) {
024: if (times <= 0)
025: return "";
026: if (times == 1)
027: return source;
028: StringBuffer result = new StringBuffer();
029: for (; times > 0; --times) {
030: result.append(source);
031: }
032: return result.toString();
033: }
034:
035: public String process(String source) {
036: StringBuffer result = new StringBuffer();
037: int lastPos = 0;
038: for (int count = 0; lastPos < source.length(); ++count) {
039: int pos = source.indexOf('\t', lastPos);
040: if (pos < 0)
041: pos = source.length();
042: process_field(count, source, lastPos, pos, result);
043: lastPos = pos + 1;
044: }
045: return prefix + result.toString() + postfix;
046: }
047:
048: private String prefix = "";
049: private String postfix = "";
050:
051: public abstract void process_field(int count, String source,
052: int start, int limit, StringBuffer output);
053:
054: public Tabber clear() {
055: return this ;
056: }
057:
058: public static class MonoTabber extends Tabber {
059: int minGap = 0;
060:
061: private List stops = new ArrayList();
062: private List types = new ArrayList();
063:
064: public Tabber clear() {
065: stops.clear();
066: types.clear();
067: minGap = 0;
068: return this ;
069: }
070:
071: public String toString() {
072: StringBuffer buffer = new StringBuffer();
073: for (int i = 0; i < stops.size(); ++i) {
074: if (i != 0)
075: buffer.append("; ");
076: buffer.append(
077: ALIGNMENT_NAMES[((Integer) types.get(i))
078: .intValue()]).append(",").append(
079: stops.get(i));
080: }
081: return buffer.toString();
082: }
083:
084: /**
085: * Adds tab stop and how to align the text UP TO that stop
086: * @param tabPos
087: * @param type
088: */
089: public MonoTabber addAbsolute(int tabPos, int type) {
090: stops.add(new Integer(tabPos));
091: types.add(new Integer(type));
092: return this ;
093: }
094:
095: /**
096: * Adds relative tab stop and how to align the text UP TO that stop
097: */
098: public Tabber add(int fieldWidth, byte type) {
099: int last = getStop(stops.size() - 1);
100: stops.add(new Integer(last + fieldWidth));
101: types.add(new Integer(type));
102: return this ;
103: }
104:
105: public int getStop(int fieldNumber) {
106: if (fieldNumber < 0)
107: return 0;
108: if (fieldNumber >= stops.size())
109: fieldNumber = stops.size() - 1;
110: return ((Integer) stops.get(fieldNumber)).intValue();
111: }
112:
113: public int getType(int fieldNumber) {
114: if (fieldNumber < 0)
115: return LEFT;
116: if (fieldNumber >= stops.size())
117: return LEFT;
118: return ((Integer) types.get(fieldNumber)).intValue();
119: }
120:
121: /*
122: public String process(String source) {
123: StringBuffer result = new StringBuffer();
124: int lastPos = 0;
125: int count = 0;
126: for (count = 0; lastPos < source.length() && count < stops.size(); count++) {
127: int pos = source.indexOf('\t', lastPos);
128: if (pos < 0) pos = source.length();
129: String piece = source.substring(lastPos, pos);
130: int stopPos = getStop(count);
131: if (result.length() < stopPos) {
132: result.append(repeat(" ", stopPos - result.length()));
133: // TODO fix type
134: }
135: result.append(piece);
136: lastPos = pos+1;
137: }
138: if (lastPos < source.length()) {
139: result.append(source.substring(lastPos));
140: }
141: return result.toString();
142: }
143: */
144:
145: public void process_field(int count, String source, int start,
146: int limit, StringBuffer output) {
147: String piece = source.substring(start, limit);
148: int startPos = getStop(count - 1);
149: int endPos = getStop(count) - minGap;
150: int type = getType(count);
151: switch (type) {
152: case LEFT:
153: break;
154: case RIGHT:
155: startPos = endPos - piece.length();
156: break;
157: case CENTER:
158: startPos = (startPos + endPos - piece.length() + 1) / 2;
159: break;
160: }
161:
162: int gap = startPos - output.length();
163: if (count != 0 && gap < minGap)
164: gap = minGap;
165: if (gap > 0)
166: output.append(repeat(" ", gap));
167: output.append(piece);
168: }
169:
170: }
171:
172: public static class HTMLTabber extends Tabber {
173: private List parameters = new ArrayList();
174: {
175: setPrefix("<tr>");
176: setPostfix("</tr>");
177: }
178:
179: public void setParameters(int count, String params) {
180: while (count >= parameters.size())
181: parameters.add(null);
182: parameters.set(count, params);
183: }
184:
185: public void process_field(int count, String source, int start,
186: int limit, StringBuffer output) {
187: output.append("<td");
188: String params = null;
189: if (count < parameters.size())
190: params = (String) parameters.get(count);
191: if (params != null) {
192: output.append(' ');
193: output.append(params);
194: }
195: output.append(">");
196: output.append(source.substring(start, limit));
197: // TODO Quote string
198: output.append("</td>");
199: }
200: }
201:
202: /**
203: */
204: public String getPostfix() {
205: return postfix;
206: }
207:
208: /**
209: */
210: public String getPrefix() {
211: return prefix;
212: }
213:
214: /**
215: * @param string
216: */
217: public Tabber setPostfix(String string) {
218: postfix = string;
219: return this ;
220: }
221:
222: /**
223: * @param string
224: */
225: public Tabber setPrefix(String string) {
226: prefix = string;
227: return this ;
228: }
229:
230: public Tabber add(int i, byte left2) {
231: // does nothing unless overridden
232: return this;
233: }
234:
235: }
|