support for CAPTCHAs
[mir.git] / source / mir / util / StringRoutines.java
1 /*
2  * Copyright (C) 2001, 2002 The Mir-coders group
3  *
4  * This file is part of Mir.
5  *
6  * Mir is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * Mir is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Mir; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  * In addition, as a special exception, The Mir-coders gives permission to link
21  * the code of this program with  any library licensed under the Apache Software License,
22  * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
23  * (or with modified versions of the above that use the same license as the above),
24  * and distribute linked combinations including the two.  You must obey the
25  * GNU General Public License in all respects for all of the code used other than
26  * the above mentioned libraries.  If you modify this file, you may extend this
27  * exception to your version of the file, but you are not obligated to do so.
28  * If you do not wish to do so, delete this exception statement from your version.
29  */
30 package mir.util;
31
32 import org.apache.oro.text.regex.*;
33
34 import java.util.ArrayList;
35 import java.util.List;
36
37 public class StringRoutines {
38
39   private StringRoutines() {
40   }
41
42   public static int indexOfCharacters(String aString, char[] aCharacters, int aFrom) {
43     int i;
44     int result=-1;
45     int position;
46
47     for (i=0; i<aCharacters.length ; i++) {
48       position = aString.indexOf(aCharacters[i], aFrom);
49
50       if (position != -1 && ( result == -1 || position < result )) {
51         result = position;
52       }
53     }
54
55     return result;
56   }
57
58   public static String replaceStringCharacters(String aText, char[] aCharactersToReplace, String[] aStringsToSubstitute) {
59     if (aText==null)
60       return null;
61
62     int position, nextPosition;
63     int i;
64     StringBuffer result = new StringBuffer();
65
66     position=0;
67     do {
68       nextPosition = StringRoutines.indexOfCharacters(aText, aCharactersToReplace, position);
69
70       if (nextPosition<0)
71         nextPosition = aText.length();
72
73       result.append(aText.substring(position, nextPosition));
74
75       if (nextPosition<aText.length())
76         for (i=0; i<aCharactersToReplace.length; i++) {
77           if (aCharactersToReplace[i] == aText.charAt(nextPosition)) {
78             result.append(aStringsToSubstitute[i]);
79             break;
80           }
81         }
82       position=nextPosition+1;
83     }
84     while (nextPosition<aText.length()) ;
85
86     return result.toString();
87   }
88
89   public static String replaceEscapedStringCharacters(String aText, char anEscapeCharacter, char[] aCharactersToReplace, String[] aStringsToSubstitute) {
90     if (aText==null)
91       return null;
92
93     int position, nextPosition;
94     int i;
95     StringBuffer result = new StringBuffer();
96
97     position=0;
98     do {
99       nextPosition = aText.indexOf(anEscapeCharacter, position);
100
101       if (nextPosition<0)
102         nextPosition = aText.length();
103
104       result.append(aText.substring(position, nextPosition));
105
106       if (nextPosition+1<aText.length()) {
107         nextPosition = nextPosition+1;
108
109         boolean found = false;
110         for (i = 0; i < aCharactersToReplace.length; i++) {
111           if (aCharactersToReplace[i] == aText.charAt(nextPosition)) {
112             result.append(aStringsToSubstitute[i]);
113             found=true;
114             break;
115           }
116         }
117
118         if (!found) {
119           result.append(aText.charAt(nextPosition));
120         }
121       }
122       position=nextPosition+1;
123     }
124     while (nextPosition<aText.length()) ;
125
126     return result.toString();
127   }
128
129   public static String interpretAsString(Object aValue) throws Exception {
130     if (aValue instanceof String)
131       return (String) aValue;
132
133     if (aValue instanceof Integer)
134       return aValue.toString();
135
136     if (aValue == null)
137       return "";
138
139     throw new Exception("String expected, "+aValue+" found");
140   }
141
142   public static int interpretAsInteger(Object aValue) throws Exception {
143     if (aValue instanceof Integer)
144       return ((Integer) aValue).intValue();
145
146     if (aValue instanceof String)
147       try {
148         return Integer.parseInt((String) aValue);
149       }
150       catch (Throwable t) {
151         throw new Exception("Integer expected, "+aValue+" found");
152       }
153
154     throw new Exception("Integer expected, "+aValue+" found");
155   }
156
157   public static String performRegularExpressionReplacement(String aSource, String aSearchExpression, String aReplacement) {
158     try {
159       Pattern pattern = new Perl5Compiler().compile(aSearchExpression);
160
161       return Util.substitute(
162               new Perl5Matcher(), pattern, new Perl5Substitution(aReplacement), aSource, Util.SUBSTITUTE_ALL);
163     }
164     catch (MalformedPatternException t) {
165       throw new UtilFailure("Invalid regular expression", t);
166     }
167   }
168
169   /**
170    * Separates a string based on a separator:
171    *     <code>seperateString("a:b:c", ":");</code> will lead to
172    *     a List with 3 Strings: <code>"a"</code>, <code>"b"</code> and <code>"c"</code>
173    *
174    * @param aString     The string to split
175    * @param aSeparator
176    * @return
177    */
178
179   public static List splitString(String aString, String aSeparator) {
180     List result= new ArrayList();
181     int previousPosition = 0;
182     int position;
183
184     if (aString!=null) {
185       while ( (position = aString.indexOf(aSeparator, previousPosition)) >= 0) {
186         result.add(aString.substring(previousPosition, position));
187         previousPosition = position + aSeparator.length();
188       }
189       result.add(aString.substring(previousPosition, aString.length()));
190     }
191
192     return result;
193   }
194
195   /**
196    * Separates a String into at most 2 parts based on a separator:
197    * <ul>
198    *   <li>
199    *     <code>seperateString("a:b:c", ":");</code> will lead to
200    *     a List with 2 Strings: <code>"a"</code> and <code>"b:c"</code>
201    *   <li>
202    *     <code>seperateString("abc", ":");</code> will lead to
203    *     a List with a single String: <code>"abc"</code>
204    * </ul>
205    *
206    *
207    * @param aString
208    * @param aSeparator
209    * @return
210    */
211   public static List separateString(String aString, String aSeparator) {
212     List result= new ArrayList();
213     int previousPosition = 0;
214     int position;
215
216     if((position = aString.indexOf(aSeparator, previousPosition))>=0) {
217       result.add(aString.substring(previousPosition, position));
218       previousPosition = position + aSeparator.length();
219     }
220
221     result.add(aString.substring(previousPosition, aString.length()));
222
223     return result;
224   }
225
226   /**
227    * Separates a string based on a separator, taking into account an escape character:
228    *     <code>seperateString("a:/::b", ":", "/");</code> will lead to
229    *     a List with 3 Strings: <code>"a"</code>, <code>":"</code> and <code>"b"</code>
230    *
231    * @param aString     The string to split
232    * @param aSeparator
233    * @return
234    */
235
236   public static List splitStringWithEscape(String aString, char aSeparator, char anEscape) {
237     List result= new ArrayList();
238     int previousPosition = 0;
239     int position;
240
241     StringBuffer currentItem = new StringBuffer();
242
243     if (aString!=null && aString.length()>0) {
244       while ((position = indexOfCharacters(aString, new char[] {aSeparator, anEscape}, previousPosition))>=0) {
245         currentItem.append(aString.substring(previousPosition, position));
246
247         if (aString.charAt(position)==aSeparator) {
248           result.add(currentItem.toString());
249           currentItem.delete(0, currentItem.length());
250         }
251         else {
252           if (aString.length()>position+1) {
253             position=position+1;
254             currentItem.append(aString.charAt(position));
255           }
256           else {
257             currentItem.append(aString.charAt(position));
258           }
259         }
260         previousPosition = position + 1;
261       }
262       currentItem.append(aString.substring(previousPosition, aString.length()));
263       result.add(currentItem.toString());
264     }
265
266     return result;
267   }
268
269   public static String replicateString(String aString, int aCount) {
270     StringBuffer result = new StringBuffer();
271
272     for (int i=0; i<aCount; i++)
273       result.append(aString);
274
275     return result.toString();
276   }
277
278   public static String replicateChar(char aCharacter, int aCount) {
279     char result[] = new char[aCount];
280
281     for (int i=0; i<aCount; i++)
282       result[i]= aCharacter;
283
284     return new String(result);
285   }
286
287   public static String padStringLeft(String aString, int aLength, char aPadCharacter) {
288     if (aString.length()<aLength)
289       return replicateChar(aPadCharacter, aLength-aString.length()) + aString;
290                 return aString;
291   }
292
293   private static final char HEX_CHARACTERS[] = {
294       '0', '1', '2', '3', '4', '5', '6', '7',
295       '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
296   };
297
298   public static String convertToHex(long aData, int aNumberOfDigits) {
299     StringBuffer result = new StringBuffer();
300
301     for (int digit = aNumberOfDigits-1; digit>=0; digit--) {
302       int value = (int) (aData >> (digit*4)) & 0xf;
303       result.append(HEX_CHARACTERS[value]);
304     }
305
306     return result.toString();
307   }
308
309   public static String convertToHex(byte[] aData) {
310     StringBuffer result = new StringBuffer();
311
312     for (int i = 0; i<aData.length; i++) {
313       result.append(convertToHex(aData[i], 2));
314
315     }
316
317     return result.toString();
318   }
319 }