1 package org.apache.velocity.tools.generic;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.lang.reflect.Array;
23 import java.text.MessageFormat;
24 import java.util.ArrayList;
25 import java.util.Collection;
26 import java.util.Collections;
27 import java.util.Iterator;
28 import java.util.regex.Pattern;
29
30 import org.apache.commons.beanutils.PropertyUtils;
31 import org.apache.velocity.tools.config.DefaultKey;
32
33
34
35
36
37
38
39
40
41
42
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 @DefaultKey("display")
74 public class DisplayTool extends LocaleConfig
75 {
76 public static final String LIST_DELIM_KEY = "listDelim";
77 public static final String LIST_FINAL_DELIM_KEY = "listFinalDelim";
78 public static final String TRUNCATE_LENGTH_KEY = "truncateLength";
79 public static final String TRUNCATE_SUFFIX_KEY = "truncateSuffix";
80 public static final String TRUNCATE_AT_WORD_KEY = "truncateAtWord";
81 public static final String CELL_LENGTH_KEY = "cellLength";
82 public static final String CELL_SUFFIX_KEY = "cellSuffix";
83 public static final String DEFAULT_ALTERNATE_KEY = "defaultAlternate";
84 public static final String ALLOWED_TAGS_KEY = "allowedTags";
85
86 private String defaultDelim = ", ";
87 private String defaultFinalDelim = " and ";
88 private int defaultTruncateLength = 30;
89 private String defaultTruncateSuffix = "...";
90 private boolean defaultTruncateAtWord = false;
91 private int defaultCellLength = 30;
92 private String defaultCellSuffix = "...";
93 private String defaultAlternate = "null";
94 private String[] defaultAllowedTags = null;
95
96
97
98
99
100
101
102 protected void configure(ValueParser values)
103 {
104 String listDelim = values.getString(LIST_DELIM_KEY);
105 if (listDelim != null)
106 {
107 setListDelimiter(listDelim);
108 }
109
110 String listFinalDelim = values.getString(LIST_FINAL_DELIM_KEY);
111 if (listFinalDelim != null)
112 {
113 setListFinalDelimiter(listFinalDelim);
114 }
115
116 Integer truncateLength = values.getInteger(TRUNCATE_LENGTH_KEY);
117 if (truncateLength != null)
118 {
119 setTruncateLength(truncateLength);
120 }
121
122 String truncateSuffix = values.getString(TRUNCATE_SUFFIX_KEY);
123 if (truncateSuffix != null)
124 {
125 setTruncateSuffix(truncateSuffix);
126 }
127
128 Boolean truncateAtWord = values.getBoolean(TRUNCATE_AT_WORD_KEY);
129 if (truncateAtWord != null)
130 {
131 setTruncateAtWord(truncateAtWord);
132 }
133
134 Integer cellLength = values.getInteger(CELL_LENGTH_KEY);
135 if (cellLength != null)
136 {
137 setCellLength(cellLength);
138 }
139
140 String cellSuffix = values.getString(CELL_SUFFIX_KEY);
141 if (cellSuffix != null)
142 {
143 setCellSuffix(cellSuffix);
144 }
145
146 String defaultAlternate = values.getString(DEFAULT_ALTERNATE_KEY);
147 if (defaultAlternate != null)
148 {
149 setDefaultAlternate(defaultAlternate);
150 }
151
152 String[] allowedTags = values.getStrings(ALLOWED_TAGS_KEY);
153 if (allowedTags != null)
154 {
155 setAllowedTags(allowedTags);
156 }
157 }
158
159 public String getListDelimiter()
160 {
161 return this.defaultDelim;
162 }
163
164 protected void setListDelimiter(String delim)
165 {
166 this.defaultDelim = delim;
167 }
168
169 public String getListFinalDelimiter()
170 {
171 return this.defaultFinalDelim;
172 }
173
174 protected void setListFinalDelimiter(String finalDelim)
175 {
176 this.defaultFinalDelim = finalDelim;
177 }
178
179 public int getTruncateLength()
180 {
181 return this.defaultTruncateLength;
182 }
183
184 protected void setTruncateLength(int maxlen)
185 {
186 this.defaultTruncateLength = maxlen;
187 }
188
189 public String getTruncateSuffix()
190 {
191 return this.defaultTruncateSuffix;
192 }
193
194 protected void setTruncateSuffix(String suffix)
195 {
196 this.defaultTruncateSuffix = suffix;
197 }
198
199 public boolean getTruncateAtWord()
200 {
201 return this.defaultTruncateAtWord;
202 }
203
204 protected void setTruncateAtWord(boolean atWord)
205 {
206 this.defaultTruncateAtWord = atWord;
207 }
208
209 public String getCellSuffix()
210 {
211 return this.defaultCellSuffix;
212 }
213
214 protected void setCellSuffix(String suffix)
215 {
216 this.defaultCellSuffix = suffix;
217 }
218
219 public int getCellLength()
220 {
221 return this.defaultCellLength;
222 }
223
224 protected void setCellLength(int maxlen)
225 {
226 this.defaultCellLength = maxlen;
227 }
228
229 public String getDefaultAlternate()
230 {
231 return this.defaultAlternate;
232 }
233
234 protected void setDefaultAlternate(String dflt)
235 {
236 this.defaultAlternate = dflt;
237 }
238
239 public String[] getAllowedTags()
240 {
241 return this.defaultAllowedTags;
242 }
243
244 protected void setAllowedTags(String[] tags)
245 {
246 this.defaultAllowedTags = tags;
247 }
248
249
250
251
252
253
254
255
256 public String list(Object list)
257 {
258 return list(list, this.defaultDelim, this.defaultFinalDelim);
259 }
260
261
262
263
264
265
266
267
268
269 public String list(Object list, String delim)
270 {
271 return list(list, delim, delim);
272 }
273
274
275
276
277
278
279
280
281
282
283 public String list(Object list, String delim, String finaldelim)
284 {
285 return list(list, delim, finaldelim, null);
286 }
287
288
289
290
291
292
293
294
295
296
297
298 public String list(Object list, String delim, String finaldelim,
299 String property)
300 {
301 if (list == null)
302 {
303 return null;
304 }
305 if (list instanceof Collection)
306 {
307 return format((Collection) list, delim, finaldelim, property);
308 }
309 Collection items;
310 if (list.getClass().isArray())
311 {
312 int size = Array.getLength(list);
313 items = new ArrayList(size);
314 for (int i = 0; i < size; i++)
315 {
316 items.add(Array.get(list, i));
317 }
318 }
319 else
320 {
321 items = Collections.singletonList(list);
322 }
323 return format(items, delim, finaldelim, property);
324 }
325
326
327
328
329 protected String format(Collection list, String delim, String finaldelim,
330 String property)
331 {
332 StringBuilder sb = new StringBuilder();
333 int size = list.size();
334 Iterator iterator = list.iterator();
335 for (int i = 0; i < size; i++)
336 {
337 if (property != null && property.length() > 0)
338 {
339 sb.append(getProperty(iterator.next(), property));
340 }
341 else
342 {
343 sb.append(iterator.next());
344 }
345 if (i < size - 2)
346 {
347 sb.append(delim);
348 }
349 else if (i < size - 1)
350 {
351 sb.append(finaldelim);
352 }
353 }
354 return sb.toString();
355 }
356
357
358
359
360 @Deprecated
361 public String message(String format, Collection args)
362 {
363 return message(format, new Object[] { args });
364 }
365
366
367
368
369 @Deprecated
370 public String message(String format, Object arg)
371 {
372 return message(format, new Object[] { arg });
373 }
374
375
376
377
378 @Deprecated
379 public String message(String format, Object arg1, Object arg2)
380 {
381 return message(format, new Object[] { arg1, arg2 });
382 }
383
384
385
386
387
388
389
390
391
392
393 public String message(String format, Object... args)
394 {
395 if (format == null)
396 {
397 return null;
398 }
399 if (args == null || args.length == 0)
400 {
401 return format;
402 }
403 else if (args.length == 1 && args[0] instanceof Collection)
404 {
405 Collection list = (Collection)args[0];
406 if (list.isEmpty())
407 {
408 return format;
409 }
410 else
411 {
412 args = list.toArray();
413 }
414 }
415 return MessageFormat.format(format, args);
416 }
417
418
419
420
421
422
423
424
425
426
427 public String printf(String format, Object... args)
428 {
429 if (format == null)
430 {
431 return null;
432 }
433 if (args == null || args.length == 0)
434 {
435 return format;
436 }
437 if (args.length == 1 && args[0] instanceof Collection)
438 {
439 Collection list = (Collection)args[0];
440 if (list.isEmpty())
441 {
442 return format;
443 }
444 else
445 {
446 args = list.toArray();
447 }
448 }
449 return String.format(getLocale(), format, args);
450 }
451
452
453
454
455
456
457
458
459
460
461 public String truncate(Object truncateMe)
462 {
463 return truncate(truncateMe, this.defaultTruncateLength);
464 }
465
466
467
468
469
470
471
472
473
474
475 public String truncate(Object truncateMe, int maxLength)
476 {
477 return truncate(truncateMe, maxLength, this.defaultTruncateSuffix);
478 }
479
480
481
482
483
484
485
486
487
488
489
490 public String truncate(Object truncateMe, String suffix)
491 {
492 return truncate(truncateMe, this.defaultTruncateLength, suffix);
493 }
494
495
496
497
498
499
500
501
502
503
504
505 public String truncate(Object truncateMe, int maxLength, String suffix)
506 {
507 return truncate(truncateMe, maxLength, suffix, defaultTruncateAtWord);
508 }
509
510
511
512
513
514
515
516
517
518
519
520
521 public String truncate(Object truncateMe, int maxLength, String suffix,
522 boolean defaultTruncateAtWord)
523 {
524 if (truncateMe == null || maxLength <= 0)
525 {
526 return null;
527 }
528
529 String string = String.valueOf(truncateMe);
530 if (string.length() <= maxLength)
531 {
532 return string;
533 }
534 if (suffix == null || maxLength - suffix.length() <= 0)
535 {
536
537 return string.substring(0, maxLength);
538 }
539 if (defaultTruncateAtWord)
540 {
541
542 int lastSpace = string.substring(0, maxLength - suffix.length() + 1)
543 .lastIndexOf(" ");
544 if (lastSpace > suffix.length())
545 {
546 return string.substring(0, lastSpace) + suffix;
547 }
548 }
549
550 return string.substring(0, maxLength - suffix.length()) + suffix;
551
552 }
553
554
555
556
557
558 public String space(int length)
559 {
560 if (length < 0)
561 {
562 return null;
563 }
564
565 StringBuilder space = new StringBuilder();
566 for (int i=0; i < length; i++)
567 {
568 space.append(' ');
569 }
570 return space.toString();
571 }
572
573
574
575
576
577
578 public String cell(Object obj)
579 {
580 return cell(obj, this.defaultCellLength);
581 }
582
583
584
585
586
587
588
589 public String cell(Object obj, int cellsize)
590 {
591 return cell(obj, cellsize, this.defaultCellSuffix);
592 }
593
594
595
596
597
598
599
600
601
602
603 public String cell(Object obj, String suffix)
604 {
605 return cell(obj, this.defaultCellLength, suffix);
606 }
607
608
609
610
611
612
613
614
615
616 public String cell(Object obj, int cellsize, String suffix)
617 {
618 if (obj == null || cellsize <= 0)
619 {
620 return null;
621 }
622
623 String value = String.valueOf(obj);
624 if (value.length() == cellsize)
625 {
626 return value;
627 }
628 else if (value.length() > cellsize)
629 {
630 return truncate(value, cellsize, suffix);
631 }
632 else
633 {
634 return value + space(cellsize - value.length());
635 }
636 }
637
638
639
640
641
642
643
644 public String capitalize(Object capitalizeMe)
645 {
646 if (capitalizeMe == null)
647 {
648 return null;
649 }
650
651 String string = String.valueOf(capitalizeMe);
652 switch (string.length())
653 {
654 case 0:
655 return string;
656 case 1:
657 return string.toUpperCase();
658 default:
659 StringBuilder out = new StringBuilder(string.length());
660 out.append(string.substring(0,1).toUpperCase());
661 out.append(string.substring(1, string.length()));
662 return out.toString();
663 }
664 }
665
666
667
668
669
670
671
672 public String uncapitalize(Object uncapitalizeMe)
673 {
674 if (uncapitalizeMe == null)
675 {
676 return null;
677 }
678
679 String string = String.valueOf(uncapitalizeMe);
680 switch (string.length())
681 {
682 case 0:
683 return string;
684 case 1:
685 return string.toLowerCase();
686 default:
687 StringBuilder out = new StringBuilder(string.length());
688 out.append(string.substring(0,1).toLowerCase());
689 out.append(string.substring(1, string.length()));
690 return out.toString();
691 }
692 }
693
694
695
696
697
698
699 public Object alt(Object checkMe)
700 {
701 return alt(checkMe, this.defaultAlternate);
702 }
703
704
705
706
707
708
709
710 public Object alt(Object checkMe, Object alternate)
711 {
712 if (checkMe == null)
713 {
714 return alternate;
715 }
716 return checkMe;
717 }
718
719
720
721
722
723
724
725 public String br(Object obj)
726 {
727 if (obj == null)
728 {
729 return null;
730 }
731 else
732 {
733 return String.valueOf(obj).replaceAll("\n", "<br />\n");
734 }
735 }
736
737
738
739
740
741
742 public String stripTags(Object obj)
743 {
744 return stripTags(obj, defaultAllowedTags);
745 }
746
747
748
749
750
751
752
753 public String stripTags(Object obj, String... allowedTags)
754 {
755 if (obj == null)
756 {
757 return null;
758 }
759
760
761 StringBuilder allowedTagList = new StringBuilder();
762 if (allowedTags != null)
763 {
764 for (String tag : allowedTags)
765 {
766 if (tag !=null && tag.matches("[a-zA-Z0-9]+"))
767 {
768 if (allowedTagList.length() > 0)
769 {
770 allowedTagList.append("|");
771 }
772 allowedTagList.append(tag);
773 }
774 }
775 }
776 String tagRule = "<[^>]*?>";
777 if (allowedTagList.length() > 0)
778 {
779 tagRule = "<(?!/?(" + allowedTagList.toString() + ")[\\s>/])[^>]*?>";
780 }
781 return Pattern.compile(tagRule, Pattern.CASE_INSENSITIVE)
782 .matcher(String.valueOf(obj)).replaceAll("");
783 }
784
785
786
787
788
789
790
791
792
793 public String plural(int value, String singular)
794 {
795 return plural(value, singular, null);
796 }
797
798
799
800
801
802
803
804
805 public String plural(int value, String singular, String plural)
806 {
807 if (value == 1 || value == -1)
808 {
809 return singular;
810 }
811 else if (plural != null)
812 {
813 return plural;
814 }
815 else if (singular == null || singular.length() == 0)
816 {
817 return singular;
818 }
819 else
820 {
821
822 boolean isCapital = !singular.substring(singular.length() - 1)
823 .toLowerCase().equals(singular
824 .substring(singular.length() - 1));
825
826 String word = singular.toLowerCase();
827
828 if (word.endsWith("x") || word.endsWith("sh")
829 || word.endsWith("ch") || word.endsWith("s"))
830 {
831 return singular.concat(isCapital ? "ES" : "es");
832 }
833 else if (word.length() > 1
834 && word.endsWith("y")
835 && !word.substring(word.length() - 2, word.length() - 1)
836 .matches("[aeiou]"))
837 {
838 return singular.substring(0, singular.length() - 1)
839 .concat(isCapital ? "IES" : "ies");
840 }
841 else
842 {
843 return singular.concat(isCapital ? "S" : "s");
844 }
845 }
846 }
847
848
849
850
851
852
853
854 protected Object getProperty(Object object, String property)
855 {
856 try
857 {
858 return PropertyUtils.getProperty(object, property);
859 }
860 catch (Exception e)
861 {
862 throw new IllegalArgumentException("Could not retrieve '"
863 + property + "' from " + object + ": " + e);
864 }
865 }
866
867
868
869
870 public Measurements measure(Object measureMe)
871 {
872 if (measureMe == null)
873 {
874 return null;
875 }
876 return new Measurements(String.valueOf(measureMe));
877 }
878
879
880
881
882
883
884
885 public static class Measurements
886 {
887 private int height;
888 private int width;
889
890 public Measurements(String s)
891 {
892 String[] lines = s.split("\n");
893 height = lines.length;
894 for (String line : lines)
895 {
896 if (line.length() > width)
897 {
898 width = line.length();
899 }
900 }
901 }
902
903 public int getHeight()
904 {
905 return height;
906 }
907
908 public int getWidth()
909 {
910 return width;
911 }
912
913 public String toString()
914 {
915 StringBuilder out = new StringBuilder(28);
916 out.append("{ height: ");
917 out.append(height);
918 out.append(", width: ");
919 out.append(width);
920 out.append(" }");
921 return out.toString();
922 }
923 }
924
925 }