Added
Link Here
|
1 |
/******************************************************************************* |
2 |
* Copyright (c) 2006 IBM Corporation and others. |
3 |
* All rights reserved. This program and the accompanying materials |
4 |
* are made available under the terms of the Common Public License v1.0 |
5 |
* which accompanies this distribution, and is available at |
6 |
* http://www.eclipse.org/legal/cpl-v10.html |
7 |
* |
8 |
* Contributors: |
9 |
* Sebastian Davids <sdavids@gmx.de> - initial API and implementation |
10 |
*******************************************************************************/ |
11 |
package org.eclipse.ui.internal.texteditor; |
12 |
|
13 |
import java.util.StringTokenizer; |
14 |
|
15 |
/** |
16 |
* Helper class to provide String manipulation functions not available in |
17 |
* standard JDK. |
18 |
* |
19 |
* @since 3.3 |
20 |
*/ |
21 |
public class Strings { |
22 |
|
23 |
private Strings() { |
24 |
// Do not instantiate |
25 |
} |
26 |
|
27 |
/** |
28 |
* Capitalizes the given String. |
29 |
* <p> |
30 |
* Since case mappings are not always 1:1 char mappings, the resulting |
31 |
* String may be a different length than the String input. |
32 |
* </p> |
33 |
* <p> |
34 |
* Rules: |
35 |
* </p> |
36 |
* <ul> |
37 |
* <li>the first character will be converted to upper case</li> |
38 |
* <li>each letter directly after a whitespace will be converted to upper |
39 |
* case</li> |
40 |
* </ul> |
41 |
* <p> |
42 |
* Examples: |
43 |
* </p> |
44 |
* |
45 |
* <pre> |
46 |
* Strings.capitalize(null) = null |
47 |
* Strings.capitalize("to be capitalized") = "To Be Capitalized" |
48 |
* Strings.capitalize("§") = "SS" |
49 |
* Strings.capitalize("a\tba") = "A\tBa" |
50 |
* </pre> |
51 |
* |
52 |
* @param input |
53 |
* the String to be capitalized, may be null |
54 |
* @return the capitalized String or <code>null</code> if null String |
55 |
* input |
56 |
* @see java.lang.String#toUpperCase() |
57 |
*/ |
58 |
public static String capitalize(String input) { |
59 |
if (input == null) |
60 |
return null; |
61 |
|
62 |
int len = input.length(); |
63 |
|
64 |
if (len == 0) |
65 |
return input; |
66 |
|
67 |
if (len == 1) |
68 |
return input.toUpperCase(); |
69 |
|
70 |
StringTokenizer st = new StringTokenizer(input, " \t\n\r\f", true); //$NON-NLS-1$ |
71 |
|
72 |
// common case has no 1:M mappings so initialize buffer w/ |
73 |
// length of original String to avoid resizing |
74 |
StringBuffer result = new StringBuffer(input.length()); |
75 |
|
76 |
while (st.hasMoreTokens()) |
77 |
appendCapitalized(result, st.nextToken()); |
78 |
|
79 |
return result.toString(); |
80 |
} |
81 |
|
82 |
/** |
83 |
* Converts the given String to constant case. |
84 |
* <p> |
85 |
* Since case mappings are not always 1:1 char mappings, the resulting |
86 |
* String may be a different length than the String input. |
87 |
* </p> |
88 |
* <p> |
89 |
* Rules: |
90 |
* </p> |
91 |
* <ul> |
92 |
* <li>all letters will be converted to upper case</li> |
93 |
* <li>each upper case letter in the input String will be prefixed by an _ |
94 |
* in the result</li> |
95 |
* <li>if the first character of the input String is an upper case letter |
96 |
* then it wil not be prefixed by _ in the result</li> |
97 |
* </ul> |
98 |
* <p> |
99 |
* Examples: |
100 |
* </p> |
101 |
* |
102 |
* <pre> |
103 |
* Strings.constantCase(null) = null |
104 |
* Strings.constantCase("toConstantCase") = "TO_CONSTANT_CASE" |
105 |
* Strings.constantCase("NoLeadingUnderscore") = "NO_LEADING_UNDERSCORE" |
106 |
* Strings.constantCase("__someExtra__Underscores_") = "__SOME_EXTRA___UNDERSCORES_" |
107 |
* </pre> |
108 |
* |
109 |
* @param input |
110 |
* the String to be converted to constant case, may be null |
111 |
* @return the constant case String or <code>null</code> if null String |
112 |
* input |
113 |
*/ |
114 |
public static String constantCase(String input) { |
115 |
if (input == null) |
116 |
return null; |
117 |
|
118 |
int len = input.length(); |
119 |
|
120 |
if (len == 0) |
121 |
return input; |
122 |
|
123 |
if (len == 1) |
124 |
return input.toUpperCase(); |
125 |
|
126 |
// it is likely that the result is longer than the input; |
127 |
// nethertheless do not set a larger initial size and depend on |
128 |
// StringBuffer's resize strategy |
129 |
StringBuffer buffer = new StringBuffer(input.length()); |
130 |
|
131 |
// toUpperCase on an entire String is more performant than |
132 |
// several String.valueOf(c).toUpperCase() calls in a loop; |
133 |
// so we first just copy and insert _'s |
134 |
|
135 |
// first letter should not be prefixed by _ |
136 |
buffer.append(input.charAt(0)); |
137 |
|
138 |
// now prefix the remaining |
139 |
for (int i = 1; i < len; i++) { |
140 |
char c = input.charAt(i); |
141 |
if (Character.isUpperCase(c)) |
142 |
buffer.append('_'); |
143 |
buffer.append(c); |
144 |
} |
145 |
|
146 |
// now convert to uppercase |
147 |
return buffer.toString().toUpperCase(); |
148 |
} |
149 |
|
150 |
/** |
151 |
* Inverts the case of the given String's letters. |
152 |
* <p> |
153 |
* Since case mappings are not always 1:1 char mappings, the resulting |
154 |
* String may be a different length than the String input. |
155 |
* </p> |
156 |
* <p> |
157 |
* This operation is not symmetric; |
158 |
* <code>Strings.invertCase(Strings.invertCase(input))</code> might not be |
159 |
* equal to <code>input</code>. |
160 |
* </p> |
161 |
* <p> |
162 |
* Rules: |
163 |
* </p> |
164 |
* <ul> |
165 |
* <li>each lower case letter will be converted to upper case</li> |
166 |
* <li>each upper case letter will be converted to lower case</li> |
167 |
* </ul> |
168 |
* <p> |
169 |
* Examples: |
170 |
* </p> |
171 |
* |
172 |
* <pre> |
173 |
* Strings.invertCase(null) = null |
174 |
* Strings.invertCase("To Be Inverted") = "tO bE iNVERTED" |
175 |
* Strings.invertCase("tO bE iNVERTED") = "To Be Inverted" |
176 |
* Strings.invertCase("Maße") = "mASSE" |
177 |
* Strings.invertCase("mASSE") = "Masse" |
178 |
* Strings.invertCase("StringsTest") = "sTRINGStEST" |
179 |
* </pre> |
180 |
* |
181 |
* @param input |
182 |
* the String to be inverted, may be null |
183 |
* @return the inverted String or <code>null</code> if null String input |
184 |
* @see java.lang.String#toLowerCase() |
185 |
* @see java.lang.String#toUpperCase() |
186 |
* @see java.lang.Character#isLetter(char) |
187 |
*/ |
188 |
public static String invertCase(String input) { |
189 |
if (input == null) |
190 |
return null; |
191 |
|
192 |
int len = input.length(); |
193 |
|
194 |
if (len == 0) |
195 |
return input; |
196 |
|
197 |
int i; |
198 |
char c; |
199 |
|
200 |
// skip to first lower case letter |
201 |
for (i = 0; i < len; i++) { |
202 |
c = input.charAt(i); |
203 |
if (Character.isLetter(c) && Character.isLowerCase(c)) |
204 |
break; |
205 |
} |
206 |
|
207 |
// only upper case letters in String? |
208 |
if (i == len) |
209 |
return input.toLowerCase(); |
210 |
|
211 |
// common case has no 1:M mappings so initialize buffer w/ |
212 |
// length of original String to avoid resizing |
213 |
StringBuffer result = new StringBuffer(len); |
214 |
|
215 |
// append upper case letters before first lower case letter |
216 |
result.append(input.substring(0, i).toLowerCase()); |
217 |
|
218 |
// convert the remaining characters |
219 |
for (; i < len; i++) { |
220 |
c = input.charAt(i); |
221 |
if (Character.isLetter(c)) { |
222 |
// String.toUpper/Lower insure 1:M mappings |
223 |
String letter = String.valueOf(c); |
224 |
if (Character.isLowerCase(c)) |
225 |
result.append(letter.toUpperCase()); |
226 |
else |
227 |
result.append(letter.toLowerCase()); |
228 |
} else |
229 |
result.append(c); |
230 |
} |
231 |
|
232 |
return result.toString(); |
233 |
} |
234 |
|
235 |
/** |
236 |
* Converts the given String to lower camel case. |
237 |
* <p> |
238 |
* Since case mappings are not always 1:1 char mappings, the resulting |
239 |
* String may be a different length than the String input. |
240 |
* </p> |
241 |
* <p> |
242 |
* Rules: |
243 |
* </p> |
244 |
* <ul> |
245 |
* <li>the first letter will be converted to lower case</li> |
246 |
* <li>the character _ will be removed unless it is followed by another _ |
247 |
* or if it is a trailing _</li> |
248 |
* <li>a letter following an _ will be converted to upper case</li> |
249 |
* <li>all other letters will be in converted to lower case</li> |
250 |
* </ul> |
251 |
* <p> |
252 |
* Examples: |
253 |
* </p> |
254 |
* |
255 |
* <pre> |
256 |
* Strings.lowerCamelCase(null) = null |
257 |
* Strings.lowerCamelCase("TO_LOWER_CAMEL_CASE") = "toLowerCamelCase" |
258 |
* Strings.lowerCamelCase("_Leading") = "leading" |
259 |
* Strings.lowerCamelCase("__someExtra__underscores_") = "_Someextra_Underscores_" |
260 |
* </pre> |
261 |
* |
262 |
* @param input |
263 |
* the String to be converted to lower camel case, may be null |
264 |
* @return the lower camel case String or <code>null</code> if null String |
265 |
* input |
266 |
*/ |
267 |
public static String lowerCamelCase(String input) { |
268 |
return internalCamelCase(input, false); |
269 |
} |
270 |
|
271 |
/** |
272 |
* Converts the given String to upper camel case. |
273 |
* <p> |
274 |
* Since case mappings are not always 1:1 char mappings, the resulting |
275 |
* String may be a different length than the String input. |
276 |
* </p> |
277 |
* <p> |
278 |
* Rules: |
279 |
* </p> |
280 |
* <ul> |
281 |
* <li>the character _ will be removed unless it is followed by another _ |
282 |
* or if it is a trailing _</li> |
283 |
* <li>a letter following an _ will be converted to upper case</li> |
284 |
* <li>all other letters will be in converted to lower case</li> |
285 |
* </ul> |
286 |
* <p> |
287 |
* Examples: |
288 |
* </p> |
289 |
* |
290 |
* <pre> |
291 |
* Strings.upperCamelCase(null) = null |
292 |
* Strings.upperCamelCase("TO_UPPER_CAMEL_CASE") = "ToUpperCamelCase" |
293 |
* Strings.upperCamelCase("_leading") = "Leading" |
294 |
* Strings.upperCamelCase("__someExtra__underscores_") = "_Someextra_Underscores_" |
295 |
* </pre> |
296 |
* |
297 |
* @param input |
298 |
* the String to be converted to upper camel case, may be null |
299 |
* @return the upper camel case String or <code>null</code> if null String |
300 |
* input |
301 |
*/ |
302 |
public static String upperCamelCase(String input) { |
303 |
return internalCamelCase(input, true); |
304 |
} |
305 |
|
306 |
/** |
307 |
* Converts the given String to upper or lower camel case. |
308 |
* |
309 |
* @param input |
310 |
* the String to be converted, may be null |
311 |
* @param toUpper |
312 |
* <code>true</code> if the input should be converted to upper |
313 |
* camel case, <code>false</code> otherwise |
314 |
* @return the converted String or <code>null</code> if null String input |
315 |
*/ |
316 |
private static String internalCamelCase(String input, boolean toUpper) { |
317 |
if (input == null) |
318 |
return null; |
319 |
|
320 |
if (input.length() == 0) |
321 |
return input; |
322 |
|
323 |
// the result mainly consists of lower case letters; |
324 |
// toLowerCase on the entire String is more performant than |
325 |
// several String.valueOf(c).toLowerCase() calls in the loop below |
326 |
String lower = input.toLowerCase(); |
327 |
int len = lower.length(); |
328 |
StringBuffer buffer = new StringBuffer(len); |
329 |
for (int i = 0; i < len; i++) { |
330 |
char c = lower.charAt(i); |
331 |
if (c == '_') { |
332 |
int j = i + 1; |
333 |
for (; j < len; j++) { |
334 |
c = lower.charAt(j); |
335 |
if (c == '_') { |
336 |
// keep additional _'s |
337 |
buffer.append('_'); |
338 |
} else { |
339 |
if (toUpper || j > 1) { |
340 |
// String.toUpper insures 1:M mappings |
341 |
buffer.append(String.valueOf(c).toUpperCase()); |
342 |
} else { |
343 |
// keep result's first character in lower case |
344 |
buffer.append(c); |
345 |
} |
346 |
break; |
347 |
} |
348 |
} |
349 |
if (j == len) { |
350 |
// keep trailing _ |
351 |
buffer.append('_'); |
352 |
} |
353 |
i = j; |
354 |
} else { |
355 |
// letters are lower case already so just append |
356 |
buffer.append(lower.charAt(i)); |
357 |
} |
358 |
} |
359 |
if (toUpper) { |
360 |
buffer |
361 |
.replace(0, 1, String.valueOf(buffer.charAt(0)) |
362 |
.toUpperCase()); |
363 |
} |
364 |
return buffer.toString(); |
365 |
} |
366 |
|
367 |
/** |
368 |
* Appends the given String to the buffer; the first character of the String |
369 |
* will be appended in upper case if it is a letter. |
370 |
* |
371 |
* @param buffer |
372 |
* the <code>StringBuffer</code> the capitalized input String |
373 |
* will be appended to |
374 |
* @param input |
375 |
* the String to be capitalized |
376 |
*/ |
377 |
private static void appendCapitalized(StringBuffer buffer, String input) { |
378 |
char firstChar = input.charAt(0); |
379 |
|
380 |
if (!Character.isLetter(firstChar)) { |
381 |
buffer.append(input); |
382 |
return; |
383 |
} |
384 |
|
385 |
// capitalize first char of token |
386 |
// String.toUpper insures 1:M mappings |
387 |
buffer.append(String.valueOf(firstChar).toUpperCase()); |
388 |
|
389 |
int len = input.length(); |
390 |
|
391 |
// append remaining chars of token |
392 |
if (len > 1) |
393 |
buffer.append(input.substring(1, len)); |
394 |
} |
395 |
} |