Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
Comparators |
|
| 1.7647058823529411;1.765 | ||||
Comparators$1 |
|
| 1.7647058823529411;1.765 | ||||
Comparators$Chain |
|
| 1.7647058823529411;1.765 | ||||
Comparators$CommandFirst |
|
| 1.7647058823529411;1.765 | ||||
Comparators$DefaultOptionFirst |
|
| 1.7647058823529411;1.765 | ||||
Comparators$GroupFirst |
|
| 1.7647058823529411;1.765 | ||||
Comparators$Named |
|
| 1.7647058823529411;1.765 | ||||
Comparators$PreferredName |
|
| 1.7647058823529411;1.765 | ||||
Comparators$Required |
|
| 1.7647058823529411;1.765 | ||||
Comparators$Reverse |
|
| 1.7647058823529411;1.765 | ||||
Comparators$SwitchFirst |
|
| 1.7647058823529411;1.765 |
1 | /** | |
2 | * Licensed to the Apache Software Foundation (ASF) under one or more | |
3 | * contributor license agreements. See the NOTICE file distributed with | |
4 | * this work for additional information regarding copyright ownership. | |
5 | * The ASF licenses this file to You under the Apache License, Version 2.0 | |
6 | * (the "License"); you may not use this file except in compliance with | |
7 | * the License. You may obtain a copy of the License at | |
8 | * | |
9 | * http://www.apache.org/licenses/LICENSE-2.0 | |
10 | * | |
11 | * Unless required by applicable law or agreed to in writing, software | |
12 | * distributed under the License is distributed on an "AS IS" BASIS, | |
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
14 | * See the License for the specific language governing permissions and | |
15 | * limitations under the License. | |
16 | */ | |
17 | package org.apache.commons.cli2.util; | |
18 | ||
19 | import java.util.Comparator; | |
20 | import java.util.List; | |
21 | ||
22 | import org.apache.commons.cli2.Group; | |
23 | import org.apache.commons.cli2.Option; | |
24 | import org.apache.commons.cli2.option.Command; | |
25 | import org.apache.commons.cli2.option.DefaultOption; | |
26 | import org.apache.commons.cli2.option.Switch; | |
27 | ||
28 | /** | |
29 | * A collection of Comparators suitable for use with Option instances. | |
30 | */ | |
31 | public class Comparators { | |
32 | ||
33 | 0 | private Comparators(){ |
34 | // constructor hiden from potential users | |
35 | 0 | } |
36 | ||
37 | ||
38 | /** | |
39 | * Chains comparators together. | |
40 | * | |
41 | * @see #chain(Comparator[]) | |
42 | * @param c0 | |
43 | * a comparator | |
44 | * @param c1 | |
45 | * a comparator | |
46 | * @return a chained comparator | |
47 | */ | |
48 | public static Comparator chain(final Comparator c0, final Comparator c1) { | |
49 | 1 | return chain(new Comparator[] { c0, c1 }); |
50 | } | |
51 | ||
52 | /** | |
53 | * Chains comparators together. | |
54 | * | |
55 | * @see #chain(Comparator[]) | |
56 | * @param c0 | |
57 | * a comparator | |
58 | * @param c1 | |
59 | * a comparator | |
60 | * @param c2 | |
61 | * a comparator | |
62 | * @return a chained comparator | |
63 | */ | |
64 | public static Comparator chain( | |
65 | final Comparator c0, | |
66 | final Comparator c1, | |
67 | final Comparator c2) { | |
68 | 0 | return chain(new Comparator[] { c0, c1, c2 }); |
69 | } | |
70 | ||
71 | /** | |
72 | * Chains comparators together. | |
73 | * | |
74 | * @see #chain(Comparator[]) | |
75 | * @param c0 | |
76 | * a comparator | |
77 | * @param c1 | |
78 | * a comparator | |
79 | * @param c2 | |
80 | * a comparator | |
81 | * @param c3 | |
82 | * a comparator | |
83 | * @return a chained comparator | |
84 | */ | |
85 | public static Comparator chain( | |
86 | final Comparator c0, | |
87 | final Comparator c1, | |
88 | final Comparator c2, | |
89 | final Comparator c3) { | |
90 | 0 | return chain(new Comparator[] { c0, c1, c2, c3 }); |
91 | } | |
92 | ||
93 | /** | |
94 | * Chains comparators together. | |
95 | * | |
96 | * @see #chain(Comparator[]) | |
97 | * @param c0 | |
98 | * a comparator | |
99 | * @param c1 | |
100 | * a comparator | |
101 | * @param c2 | |
102 | * a comparator | |
103 | * @param c3 | |
104 | * a comparator | |
105 | * @param c4 | |
106 | * a comparator | |
107 | * @return a chained comparator | |
108 | */ | |
109 | public static Comparator chain( | |
110 | final Comparator c0, | |
111 | final Comparator c1, | |
112 | final Comparator c2, | |
113 | final Comparator c3, | |
114 | final Comparator c4) { | |
115 | 0 | return chain(new Comparator[] { c0, c1, c2, c3, c4 }); |
116 | } | |
117 | ||
118 | /** | |
119 | * Chains comparators together. | |
120 | * | |
121 | * @see #chain(Comparator[]) | |
122 | * @param comparators | |
123 | * a List of comparators to chain together | |
124 | * @return a chained comparator | |
125 | */ | |
126 | public static Comparator chain(final List comparators) { | |
127 | 0 | return new Chain( |
128 | (Comparator[])comparators.toArray( | |
129 | new Comparator[comparators.size()])); | |
130 | } | |
131 | ||
132 | /** | |
133 | * Chains an array of comparators together. Each Comparator will be called | |
134 | * in turn until one of them return a non-zero value, this value will be | |
135 | * returned. | |
136 | * | |
137 | * @param comparators | |
138 | * the array of comparators | |
139 | * @return a chained comparator | |
140 | */ | |
141 | public static Comparator chain(final Comparator[] comparators) { | |
142 | 1 | return new Chain(comparators); |
143 | } | |
144 | ||
145 | /** | |
146 | * Chains a series of Comparators together. | |
147 | */ | |
148 | private static class Chain implements Comparator { | |
149 | ||
150 | final Comparator[] chain; | |
151 | ||
152 | /** | |
153 | * Creates a Comparator chain using the specified array of Comparators | |
154 | * @param chain the Comparators in the chain | |
155 | */ | |
156 | 1 | public Chain(final Comparator[] chain) { |
157 | 1 | this.chain = new Comparator[chain.length]; |
158 | 1 | System.arraycopy(chain, 0, this.chain, 0, chain.length); |
159 | 1 | } |
160 | ||
161 | public int compare(final Object left, final Object right) { | |
162 | 4 | int result = 0; |
163 | 9 | for (int i = 0; result == 0 && i < chain.length; ++i) { |
164 | 5 | result = chain[i].compare(left, right); |
165 | } | |
166 | 4 | return result; |
167 | } | |
168 | } | |
169 | ||
170 | /** | |
171 | * Reverses a comparator's logic. | |
172 | * | |
173 | * @param wrapped | |
174 | * the Comparator to reverse the logic of | |
175 | * @return a comparator with reverse logic | |
176 | */ | |
177 | private static Comparator reverse(final Comparator wrapped) { | |
178 | 7 | return new Reverse(wrapped); |
179 | } | |
180 | ||
181 | private static class Reverse implements Comparator { | |
182 | private final Comparator wrapped; | |
183 | ||
184 | /** | |
185 | * Creates a Comparator with reverse logic | |
186 | * @param wrapped the original logic | |
187 | */ | |
188 | 7 | public Reverse(final Comparator wrapped) { |
189 | 7 | this.wrapped = wrapped; |
190 | 7 | } |
191 | ||
192 | public int compare(final Object left, final Object right) { | |
193 | 7 | return -wrapped.compare(left, right); |
194 | } | |
195 | } | |
196 | ||
197 | /** | |
198 | * Forces Group instances to appear at the beginning of lists | |
199 | * | |
200 | * @see Group | |
201 | * @return a new comparator | |
202 | */ | |
203 | public static Comparator groupFirst() { | |
204 | 2 | return new GroupFirst(); |
205 | } | |
206 | ||
207 | /** | |
208 | * Forces Group instances to appear at the end of lists | |
209 | * | |
210 | * @see Group | |
211 | * @return a new comparator | |
212 | */ | |
213 | public static Comparator groupLast() { | |
214 | 1 | return reverse(groupFirst()); |
215 | } | |
216 | ||
217 | 4 | private static class GroupFirst implements Comparator { |
218 | public int compare(final Object left, final Object right) { | |
219 | 2 | final boolean l = left instanceof Group; |
220 | 2 | final boolean r = right instanceof Group; |
221 | ||
222 | 2 | if (l ^ r) { |
223 | 2 | if (l) { |
224 | 0 | return -1; |
225 | } | |
226 | 2 | return 1; |
227 | } | |
228 | 0 | return 0; |
229 | } | |
230 | } | |
231 | ||
232 | /** | |
233 | * Forces Switch instances to appear at the beginning of lists | |
234 | * | |
235 | * @see Switch | |
236 | * @return a new comparator | |
237 | */ | |
238 | public static Comparator switchFirst() { | |
239 | 2 | return new SwitchFirst(); |
240 | } | |
241 | ||
242 | /** | |
243 | * Forces Switch instances to appear at the end of lists | |
244 | * | |
245 | * @see Switch | |
246 | * @return a new comparator | |
247 | */ | |
248 | public static Comparator switchLast() { | |
249 | 1 | return reverse(switchFirst()); |
250 | } | |
251 | ||
252 | 4 | private static class SwitchFirst implements Comparator { |
253 | public int compare(final Object left, final Object right) { | |
254 | 2 | final boolean l = left instanceof Switch; |
255 | 2 | final boolean r = right instanceof Switch; |
256 | ||
257 | 2 | if (l ^ r) { |
258 | 2 | if (l) { |
259 | 0 | return -1; |
260 | } | |
261 | 2 | return 1; |
262 | } | |
263 | 0 | return 0; |
264 | } | |
265 | } | |
266 | ||
267 | /** | |
268 | * Forces Command instances to appear at the beginning of lists | |
269 | * | |
270 | * @see Command | |
271 | * @return a new comparator | |
272 | */ | |
273 | public static Comparator commandFirst() { | |
274 | 3 | return new CommandFirst(); |
275 | } | |
276 | ||
277 | /** | |
278 | * Forces Command instances to appear at the end of lists | |
279 | * | |
280 | * @see Command | |
281 | * @return a new comparator | |
282 | */ | |
283 | public static Comparator commandLast() { | |
284 | 1 | return reverse(commandFirst()); |
285 | } | |
286 | ||
287 | 6 | private static class CommandFirst implements Comparator { |
288 | public int compare(final Object left, final Object right) { | |
289 | 3 | final boolean l = left instanceof Command; |
290 | 3 | final boolean r = right instanceof Command; |
291 | ||
292 | 3 | if (l ^ r) { |
293 | 3 | if (l) { |
294 | 0 | return -1; |
295 | } | |
296 | 3 | return 1; |
297 | } | |
298 | 0 | return 0; |
299 | } | |
300 | } | |
301 | ||
302 | /** | |
303 | * Forces DefaultOption instances to appear at the beginning of lists | |
304 | * | |
305 | * @see DefaultOption | |
306 | * @return a new comparator | |
307 | */ | |
308 | public static Comparator defaultOptionFirst() { | |
309 | 2 | return new DefaultOptionFirst(); |
310 | } | |
311 | ||
312 | /** | |
313 | * Forces DefaultOption instances to appear at the end of lists | |
314 | * | |
315 | * @see DefaultOption | |
316 | * @return a new comparator | |
317 | */ | |
318 | public static Comparator defaultOptionLast() { | |
319 | 1 | return reverse(defaultOptionFirst()); |
320 | } | |
321 | ||
322 | 4 | private static class DefaultOptionFirst implements Comparator { |
323 | public int compare(final Object left, final Object right) { | |
324 | 2 | final boolean l = left instanceof DefaultOption; |
325 | 2 | final boolean r = right instanceof DefaultOption; |
326 | ||
327 | 2 | if (l ^ r) { |
328 | 2 | if (l) { |
329 | 0 | return -1; |
330 | } | |
331 | 2 | return 1; |
332 | } | |
333 | 0 | return 0; |
334 | } | |
335 | } | |
336 | ||
337 | /** | |
338 | * Forces Comparators with a particular trigger to appear at the beginning | |
339 | * of lists | |
340 | * | |
341 | * @param name | |
342 | * the trigger name to select | |
343 | * @see Option#getTriggers() | |
344 | * @return a new comparator | |
345 | */ | |
346 | public static Comparator namedFirst(final String name) { | |
347 | 2 | return new Named(name); |
348 | } | |
349 | ||
350 | /** | |
351 | * Forces Comparators with a particular trigger to appear at the end of | |
352 | * lists | |
353 | * | |
354 | * @param name | |
355 | * the trigger name to select | |
356 | * @see Option#getTriggers() | |
357 | * @return a new comparator | |
358 | */ | |
359 | public static Comparator namedLast(final String name) { | |
360 | 1 | return reverse(new Named(name)); |
361 | } | |
362 | ||
363 | private static class Named implements Comparator { | |
364 | private final String name; | |
365 | ||
366 | /** | |
367 | * Creates a Comparator that sorts a particular name high in order | |
368 | * @param name the trigger name to select | |
369 | */ | |
370 | 3 | public Named(final String name) { |
371 | 3 | this.name = name; |
372 | 3 | } |
373 | public int compare(final Object oleft, final Object oright) { | |
374 | 6 | final Option left = (Option)oleft; |
375 | 6 | final Option right = (Option)oright; |
376 | ||
377 | 6 | final boolean l = left.getTriggers().contains(name); |
378 | 6 | final boolean r = right.getTriggers().contains(name); |
379 | ||
380 | 6 | if (l ^ r) { |
381 | 5 | if (l) { |
382 | 3 | return -1; |
383 | } | |
384 | 2 | return 1; |
385 | } | |
386 | 1 | return 0; |
387 | } | |
388 | } | |
389 | ||
390 | /** | |
391 | * Orders Options by preferredName | |
392 | * | |
393 | * @see Option#getPreferredName() | |
394 | * @return a new comparator | |
395 | */ | |
396 | public static Comparator preferredNameFirst() { | |
397 | 2 | return new PreferredName(); |
398 | } | |
399 | ||
400 | /** | |
401 | * Orders Options by preferredName, reversed | |
402 | * | |
403 | * @see Option#getPreferredName() | |
404 | * @return a new comparator | |
405 | */ | |
406 | public static Comparator preferredNameLast() { | |
407 | 1 | return reverse(preferredNameFirst()); |
408 | } | |
409 | ||
410 | 4 | private static class PreferredName implements Comparator { |
411 | public int compare(final Object oleft, final Object oright) { | |
412 | 2 | final Option left = (Option)oleft; |
413 | 2 | final Option right = (Option)oright; |
414 | ||
415 | 2 | return left.getPreferredName().compareTo(right.getPreferredName()); |
416 | } | |
417 | } | |
418 | ||
419 | /** | |
420 | * Orders Options grouping required Options first | |
421 | * | |
422 | * @see Option#isRequired() | |
423 | * @return a new comparator | |
424 | */ | |
425 | public static Comparator requiredFirst() { | |
426 | 2 | return new Required(); |
427 | } | |
428 | ||
429 | /** | |
430 | * Orders Options grouping required Options last | |
431 | * | |
432 | * @see Option#isRequired() | |
433 | * @return a new comparator | |
434 | */ | |
435 | public static Comparator requiredLast() { | |
436 | 1 | return reverse(requiredFirst()); |
437 | } | |
438 | ||
439 | 4 | private static class Required implements Comparator { |
440 | public int compare(final Object oleft, final Object oright) { | |
441 | 2 | final Option left = (Option)oleft; |
442 | 2 | final Option right = (Option)oright; |
443 | ||
444 | 2 | final boolean l = left.isRequired(); |
445 | 2 | final boolean r = right.isRequired(); |
446 | ||
447 | 2 | if (l ^ r) { |
448 | 2 | if (l) { |
449 | 2 | return -1; |
450 | } | |
451 | 0 | return 1; |
452 | } | |
453 | 0 | return 0; |
454 | } | |
455 | } | |
456 | } |