1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package com.cosylab.util;
21
22 import com.cosylab.introspection.ClassIntrospector;
23
24 import java.io.PrintWriter;
25 import java.io.StringWriter;
26 import java.lang.reflect.Array;
27 import java.lang.reflect.InvocationTargetException;
28 import java.lang.reflect.Method;
29
30
31
32
33
34
35
36
37
38 public final class StringUtilities
39 {
40 private static final PrintfFormat byteFormat= new PrintfFormat("%.1f");
41
42
43 private static final int ERROR_STATE = 99;
44
45
46 private static final int[][] transitions = {
47 { 99, 1, 1, 2, 3 },
48 { 99, 99, 1, 2, 3 },
49 { 99, 99, 2, 99, 3 },
50 { 99, 4, 4, 99, 99 },
51 { 99, 99, 4, 99, 99 }
52 };
53 private static char decimalSeparator = '.';
54
55
56
57
58 private StringUtilities()
59 {
60
61 }
62
63
64
65
66
67
68
69
70
71
72
73 public static Object fromString(String sValue, Class targetClass)
74 throws CommonException
75 {
76 try {
77 if ((sValue == null) || (sValue.equals(""))) {
78 return targetClass.newInstance();
79 }
80
81 if (targetClass.isArray()) {
82 return arrayFromString(sValue, targetClass);
83 }
84
85 if (targetClass.equals(String.class)) {
86 return sValue;
87 } else if (Number.class.isAssignableFrom(targetClass)
88 || Boolean.class.isAssignableFrom(targetClass)) {
89 return targetClass.getMethod("valueOf",
90 new Class[]{ String.class }).invoke(null,
91 new Object[]{ sValue });
92 } else if (targetClass.isPrimitive()) {
93
94 if (Boolean.TYPE.equals(targetClass)) {
95 return Boolean.valueOf(sValue);
96 }
97
98 if (Short.TYPE.equals(targetClass)) {
99 return Short.valueOf(sValue);
100 }
101
102 if (Byte.TYPE.equals(targetClass)) {
103 return Byte.valueOf(sValue);
104 }
105
106 if (Character.TYPE.equals(targetClass)) {
107 return new Character(sValue.charAt(0));
108 }
109
110 if (Integer.TYPE.equals(targetClass)) {
111 return Integer.valueOf(sValue);
112 }
113
114 if (Long.TYPE.equals(targetClass)) {
115 return Long.valueOf(sValue);
116 }
117
118 if (Float.TYPE.equals(targetClass)) {
119 return Float.valueOf(sValue);
120 }
121
122 if (Double.TYPE.equals(targetClass)) {
123 return Double.valueOf(sValue);
124 }
125
126 return null;
127 } else if (Class.class == targetClass) {
128
129 return classFromString(sValue);
130 }
131
132
133 else {
134 Method met = ClassIntrospector.getMethod(targetClass,
135 "valueOf", new Class[]{ String.class });
136
137 if (met != null) {
138 return met.invoke(null, new String[]{ sValue });
139 }
140
141 return targetClass.newInstance();
142 }
143 } catch (NoSuchMethodException e) {
144 throw new CommonException(ArrayHelper.class,
145 "Objects could not be instantiated from strings", e);
146 } catch (IllegalAccessException e) {
147 throw new CommonException(ArrayHelper.class,
148 "Objects could not be instantiated from strings", e);
149 } catch (InvocationTargetException e) {
150 throw new CommonException(ArrayHelper.class,
151 "Objects could not be instantiated from strings", e);
152 } catch (InstantiationException e) {
153 throw new CommonException(ArrayHelper.class,
154 "Objects could not be instantiated from strings", e);
155 }
156 }
157
158
159
160
161
162
163
164
165
166
167 public static Class classFromString(String sValue)
168 throws CommonException
169 {
170 try {
171 if (sValue.equals(Boolean.TYPE.getName())) {
172 return Boolean.TYPE;
173 }
174
175 if (sValue.equals(Short.TYPE.getName())) {
176 return Short.TYPE;
177 }
178
179 if (sValue.equals(Byte.TYPE.getName())) {
180 return Byte.TYPE;
181 }
182
183 if (sValue.equals(Character.TYPE.getName())) {
184 return Character.TYPE;
185 }
186
187 if (sValue.equals(Integer.TYPE.getName())) {
188 return Integer.TYPE;
189 }
190
191 if (sValue.equals(Long.TYPE.getName())) {
192 return Long.TYPE;
193 }
194
195 if (sValue.equals(Float.TYPE.getName())) {
196 return Float.TYPE;
197 }
198
199 if (sValue.equals(Double.TYPE.getName())) {
200 return Double.TYPE;
201 }
202
203 if (sValue.equals(Void.TYPE.getName())) {
204 return Void.TYPE;
205 }
206
207 return Class.forName(sValue);
208 } catch (ClassNotFoundException e) {
209 throw new CommonException(ArrayHelper.class,
210 "Class could not be instantiated from a String", e);
211 }
212 }
213
214
215
216
217
218
219
220
221
222
223
224 public static Object arrayFromString(String arrayString, Class arrayClass)
225 throws CommonException
226 {
227 return arrayFromString(arrayString, arrayClass, ",", true);
228 }
229
230
231
232
233
234
235
236
237
238
239
240
241
242 public static Object arrayFromString(String arrayString, Class arrayClass,
243 String separator, boolean parentheses) throws CommonException
244 {
245 String[] pStrings = arrayString.split(separator);
246
247 if (parentheses) {
248 pStrings[0] = pStrings[0].substring(1);
249 pStrings[pStrings.length - 1] = pStrings[pStrings.length - 1]
250 .substring(0, pStrings[pStrings.length - 1].length() - 1);
251 }
252
253 Object retArray = Array.newInstance(arrayClass.getComponentType(),
254 pStrings.length);
255
256 for (int i = 0; i < pStrings.length; i++) {
257 Array.set(retArray, i,
258 StringUtilities.fromString(pStrings[i],
259 arrayClass.getComponentType()));
260 }
261
262 return retArray;
263 }
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281 public static final double parseDouble(final String s)
282 {
283 double decPart = 0.0;
284 double sign = 1.0;
285
286 double fracPart = 0.0;
287 double fracDiv = 10.0;
288
289 double expPart = 0.0;
290 double expSign = 1.0;
291
292 char[] chars = s.trim().toCharArray();
293 int n = chars.length;
294
295 int currState = 0;
296 int nextState = ERROR_STATE;
297 int symbol = 0;
298 char ch = ' ';
299
300 int c = 0;
301
302 while ((c < n) && (currState != ERROR_STATE)) {
303 ch = chars[c++];
304 symbol = getNextSymbol(ch);
305 nextState = transitions[currState][symbol];
306
307
308 switch (nextState) {
309 case 1:
310
311 if (symbol == 1) {
312 if (ch == '-') {
313 sign = -1.0;
314 }
315 } else {
316 decPart *= 10;
317 decPart += (ch - '0');
318 }
319
320 break;
321
322 case 2:
323
324 if (symbol != 3) {
325 fracPart += (ch - '0') / fracDiv;
326 fracDiv *= 10;
327 }
328
329 break;
330
331 case 4:
332
333 if (symbol == 1) {
334 if (ch == '-') {
335 expSign = -1.0;
336 }
337 } else {
338 expPart *= 10;
339 expPart += (ch - '0');
340 }
341 }
342
343 currState = nextState;
344 }
345
346 if (currState != ERROR_STATE) {
347 expPart = Math.pow(10, expSign * expPart);
348
349 return sign * (decPart + fracPart) * expPart;
350 }
351
352 return Double.NaN;
353 }
354
355 private static final int getNextSymbol(final char ch)
356 {
357 if (Character.isDigit(ch)) {
358 return 2;
359 }
360
361 if ((ch == '+') || (ch == '-')) {
362 return 1;
363 }
364
365 if (ch == decimalSeparator) {
366 return 3;
367 }
368
369 if ((ch == 'e') || (ch == 'E')) {
370 return 4;
371 }
372
373 return 0;
374 }
375
376
377
378
379
380
381
382
383
384
385
386
387 public static boolean isTrueNumber(String value)
388 {
389 if (value == null) {
390 return false;
391 }
392
393 String s = value.trim();
394
395 if (s.length() == 0) {
396 return false;
397 }
398
399 if (s.length() == 1 && !Character.isDigit(s.charAt(0))) {
400 return false;
401 }
402
403 double d = parseDouble(s);
404
405 if (Double.isNaN(d) || Double.isInfinite(d)) {
406 return false;
407 }
408
409 return true;
410 }
411
412
413
414
415
416
417 public static void printBytes(long bytes, PrintWriter pr) {
418
419 if (bytes>=900000000) {
420 pr.print(byteFormat.sprintf(bytes/1000000000.0));
421 pr.print('G');
422 pr.print('B');
423 return;
424 }
425 if (bytes>=900000) {
426 pr.print(byteFormat.sprintf(bytes/1000000.0));
427 pr.print('M');
428 pr.print('B');
429 return;
430 }
431 if (bytes>900) {
432 pr.print(byteFormat.sprintf(bytes/1000.0));
433 pr.print('M');
434 pr.print('B');
435 return;
436 }
437
438 pr.print(bytes);
439 pr.print('B');
440 }
441
442
443
444
445
446
447 public static String printBytes(long bytes) {
448 StringWriter sw= new StringWriter(8);
449 printBytes(bytes,new PrintWriter(sw));
450 return sw.toString();
451 }
452 }
453
454