• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright (C) 2003 Vladimir Roubtsov. All rights reserved.
2  *
3  * This program and the accompanying materials are made available under
4  * the terms of the Common Public License v1.0 which accompanies this distribution,
5  * and is available at http://www.eclipse.org/legal/cpl-v10.html
6  *
7  * $Id: Strings.java,v 1.1.1.1 2004/05/09 16:57:55 vlad_r Exp $
8  */
9 package com.vladium.util;
10 
11 import java.io.File;
12 import java.io.IOException;
13 import java.util.ArrayList;
14 import java.util.HashSet;
15 import java.util.List;
16 import java.util.Set;
17 import java.util.StringTokenizer;
18 
19 // ----------------------------------------------------------------------------
20 /**
21  * @author Vlad Roubtsov, (C) 2003
22  */
23 public
24 abstract class Strings
25 {
26     // public: ................................................................
27 
28 
29     public static final String WHITE_SPACE = " \t\r\n";
30 
31 
32     //TODO: add duplicate removal
toListForm(final String [] strings, final char delimiter)33     public static String toListForm (final String [] strings, final char delimiter)
34     {
35         if (strings == null) return null;
36         if (strings.length == 0) return "";
37 
38         final StringBuffer s = new StringBuffer ();
39         for (int i = 0, iLimit = strings.length; i < iLimit; ++ i)
40         {
41             if (i != 0) s.append (delimiter);
42             s.append (strings [i]);
43         }
44 
45         return s.toString ();
46     }
47 
removeDuplicates(final String [] strings, final boolean removeNull)48     public static String [] removeDuplicates (final String [] strings, final boolean removeNull)
49     {
50         if (strings == null) return strings;
51 
52         final int length = strings.length;
53         if (length == 0) return strings;
54 
55         final Set /* String */ _strings = new HashSet (length);
56         final List /* String */ _result = new ArrayList (length);
57 
58         for (int i = 0; i < length; ++ i)
59         {
60             final String s = strings [i];
61             if (removeNull && (s == null)) continue;
62 
63             if (_strings.add (s)) _result.add (s);
64         }
65 
66         final int resultLength = _result.size ();
67         if (resultLength == length)
68             return strings;
69         else
70         {
71             final String [] result = new String [resultLength];
72             _result.toArray (result);
73 
74             return result;
75         }
76     }
77 
78     /**
79      * Also removes duplicates.
80      *
81      * @param strings
82      * @param delimiters
83      * @param removeNull
84      * @return
85      */
merge(final String [] strings, final String delimiters, final boolean removeNull)86     public static String [] merge (final String [] strings, final String delimiters, final boolean removeNull)
87     {
88         if (strings == null) return strings;
89 
90         final int length = strings.length;
91         if (length == 0) return strings;
92 
93         if ((delimiters == null) || (delimiters.length () == 0))
94             throw new IllegalArgumentException ("null/empty input: delimiters");
95 
96         final Set /* String */ _strings = new HashSet (length);
97         final List /* String */ _result = new ArrayList (length);
98 
99         for (int i = 0; i < length; ++ i)
100         {
101             final String s = strings [i];
102             if (removeNull && (s == null)) continue;
103 
104             final StringTokenizer tokenizer = new StringTokenizer (s, delimiters);
105             while (tokenizer.hasMoreTokens ())
106             {
107                 final String ss = tokenizer.nextToken ();
108                 if (_strings.add (ss)) _result.add (ss);
109             }
110         }
111 
112         final String [] result = new String [_result.size ()];
113         _result.toArray (result);
114 
115         return result;
116     }
117 
118     /**
119      * Removes duplicates.
120      *
121      * @param delimiters
122      * @param processAtFiles
123      * @return
124      * @throws IOException
125      */
mergeAT(final String [] strings, final String delimiters, final boolean processAtFiles)126     public static String [] mergeAT (final String [] strings, final String delimiters, final boolean processAtFiles)
127         throws IOException
128     {
129         if (! processAtFiles)
130             return merge (strings, delimiters, true);
131         else
132         {
133             if (strings == null) return strings;
134 
135             final int length = strings.length;
136             if (length == 0) return strings;
137 
138             if ((delimiters == null) || (delimiters.length () == 0))
139                 throw new IllegalArgumentException ("null/empty input: delimiters");
140 
141             final Set /* String */ _strings = new HashSet (length);
142             final List /* String */ _result = new ArrayList (length);
143 
144             for (int i = 0; i < length; ++ i)
145             {
146                 final String s = strings [i];
147                 if (s == null) continue;
148 
149                 final StringTokenizer tokenizer = new StringTokenizer (s, delimiters);
150                 while (tokenizer.hasMoreTokens ())
151                 {
152                     final String ss = tokenizer.nextToken ();
153 
154                     if (ss.startsWith ("@"))
155                     {
156                         final String [] fileList = Files.readFileList (new File (ss.substring (1)));
157                         for (int j = 0; j < fileList.length; ++ j)
158                         {
159                             final String sss = fileList [j];
160                             if (_strings.add (sss)) _result.add (sss);
161                         }
162                     }
163                     else if (_strings.add (ss)) _result.add (ss);
164                 }
165             }
166 
167             final String [] result = new String [_result.size ()];
168             _result.toArray (result);
169 
170             return result;
171         }
172     }
173 
174     /**
175      * HTML attribute values can be quoted using either double or single quotes.
176      * Depending on the type of quote used, the other kind can be used unescaped
177      * within the attribute value. This method assumes that only double quotes
178      * are used for delimiting, hence this is the only kind that is escaped.
179      */
HTMLEscape(final String s, final StringBuffer append)180     public static void HTMLEscape (final String s, final StringBuffer append)
181     {
182         if (s == null) throw new IllegalArgumentException ("null input: s");
183         if (append == null) throw new IllegalArgumentException ("null input: append");
184 
185         final char [] chars;
186         if (USE_GET_CHARS) chars = s.toCharArray ();
187 
188         for (int i = 0, iLimit = s.length (); i < iLimit; ++ i)
189         {
190             final char c = USE_GET_CHARS ? chars [i] : s.charAt (i);
191 
192             switch (c)
193             {
194                 case '<':
195                     append.append ("&lt;");
196                     break;
197 
198                 case '>':
199                     append.append ("&gt;");
200                     break;
201 
202                 case '"':
203                     append.append ("&#34;");
204                     break;
205 
206                 case '&':
207                     append.append ("&amp;");
208                     break;
209 
210                 default:
211                     append.append (c);
212 
213             } // end of switch
214         }
215     }
216 
217     /**
218      * Same as {@link #HTMLEscape(String, StringBuffer)} but also replaces spaces
219      * with "&nbsp;"'s, which is handy for escaping code.
220      */
HTMLEscapeNB(final String s, final StringBuffer append)221     public static void HTMLEscapeNB (final String s, final StringBuffer append)
222     {
223         if (s == null) throw new IllegalArgumentException ("null input: s");
224         if (append == null) throw new IllegalArgumentException ("null input: append");
225 
226         final char [] chars;
227         if (USE_GET_CHARS) chars = s.toCharArray ();
228 
229         for (int i = 0, iLimit = s.length (); i < iLimit; ++ i)
230         {
231             final char c = USE_GET_CHARS ? chars [i] : s.charAt (i);
232 
233             switch (c)
234             {
235                 case ' ':
236                     append.append ('\u00A0'); // don't use "&#160;": a waste of space
237                     break;
238 
239                 case '\t':
240                     append.append ("\u00A0\u00A0\u00A0\u00A0\u00A0\u00A0\u00A0\u00A0"); // TODO: define a prop for this
241                     break;
242 
243 //                case '-':
244 //                    append.append ((char) 0x8209);
245 //                    break;
246 
247                 case '<':
248                     append.append ("&lt;");
249                     break;
250 
251                 case '>':
252                     append.append ("&gt;");
253                     break;
254 
255                 case '"':
256                     append.append ("&#34;");
257                     break;
258 
259                 case '&':
260                     append.append ("&amp;");
261                     break;
262 
263                 default:
264                     append.append (c);
265 
266             } // end of switch
267         }
268     }
269 
HTMLEscape(final String s)270     public static String HTMLEscape (final String s)
271     {
272         final StringBuffer buf = new StringBuffer ();
273         HTMLEscape (s, buf);
274 
275         return buf.toString ();
276     }
277 
HTMLEscapeSP(final String s)278     public static String HTMLEscapeSP (final String s)
279     {
280         final StringBuffer buf = new StringBuffer ();
281         HTMLEscapeNB (s, buf);
282 
283         return buf.toString ();
284     }
285 
286     // protected: .............................................................
287 
288     // package: ...............................................................
289 
290     // private: ...............................................................
291 
292 
Strings()293     private Strings () {} // prevent subclassing
294 
295 
296     private static final boolean USE_GET_CHARS = true;
297 
298 } // end of class
299 // ----------------------------------------------------------------------------