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.util.ArrayList;
23 import java.util.Arrays;
24 import java.util.Comparator;
25 import java.util.Collection;
26 import java.util.Collections;
27 import java.util.List;
28 import java.util.Map;
29 import org.apache.commons.beanutils.PropertyUtils;
30 import org.apache.velocity.tools.config.DefaultKey;
31
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115 @DefaultKey("sorter")
116 public class SortTool
117 {
118
119 public Collection sort(Collection collection)
120 {
121 return sort(collection, (List)null);
122 }
123
124 public Collection sort(Object[] array)
125 {
126 return sort(array, (List)null);
127 }
128
129 public Collection sort(Map map)
130 {
131 return sort(map, (List)null);
132 }
133
134
135
136
137
138
139
140 public Collection sort(Object object, String property)
141 {
142 List properties = new ArrayList(1);
143 properties.add(property);
144
145 if (object instanceof Collection)
146 {
147 return sort((Collection)object, properties);
148 }
149 else if (object instanceof Object[])
150 {
151 return sort((Object[])object, properties);
152 }
153 else if (object instanceof Map)
154 {
155 return sort((Map)object, properties);
156 }
157
158 return null;
159 }
160
161 public Collection sort(Collection collection, List properties)
162 {
163 List list = new ArrayList(collection.size());
164 list.addAll(collection);
165 return internalSort(list, properties);
166 }
167
168 public Collection sort(Map map, List properties)
169 {
170 return sort(map.values(), properties);
171 }
172
173 public Collection sort(Object[] array, List properties)
174 {
175 return internalSort(Arrays.asList(array), properties);
176 }
177
178 protected Collection internalSort(List list, List properties)
179 {
180 try
181 {
182 if (properties == null)
183 {
184 Collections.sort(list);
185 } else {
186 Collections.sort(list, new PropertiesComparator(properties));
187 }
188 return list;
189 }
190 catch (Exception e)
191 {
192
193 return null;
194 }
195 }
196
197
198
199
200
201 public static class PropertiesComparator
202 implements Comparator, java.io.Serializable
203 {
204 private static final int TYPE_ASCENDING = 1;
205 private static final int TYPE_DESCENDING = -1;
206
207 public static final String TYPE_ASCENDING_SHORT = "asc";
208 public static final String TYPE_DESCENDING_SHORT = "desc";
209
210 List properties;
211 int[] sortTypes;
212
213 public PropertiesComparator(List props)
214 {
215
216 this.properties = new ArrayList(props.size());
217 this.properties.addAll(props);
218
219
220 sortTypes = new int[properties.size()];
221
222 for (int i = 0; i < properties.size(); i++)
223 {
224 if (properties.get(i) == null)
225 {
226 throw new IllegalArgumentException("Property " + i
227 + "is null, sort properties may not be null.");
228 }
229
230
231
232 String prop = properties.get(i).toString();
233 int colonIndex = prop.indexOf(':');
234 if (colonIndex != -1)
235 {
236 String sortType = prop.substring(colonIndex + 1);
237 properties.set(i, prop.substring(0, colonIndex));
238
239 if (TYPE_ASCENDING_SHORT.equalsIgnoreCase(sortType))
240 {
241 sortTypes[i] = TYPE_ASCENDING;
242 }
243 else if (TYPE_DESCENDING_SHORT.equalsIgnoreCase(sortType))
244 {
245 sortTypes[i] = TYPE_DESCENDING;
246 }
247 else
248 {
249
250
251 sortTypes[i] = TYPE_ASCENDING;
252 }
253 }
254 else
255 {
256
257 sortTypes[i] = TYPE_ASCENDING;
258 }
259 }
260 }
261
262 public int compare(Object lhs, Object rhs)
263 {
264 for (int i = 0; i < properties.size(); i++)
265 {
266 int comparison = 0;
267 String property = (String)properties.get(i);
268
269
270 Comparable left = getComparable(lhs, property);
271 Comparable right = getComparable(rhs, property);
272
273 if (left == null && right != null)
274 {
275
276 comparison = right.compareTo(null);
277
278 comparison *= -1;
279 }
280 else if (left instanceof String)
281 {
282
283 comparison = ((String)left).compareToIgnoreCase((String)right);
284 }
285 else if (left != null)
286 {
287 comparison = left.compareTo(right);
288 }
289
290
291 if (comparison != 0)
292 {
293
294 return comparison * sortTypes[i];
295 }
296 }
297 return 0;
298 }
299 }
300
301
302
303
304
305
306
307 protected static Comparable getComparable(Object object, String property)
308 {
309 try
310 {
311 return (Comparable)PropertyUtils.getProperty(object, property);
312 }
313 catch (Exception e)
314 {
315 throw new IllegalArgumentException("Could not retrieve comparable value for '"
316 + property + "' from " + object + ": " + e);
317 }
318 }
319
320 }