KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > genimen > djeneric > util > DjStringReplacer


1 /*
2  * Copyright (c) 2001-2005 by Genimen BV (www.genimen.com) All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without modification, is permitted
5  * provided that the following conditions are met:
6  * - Redistributions of source code must retain the above copyright notice, this list of conditions
7  * and the following disclaimer.
8  * - Redistributions in binary form must reproduce the above copyright notice, this list of
9  * conditions and the following disclaimer in the documentation and/or other materials
10  * provided with the distribution.
11  * - All advertising materials mentioning features or use of this software must display the
12  * following acknowledgment: "This product includes Djeneric."
13  * - Products derived from this software may not be called "Djeneric" nor may
14  * "Djeneric" appear in their names without prior written permission of Genimen BV.
15  * - Redistributions of any form whatsoever must retain the following acknowledgment: "This
16  * product includes Djeneric."
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL GENIMEN BV, DJENERIC.ORG,
22  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */

30 package com.genimen.djeneric.util;
31
32 import java.util.Vector JavaDoc;
33
34 public class DjStringReplacer
35 {
36   static final String JavaDoc LINEFEED = new String JavaDoc(System.getProperty("line.separator", "\n"));
37
38   public class PairPosition
39   { // #repeat(gname)\n
40
public int posStartKeywordS = -1; // ^
41
public int posStartKeywordE = -1; // ^
42
public int posEndKeywordS = -1; // ^
43
public int posEndKeywordE = -1; // ^
44
public Vector JavaDoc arguments = new Vector JavaDoc(0, 1); // "gname"
45
}
46
47   private String JavaDoc source;
48   private String JavaDoc currentSeps;
49
50   private static final String JavaDoc sqlSeps = "%*()-+=:;'\",.<>/|\t\r\n ";
51   private static final String JavaDoc javaSeps = "~![]{}\\?^&%*()-+=:;'\",.<>/|\t\r\n ";
52
53   public DjStringReplacer(String JavaDoc theSource)
54   {
55     source = theSource;
56     currentSeps = javaSeps;
57   }
58
59   public void useSqlSeps()
60   {
61     currentSeps = sqlSeps;
62   }
63
64   public void useJavaSeps()
65   {
66     currentSeps = javaSeps;
67   }
68
69   public final String JavaDoc replace(String JavaDoc fromStr, String JavaDoc toStr, boolean caseSensitive)
70   {
71     if (fromStr.length() == 0) return (source);
72
73     int offset;
74
75     // Both branches deliberately split because of performance gains
76
if (caseSensitive)
77     {
78       offset = source.indexOf(fromStr);
79
80       if (offset == -1) return source; // Nothing found. Just return...
81

82       if (toStr == null) toStr = "";
83
84       int toLen = toStr.length();
85       int fromLen = fromStr.length();
86       StringBuffer JavaDoc work;
87       if (toLen > fromLen) work = new StringBuffer JavaDoc(source.length() + (source.length() / 2));
88       else work = new StringBuffer JavaDoc(source.length());
89
90       work.append(source.substring(0, offset));
91
92       int newOffset;
93       while (offset >= 0)
94       {
95         work.append(toStr);
96         offset += fromLen;
97         newOffset = source.indexOf(fromStr, offset);
98         if (newOffset >= 0) work.append(source.substring(offset, newOffset));
99         else work.append(source.substring(offset));
100         offset = newOffset;
101       }
102       source = work.toString();
103     }
104     else
105     {
106       fromStr = fromStr.toLowerCase();
107       String JavaDoc compStr = source.toLowerCase();
108       offset = compStr.indexOf(fromStr);
109
110       if (offset == -1) return source; // Nothing found. Just return...
111

112       if (toStr == null) toStr = "";
113       int toLen = toStr.length();
114       int fromLen = fromStr.length();
115
116       StringBuffer JavaDoc work;
117       if (toLen > fromLen) work = new StringBuffer JavaDoc(source.length() + (source.length() / 2));
118       else work = new StringBuffer JavaDoc(source.length());
119
120       work.append(source.substring(0, offset));
121
122       int newOffset;
123       while (offset >= 0)
124       {
125         work.append(toStr);
126         offset += fromLen;
127         newOffset = compStr.indexOf(fromStr, offset);
128         if (newOffset >= 0) work.append(source.substring(offset, newOffset));
129         else work.append(source.substring(offset));
130         offset = newOffset;
131       }
132       source = work.toString();
133     }
134
135     return (source);
136   }
137
138   public final String JavaDoc replace(String JavaDoc fromStr, String JavaDoc toStr)
139   {
140     return (replace(fromStr, toStr, false));
141   }
142
143   public final String JavaDoc replaceUsingSeps(String JavaDoc fromStr, String JavaDoc toStr, String JavaDoc seps, boolean caseSensitive)
144   {
145     if (fromStr.length() == 0) return (source);
146
147     int offset;
148     int toLen = toStr.length();
149     boolean skip;
150
151     if (caseSensitive) offset = source.indexOf(fromStr);
152     else offset = source.toUpperCase().indexOf(fromStr.toUpperCase());
153
154     while (offset >= 0)
155     {
156       skip = false;
157
158       // Check character before string (if not at beginning)
159
if (offset > 0)
160       {
161         if (seps.indexOf(source.charAt(offset - 1)) == -1) skip = true;
162       }
163
164       // Check character after string (if not at end)
165
if (offset + fromStr.length() < source.length())
166       {
167         if (seps.indexOf(source.charAt(offset + fromStr.length())) == -1) skip = true;
168       }
169
170       if (!skip)
171       {
172         source = source.substring(0, offset) + toStr + source.substring(offset + fromStr.length());
173         offset += toLen;
174       }
175       else offset++;
176
177       if (caseSensitive) offset = source.indexOf(fromStr, offset);
178       else offset = source.toUpperCase().indexOf(fromStr.toUpperCase(), offset);
179     }
180     return (source);
181   }
182
183   public final String JavaDoc replaceUsingSeps(String JavaDoc fromStr, String JavaDoc toStr)
184   {
185     return (replaceUsingSeps(fromStr, toStr, currentSeps, false));
186   }
187
188   public final String JavaDoc replaceUsingSeps(String JavaDoc fromStr, String JavaDoc toStr, boolean caseSensitive)
189   {
190     return (replaceUsingSeps(fromStr, toStr, currentSeps, caseSensitive));
191   }
192
193   public final String JavaDoc getString()
194   {
195     return (source);
196   }
197
198   public final int indexOfUsingSeps(String JavaDoc subStr)
199   {
200     return (indexOfUsingSeps(subStr, 0));
201   }
202
203   public final int indexOfUsingSeps(String JavaDoc subStr, int offset)
204   {
205     boolean found;
206
207     offset = source.indexOf(subStr, offset);
208     if (offset == -1) return -1;
209
210     int len = source.length();
211     int subLen = subStr.length();
212
213     while (true)
214     {
215       found = true;
216       if (offset > 0 && currentSeps.indexOf(source.charAt(offset - 1)) == -1) found = false;
217
218       if ((offset + subLen < len) && // Make sure we don't get an out of bounds...
219
(currentSeps.indexOf(source.charAt(offset + subLen)) == -1))
220       {
221         found = false;
222       }
223       if (found) return (offset);
224
225       offset = source.indexOf(subStr, offset + 1); // Continue at next char
226
if (offset == -1) return -1;
227     }
228   }
229
230   // !!! WE ARE DELIBERATELY USING \n IN STEAD OF LINEFEED HERE!
231
// This works on PC and Unix since \r\n and \n both return expected results!
232
// Using LINEFEED can cause problems with Unix files processed on PC's!
233
public final PairPosition findFirstPair(String JavaDoc startKeyword, String JavaDoc endKeyword) throws Exception JavaDoc
234   {
235     PairPosition res = new PairPosition();
236     // start o/t keyword
237
res.posStartKeywordS = indexOfUsingSeps(startKeyword);
238     if (res.posStartKeywordS == -1) return res;
239
240     // first position of next line
241
res.posStartKeywordE = source.indexOf("\n", res.posStartKeywordS);
242     if (res.posStartKeywordE != -1) res.posStartKeywordE += 1;
243
244     // check if the start-keyword is followed by (...),
245
// if so: parse it into the arguments Vector
246
int leftParen = -1, rightParen = -1;
247     leftParen = source.indexOf('(', res.posStartKeywordS);
248
249     if (leftParen > -1 && leftParen < res.posStartKeywordE)
250     {
251       rightParen = source.indexOf(')', leftParen);
252       if (rightParen < leftParen || rightParen > res.posStartKeywordE)
253       {
254         throw new Exception JavaDoc("Unbalanced parentesis found on " + startKeyword);
255       }
256
257       StringBuffer JavaDoc s = new StringBuffer JavaDoc(source.substring(leftParen + 1, rightParen));
258
259       String JavaDoc aParam = DjString.getNextParam(s, ",", '\"', '\\');
260       while (aParam != null)
261       {
262         res.arguments.addElement(aParam);
263         aParam = DjString.getNextParam(s, ",", '\"', '\\');
264       }
265     }
266
267     // find the matching end-keyword
268
int startFound = 1; // number of startKeyword's found
269
int searchPos = res.posStartKeywordE;
270     int sourceLen = source.length();
271     int endKeyLen = endKeyword.length();
272     int startKeyLen = startKeyword.length();
273
274     while (startFound > 0)
275     {
276       int startIdx = indexOfUsingSeps(startKeyword, searchPos);
277       int endIdx = indexOfUsingSeps(endKeyword, searchPos);
278       char what = 'X';
279
280       searchPos = sourceLen;
281       if (startIdx != -1)
282       {
283         searchPos = startIdx;
284         what = 'S';
285       }
286       if ((endIdx < searchPos) && (endIdx != -1))
287       {
288         searchPos = endIdx;
289         what = 'E';
290       }
291
292       // Now searchPos points to the start or end keyword; whichever comes first OR at sourceLen (==EOF)
293

294       if (searchPos == sourceLen)
295       { // A start was found but we get here: no end keyword present!
296
int endl = source.substring(res.posStartKeywordS).indexOf('\n');
297         if (endl == -1) endl = res.posStartKeywordE;
298         String JavaDoc dbg;
299         if (endl == -1) dbg = source.substring(res.posStartKeywordS);
300         else dbg = source.substring(res.posStartKeywordS, res.posStartKeywordS + endl);
301
302         throw new Exception JavaDoc("Unmatched " + startKeyword + " found: " + dbg);
303       }
304
305       if (what == 'S')
306       {
307         startFound++; // a nested keyword
308
searchPos += startKeyLen;
309       }
310       else if (what == 'E')
311       {
312         startFound--;
313         if (startFound == 0) res.posEndKeywordS = searchPos;
314         searchPos += endKeyLen;
315       }
316       else
317       { // We should never get here
318
searchPos++;
319       }
320
321     }
322
323     if (startFound == 0) // Position end marker on the terminating ';', or at the new-line, whichever comes first
324
{
325       int semiPos = source.indexOf(';', res.posEndKeywordS);
326       int lnPos = source.indexOf("\n", res.posEndKeywordS);
327
328       res.posEndKeywordE = res.posEndKeywordS + endKeyLen;
329
330       if (lnPos < semiPos || (semiPos == -1 && lnPos != -1))
331       {
332         res.posEndKeywordE = lnPos + 1;
333       }
334       else if (semiPos < lnPos || (lnPos == -1 && semiPos != -1))
335       {
336         res.posEndKeywordE = semiPos + 1;
337       }
338     }
339     return (res);
340   }
341
342   public final PairPosition findFirstPairNoSeps(String JavaDoc startKeyword, String JavaDoc endKeyword, String JavaDoc endMarker)
343       throws Exception JavaDoc
344   {
345     PairPosition res = new PairPosition();
346     // start o/t keyword
347
res.posStartKeywordS = source.indexOf(startKeyword);
348     if (res.posStartKeywordS == -1) return res;
349
350     // first position of next line
351
res.posStartKeywordE = res.posStartKeywordS + startKeyword.length();
352
353     // check if the start-keyword is followed by (...), `
354
// if so: parse it into the arguments Vector
355
int leftParen = -1, rightParen = -1;
356     leftParen = source.indexOf('(', res.posStartKeywordS);
357
358     if (leftParen > -1 && leftParen < res.posStartKeywordE)
359     {
360       rightParen = source.indexOf(')', leftParen);
361       if (rightParen < leftParen || rightParen > res.posStartKeywordE)
362       {
363         throw new Exception JavaDoc("Unbalanced parentesis found on " + startKeyword);
364       }
365
366       StringBuffer JavaDoc s = new StringBuffer JavaDoc(source.substring(leftParen + 1, rightParen));
367
368       String JavaDoc aParam = DjString.getNextParam(s, ",", '\"', '\\');
369       while (aParam != null)
370       {
371         res.arguments.addElement(aParam);
372         aParam = DjString.getNextParam(s, ",", '\"', '\\');
373       }
374     }
375
376     // find the matching end-keyword
377
int startFound = 1; // number of startKeyword's found
378
int searchPos = res.posStartKeywordE;
379     int sourceLen = source.length();
380     int endKeyLen = endKeyword.length();
381     int startKeyLen = startKeyword.length();
382
383     while (startFound > 0)
384     {
385       int startIdx = source.indexOf(startKeyword, searchPos);
386       int endIdx = source.indexOf(endKeyword, searchPos);
387       char what = 'X';
388
389       searchPos = sourceLen;
390       if (startIdx != -1)
391       {
392         searchPos = startIdx;
393         what = 'S';
394       }
395       if ((endIdx < searchPos) && (endIdx != -1))
396       {
397         searchPos = endIdx;
398         what = 'E';
399       }
400
401       // Now searchPos points to the start or end keyword; whichever comes first OR at sourceLen (==EOF)
402

403       if (searchPos == sourceLen)
404       { // A start was found but we get here: no end keyword present!
405
int endl = source.substring(res.posStartKeywordS).indexOf('\n');
406         if (endl == -1) endl = res.posStartKeywordE;
407         String JavaDoc dbg;
408         if (endl == -1) dbg = source.substring(res.posStartKeywordS);
409         else dbg = source.substring(res.posStartKeywordS, res.posStartKeywordS + endl);
410
411         throw new Exception JavaDoc("Unmatched " + startKeyword + " found: " + dbg);
412       }
413
414       if (what == 'S')
415       {
416         startFound++; // a nested keyword
417
searchPos += startKeyLen;
418       }
419       else if (what == 'E')
420       {
421         startFound--;
422         if (startFound == 0) res.posEndKeywordS = searchPos;
423         searchPos += endKeyLen;
424       }
425       else
426       { // We should never get here
427
searchPos++;
428       }
429
430     }
431
432     if (startFound == 0) // Position end marker on the terminating ';', or at the new-line, whichever comes first
433
{
434       res.posEndKeywordE = res.posEndKeywordS + endKeyLen;
435     }
436     return (res);
437   }
438
439   public final void adjustForIndentation(PairPosition pp) throws Exception JavaDoc
440   {
441     while ((pp.posStartKeywordS > 0) && (source.charAt(pp.posStartKeywordS - 1) == ' '))
442       pp.posStartKeywordS--;
443     while ((pp.posEndKeywordS > 0) && (source.charAt(pp.posEndKeywordS - 1) == ' '))
444       pp.posEndKeywordS--;
445   }
446
447   public final String JavaDoc stripIndentation()
448   {
449     int startOfText = 0;
450     while ((startOfText < source.length())
451            && ((source.charAt(startOfText) == ' ') || (source.charAt(startOfText) == '\t')))
452       startOfText++;
453
454     String JavaDoc fromStr = "\n" + source.substring(0, startOfText);
455     source = source.substring(startOfText);
456     replace(fromStr, "\n", true);
457     return (source);
458   }
459
460   public String JavaDoc toString()
461   {
462     return getString();
463   }
464
465   /*
466    public static void main(String g[])
467    { GStringReplacer sr = new GStringReplacer("xxxx<table TESTjeDit is </table>ccTESTjevv een TESTje test TEST test TESTje");
468    try {
469    GStringReplacer.PairPosition pp = sr.findFirstPairNoSeps("<table ", "</table>");
470    } catch(Exception x) { DjLogger.log(x);}
471    }
472    */

473 }
Popular Tags