KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > tanesha > replacer > ReplacerFormat


1 /*
2  * libreplacer, Java library to support C-sprintf alike text formatting
3  * Copyright (C) 2002 Tanesha FTPD Project, www.tanesha.net
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  */

19 /*
20  * $Id: ReplacerFormat.java,v 1.8 2002/12/12 13:06:48 flower Exp $
21  */

22 package org.tanesha.replacer;
23
24 import org.tanesha.replacer.formatters.StringFormatter;
25 import java.util.*;
26
27 /***
28  * Handles parsing the format string.
29  * <p>
30  * ${param[,[-]width[,max]]}
31  *
32  * @author Soren, www.tanesha.net
33  */

34 public class ReplacerFormat {
35
36     public static final boolean LEFT = true;
37     public static final boolean RIGHT = false;
38     public static final int UNDEF = -1;
39
40     // default start of a replacement token
41
public static final String JavaDoc REPLACER_START = "${";
42
43     // default end of a replacement token
44
public static final String JavaDoc REPLACER_END = "}";
45
46     /**
47      * Create a new ReplacerFormat from a string.
48      *
49      * @param input the String containing the format
50      * @throws FormatterException if the string contains an invalid format for formatting.
51      */

52     public static ReplacerFormat createFormat(String JavaDoc input) throws FormatterException {
53         return createFormat(input, REPLACER_START, REPLACER_END);
54     }
55
56     /**
57      * Create ReplacerFormat using alternative start/end tokens.
58      */

59     public static ReplacerFormat createFormat(String JavaDoc input, String JavaDoc start, String JavaDoc end)
60         throws FormatterException {
61
62         return new ReplacerFormat(input, start, end);
63     }
64
65
66     private List _items = new LinkedList();
67     private String JavaDoc _input;
68
69     private ReplacerFormat(String JavaDoc input, String JavaDoc start, String JavaDoc end) throws FormatterException {
70
71         _input = input;
72         parseFormat(start, end);
73     }
74
75     public String JavaDoc toString() {
76         return "[ReplacerFormat" + _items.toString() + "]";
77     }
78
79     private void parseFormat(String JavaDoc start, String JavaDoc end) throws FormatterException {
80
81         try {
82
83
84             int offset = 0;
85             int inputlength = _input.length();
86
87             while (offset < inputlength) {
88
89                 int nextd = _input.indexOf(start, offset);
90
91                 if (nextd == -1)
92                     break;
93
94                 int nexte = _input.indexOf(end, nextd);
95
96                 // error, ${ without ending }
97
if (nexte == -1)
98                     throw new FormatterException("Start-tag without end-tag.");
99
100                 String JavaDoc foundKey = _input.substring(nextd + start.length(), nexte);
101                 
102                 _items.add(new PlainTextElement(_input.substring(offset, nextd)));
103
104                 _items.add(new ExpandingElement(foundKey));
105
106                 offset = nexte + end.length();
107             }
108
109             // add trail
110
if (offset < inputlength)
111                 _items.add(new PlainTextElement(_input.substring(offset, inputlength)));
112         }
113         catch (Exception JavaDoc e) {
114             throw new FormatterException(e.getMessage());
115         }
116
117     }
118
119
120     protected String JavaDoc format(ReplacerEnvironment env) {
121
122         StringBuffer JavaDoc out = new StringBuffer JavaDoc();
123
124         for (Iterator i = _items.iterator(); i.hasNext(); ) {
125
126             Object JavaDoc o = i.next();
127
128             if (o instanceof PlainTextElement) {
129
130                 out.append(((PlainTextElement)o).getText());
131             }
132             else if (o instanceof ExpandingElement) {
133
134                 formatExpanding(out, env, (ExpandingElement) o);
135             }
136
137         }
138
139         return out.toString();
140     }
141
142     private static void formatExpanding(StringBuffer JavaDoc buf,
143                                         ReplacerEnvironment env, ExpandingElement elem) {
144
145
146         Object JavaDoc rep = env.resolve(elem.param());
147
148         // could not be resolved.
149
if (rep == null) {
150             buf.append(elem.orig());
151             return;
152         }
153
154         if (rep instanceof String JavaDoc)
155             formatString(buf, (String JavaDoc) rep, elem);
156         else if (rep instanceof Double JavaDoc)
157             formatDouble(buf, (Double JavaDoc) rep, elem);
158         else if (rep instanceof StringFormatter)
159             formatStringFormatter(buf, (StringFormatter) rep, elem);
160         else
161             formatString(buf, rep.toString(), elem);
162     }
163
164     private static void formatStringFormatter(StringBuffer JavaDoc buf, StringFormatter f, ExpandingElement elem) {
165
166         buf.append(f.format(elem.align(), elem.width(), elem.max()));
167     }
168
169     private static void formatDouble(StringBuffer JavaDoc buf, Double JavaDoc d, ExpandingElement elem) {
170
171         boolean minus = false;
172
173         String JavaDoc t = d.toString();
174
175         // System.out.println("double = " + t);
176

177         if (t.startsWith("-")) {
178             minus = true;
179             t = t.substring(1);
180         }
181
182         // 1234.321E12
183
int dPoint = t.indexOf(".");
184         int ePoint = t.indexOf("E");
185
186         List num = new LinkedList();
187         List dec = new LinkedList();
188         List tho = new LinkedList();
189
190         List cur = num;
191
192         byte b[] = t.getBytes();
193         for (int j = 0; j < b.length; j++) {
194
195             if (j == dPoint)
196                 cur = dec;
197             else if (j == ePoint)
198                 cur = tho;
199             else
200                 cur.add(new Character JavaDoc((char) b[j]));
201         }
202
203         if (ePoint != -1) {
204             // correct for E<10th>
205
String JavaDoc sCorrect = "";
206             for (Iterator thoi = tho.iterator(); thoi.hasNext(); )
207                 sCorrect += ((Character JavaDoc) thoi.next()).charValue();
208
209             if (!"".equals(sCorrect)) {
210
211                 int correct = Integer.parseInt(sCorrect);
212
213                 for (int j = 0; j < correct; j++) {
214
215                     if (dec.size() > 0)
216                         num.add(dec.remove(0));
217                     else
218                         num.add(new Character JavaDoc('0'));
219
220                     // System.out.println("num = " + num + ", dec = " + dec);
221
}
222             }
223         }
224
225         StringBuffer JavaDoc sDec = new StringBuffer JavaDoc();
226         for (int j = 0; j < elem.max(); j++)
227             if (dec.size() > 0)
228                 sDec.append(((Character JavaDoc)dec.remove(0)).charValue());
229             else
230                 sDec.append('0');
231
232         StringBuffer JavaDoc sNum = new StringBuffer JavaDoc();
233
234         if (sDec.length() > 0)
235             sNum.append(".").append(sDec);
236
237         if (elem.width() == UNDEF) {
238             // no width specified
239

240             while (num.size() > 0)
241                 sNum.insert(0, ((Character JavaDoc)num.remove(num.size() - 1)).charValue());
242
243         } else {
244             // width specified
245
while (sNum.length() < elem.width()) {
246
247                 if (num.size() > 0)
248                     sNum.insert(0, ((Character JavaDoc)num.remove(num.size() - 1)).charValue());
249                 else {
250                     if (elem.align() == RIGHT)
251                         sNum.insert(0, ' ');
252                     else
253                         sNum.append(' ');
254                 }
255             }
256
257         }
258
259         buf.append(sNum);
260
261     }
262
263     private static void formatString(StringBuffer JavaDoc buf, String JavaDoc str, ExpandingElement elem) {
264
265         boolean align = elem.align();
266         int width = elem.width();
267         int max = elem.max();
268         int delta = UNDEF;
269
270         if (width != UNDEF && str.length() < width)
271             delta = width - str.length();
272
273         if (max != UNDEF && str.length() > max) {
274             str = str.substring(0, max);
275             delta = UNDEF;
276         }
277
278
279         if (delta != UNDEF && align == RIGHT)
280             for (int i = 0; i < delta; i++)
281                 buf.append(" ");
282
283         buf.append(str);
284
285         if (delta != UNDEF && align == LEFT)
286             for (int i = 0; i < delta; i++)
287                 buf.append(" ");
288     }
289
290     private class PlainTextElement {
291         private String JavaDoc _text;
292
293         public PlainTextElement(String JavaDoc text) {
294             _text = text;
295         }
296         public String JavaDoc getText() {
297             return _text;
298         }
299     }
300
301     private class ExpandingElement {
302         private boolean _align = RIGHT;
303         private int _width = UNDEF;
304         private int _max = UNDEF;
305         private String JavaDoc _param;
306         private String JavaDoc _orig;
307
308         public ExpandingElement(String JavaDoc orig) throws Exception JavaDoc {
309
310             _orig = orig;
311
312             int c = orig.indexOf(",");
313
314             if (c == -1) {
315                 _param = orig;
316                 return;
317             }
318
319             _param = orig.substring(0, c);
320             orig = orig.substring(c + 1);
321
322             char first = orig.charAt(0);
323             if (first == '-') {
324                 _align = LEFT;
325                 orig = orig.substring(1);
326             }
327
328             c = orig.indexOf(".");
329
330             if (c == -1) {
331                 _width = Integer.parseInt(orig);
332                 return ;
333             }
334
335             if (c > 0)
336                 _width = Integer.parseInt(orig.substring(0, c));
337             else
338                 _width = UNDEF;
339
340             _max = Integer.parseInt(orig.substring(c + 1));
341
342         }
343
344         public String JavaDoc orig() {
345             return _orig;
346         }
347         public String JavaDoc param() {
348             return _param;
349         }
350         public boolean align() {
351             return _align;
352         }
353         public int width() {
354             return _width;
355         }
356         public int max() {
357             return _max;
358         }
359         public String JavaDoc toString() {
360             return _orig;
361         }
362     }
363
364 }
365
Popular Tags