1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.kns.web.format;
17
18
19 import java.io.Serializable;
20 import java.lang.reflect.Array;
21 import java.math.BigDecimal;
22 import java.sql.Date;
23 import java.sql.Timestamp;
24 import java.util.ArrayList;
25 import java.util.Collection;
26 import java.util.Collections;
27 import java.util.HashMap;
28 import java.util.HashSet;
29 import java.util.Iterator;
30 import java.util.List;
31 import java.util.Map;
32 import java.util.Set;
33
34 import javax.servlet.http.HttpServletRequest;
35
36 import org.apache.commons.beanutils.PropertyUtils;
37 import org.apache.commons.lang.StringUtils;
38 import org.kuali.rice.kns.util.AbstractKualiDecimal;
39 import org.kuali.rice.kns.util.KualiDecimal;
40 import org.kuali.rice.kns.util.KualiInteger;
41 import org.kuali.rice.kns.util.KualiPercent;
42 import org.kuali.rice.kns.web.struts.pojo.ArrayUtils;
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80 public class Formatter implements Serializable {
81
82
83
84
85 static final String CREATE_MSG = "Couldn't create an instance of class ";
86
87
88 private static Map registry = Collections.synchronizedMap(new HashMap());
89
90
91 protected Map settings;
92
93
94
95
96
97 protected Class propertyType;
98
99 static {
100
101 registerFormatter(String.class, Formatter.class);
102 registerFormatter(String[].class, Formatter.class);
103 registerFormatter(AbstractKualiDecimal.class, BigDecimalFormatter.class);
104 registerFormatter(KualiDecimal.class, CurrencyFormatter.class);
105 registerFormatter(KualiInteger.class, KualiIntegerCurrencyFormatter.class);
106 registerFormatter(KualiPercent.class, PercentageFormatter.class);
107 registerFormatter(BigDecimal.class, BigDecimalFormatter.class);
108 registerFormatter(Date.class, DateFormatter.class);
109 registerFormatter(Integer.class, IntegerFormatter.class);
110 registerFormatter(int.class, IntegerFormatter.class);
111 registerFormatter(int[].class, IntegerFormatter.class);
112 registerFormatter(Boolean.class, BooleanFormatter.class);
113 registerFormatter(Boolean.TYPE, BooleanFormatter.class);
114 registerFormatter(boolean[].class, BooleanFormatter.class);
115 registerFormatter(Long.class, LongFormatter.class);
116 registerFormatter(Timestamp.class, DateViewTimestampObjectFormatter.class);
117 registerFormatter(boolean.class, LittleBooleanFormatter.class);
118 registerFormatter(Collection.class, ArrayFormatter.class);
119
120 }
121
122 public static Formatter getFormatter(Class aType) {
123 return getFormatter(aType, null);
124 }
125
126
127
128
129
130
131
132
133
134
135 public static Formatter getFormatter(Class aType, Map settings) {
136
137
138 Class type = formatterForType(aType);
139 Formatter formatter = null;
140 try {
141 formatter = (Formatter) type.newInstance();
142 }
143 catch (InstantiationException e) {
144 throw new FormatException(CREATE_MSG + type, e);
145 }
146 catch (IllegalAccessException e) {
147 throw new FormatException(CREATE_MSG + type, e);
148 }
149
150 if (settings != null)
151 formatter.setSettings(Collections.unmodifiableMap(settings));
152 formatter.propertyType = aType;
153
154 return formatter;
155 }
156
157
158
159
160
161
162
163
164
165
166
167 public static void registerFormatter(Class type, Class formatterType) {
168 registry.put(type, formatterType);
169 }
170
171
172
173
174
175
176
177 public static boolean isSupportedType(Class type) {
178
179 if (type == null)
180 return false;
181
182 if (List.class.isAssignableFrom(type))
183 return true;
184 if (Set.class.isAssignableFrom(type))
185 return true;
186
187 return findFormatter(type) != null;
188 }
189
190
191
192
193
194
195
196 public static Class formatterForType(Class type) {
197 if (type == null)
198 throw new IllegalArgumentException("Type can not be null");
199
200 Class formatterType = findFormatter(type);
201
202 return formatterType == null ? Formatter.class : formatterType;
203 }
204
205
206 public static Class findFormatter(Class type) {
207
208 if (type == null)
209 return null;
210
211 if (registry.containsKey(type)) {
212 return (Class) registry.get(type);
213 }
214
215
216 Iterator typeIter = registry.keySet().iterator();
217 while (typeIter.hasNext()) {
218 Class currType = (Class) typeIter.next();
219 if (currType.isAssignableFrom(type)) {
220 Class currFormatter = (Class) registry.get(currType);
221 registerFormatter(type, currFormatter);
222 return currFormatter;
223 }
224 }
225
226 return null;
227
228 }
229
230
231 public String getImplementationClass() {
232 return this.getClass().getName();
233 }
234
235
236 public Class getPropertyType() {
237 return propertyType;
238 }
239
240 public void setPropertyType(Class propertyType) {
241 this.propertyType = propertyType;
242 }
243
244 public Map getSettings() {
245 return settings;
246 }
247
248 public void setSettings(Map settings) {
249 this.settings = settings;
250 }
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274 public Object formatForPresentation(Object value) {
275 if (isNullValue(value))
276 return formatNull();
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292 return formatObject(value);
293 }
294
295
296
297
298
299 protected Object formatNull() {
300 return null;
301 }
302
303
304
305
306
307
308 public Object formatObject(Object value) {
309 if (value == null)
310 return formatNull();
311
312
313
314 Class type = value.getClass();
315 if (type.isArray())
316
317 return ArrayUtils.toString(value, type.getComponentType());
318
319
320 if (!(isSupportedType(value.getClass())))
321
322 formatBean(value);
323
324
325 return format(value);
326 }
327
328
329
330
331
332 protected Object formatBean(Object bean) {
333 Map properties = null;
334 try {
335
336 properties = PropertyUtils.describe(bean);
337
338 }
339 catch (Exception e) {
340 throw new FormatException("Unable to format values for bean " + bean, e);
341 }
342
343 Map formattedVals = new HashMap();
344
345 Iterator propIter = properties.entrySet().iterator();
346
347 while (propIter.hasNext()) {
348 Map.Entry entry = (Map.Entry) propIter.next();
349 Object value = entry.getValue();
350 if (value != null && isSupportedType(value.getClass())) {
351 Formatter formatter = getFormatter(value.getClass());
352 formattedVals.put(entry.getKey(), formatter.formatForPresentation(value));
353 }
354 }
355
356 return formattedVals;
357 }
358
359 public Object format(Object value) {
360 return value;
361 }
362
363 public Object formatArray(Object value) {
364
365 Class elementType = value.getClass().getComponentType();
366 if (!isSupportedType(elementType))
367 return value;
368
369 int length = Array.getLength(value);
370 Object[] formattedVals = new String[length];
371
372 for (int i = 0; i < length; i++) {
373 Object element = Array.get(value, i);
374 Object objValue = ArrayUtils.toObject(element);
375 Formatter elementFormatter = getFormatter(elementType);
376 formattedVals[i] = elementFormatter.formatForPresentation(objValue);
377 }
378
379 return formattedVals;
380
381 }
382
383 public Object formatCollection(Collection value) {
384 List stringVals = new ArrayList();
385 Iterator iter = value.iterator();
386 while (iter.hasNext()) {
387 Object obj = iter.next();
388 Formatter formatter = getFormatter(obj.getClass());
389
390 stringVals.add(formatter.formatForPresentation(obj));
391
392 }
393 return stringVals.toArray();
394 }
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416 public Object convertFromPresentationFormat(Object value) {
417 if (isEmptyValue(value))
418 return getNullObjectValue();
419
420 Class type = value.getClass();
421 boolean isArray = propertyType != null && propertyType.isArray();
422 boolean isCollection = propertyType != null && Collection.class.isAssignableFrom(propertyType);
423
424 if (!(isArray || isCollection)) {
425 value = unwrapString(value);
426 return convertToObject((String) value);
427 }
428
429 String[] strings = type.isArray() ? (String[]) value : new String[] { (String) value };
430
431 return isArray ? convertToArray(strings) : convertToCollection(strings);
432 }
433
434
435
436
437
438 protected Object getNullObjectValue() {
439 return null;
440 }
441
442
443
444
445
446 protected Object convertToObject(String string) {
447 return string == null ? null : string.replace( "\r\n", "\n" ).trim();
448 }
449
450
451
452
453
454
455
456 protected Collection convertToCollection(String[] strings) {
457 Collection collection = null;
458 Class type = propertyType;
459
460 if (propertyType.isAssignableFrom(List.class))
461 type = ArrayList.class;
462 else if (propertyType.isAssignableFrom(Set.class))
463 type = HashSet.class;
464
465 try {
466 collection = (Collection) type.newInstance();
467 }
468 catch (Exception e) {
469 throw new FormatException(CREATE_MSG + propertyType, e);
470 }
471
472 for (int i = 0; i < strings.length; i++)
473 collection.add(strings[i]);
474
475 return collection;
476 }
477
478
479
480
481
482
483
484 protected Object convertToArray(String[] strings) {
485 Class type = propertyType.getComponentType();
486
487 Formatter formatter = getFormatter(type);
488
489 Object array = null;
490 try {
491 array = Array.newInstance(type, strings.length);
492 }
493 catch (Exception e) {
494 throw new FormatException(CREATE_MSG + type, e);
495 }
496
497 for (int i = 0; i < strings.length; i++) {
498 Object value = formatter.convertToObject(strings[i]);
499
500 ArrayUtils.setArrayValue(array, type, value, i);
501
502 }
503
504 return array;
505 }
506
507 public static String unwrapString(Object target) {
508
509 if (target.getClass().isArray()) {
510 String wrapper[] = (String[]) target;
511 return wrapper.length > 0 ? wrapper[0] : null;
512 }
513
514
515 else if (target == null) {
516 return new String();
517 }
518
519
520
521 else {
522 return target.toString();
523 }
524
525 }
526
527 public static boolean isNullValue(Object obj) {
528 if (obj == null)
529 return true;
530
531
532 if ((obj instanceof String) && StringUtils.isEmpty((String) obj))
533 return true;
534
535
536 return false;
537 }
538
539 public static boolean isEmptyValue(Object obj) {
540 if (obj == null)
541 return true;
542
543 if ((obj instanceof String) && StringUtils.isEmpty((String) obj))
544 return true;
545
546 Class type = obj.getClass();
547 if (type.isArray()) {
548 Class compType = type.getComponentType();
549 if (compType.isPrimitive())
550 return false;
551 if (((Object[]) obj).length == 0)
552 return true;
553 if (((Object[]) obj)[0] == null)
554 return true;
555 if (String.class.isAssignableFrom(compType)) {
556
557 return StringUtils.isEmpty(((String[]) obj)[0]);
558
559 }
560 }
561 return false;
562 }
563
564 protected String trimString(Object target) {
565 String stringValue = null;
566 try {
567 stringValue = (String) target;
568 }
569 catch (ClassCastException e) {
570 throw new FormatException("Can't cast " + target + " to String", e);
571 }
572 return stringValue == null ? null : stringValue.trim();
573 }
574
575
576
577
578 protected boolean isBlank(String string) {
579 return string == null || string.trim().length() == 0;
580 }
581 }