1 package net.avcompris.commons3.core.impl;
2
3 import static com.google.common.base.Preconditions.checkArgument;
4 import static com.google.common.base.Preconditions.checkNotNull;
5 import static com.google.common.collect.Maps.newHashMap;
6 import static org.apache.commons.lang3.StringUtils.isBlank;
7 import static org.apache.commons.lang3.StringUtils.substringBeforeLast;
8
9 import java.util.ArrayList;
10 import java.util.List;
11 import java.util.Locale;
12 import java.util.Map;
13
14 import javax.annotation.Nullable;
15
16 import com.google.common.collect.Iterables;
17
18 public final class SortBysParser<T extends Enum<?>> {
19
20 private final Class<T> clazz;
21
22 private final Map<String, T> byLowercases = newHashMap();
23
24 public SortBysParser(final Class<T> clazz, final T[] values) {
25
26 this.clazz = checkNotNull(clazz, "clazz");
27
28 checkNotNull(values, "values");
29
30 for (final T value : values) {
31
32 final String name = value.toString();
33
34 checkArgument(name.startsWith("SORT_BY_"),
35 "SortBy item should start with \"SORT_BY_\", but was: %s", name);
36
37 final String lowercase = name.replace("_", "").toLowerCase(Locale.ENGLISH);
38
39 byLowercases.put(lowercase, value);
40 }
41 }
42
43 @Nullable
44 public T[] parse(@Nullable final String s) {
45
46 if (isBlank(s)) {
47 return null;
48 }
49
50 final List<T> sortBys = new ArrayList<>();
51
52 final StringBuilder sb = new StringBuilder();
53
54 boolean asc = true;
55
56 final String trim = s.trim().replace("_", "").toLowerCase(Locale.ENGLISH);
57
58 for (final char c : trim.toCharArray()) {
59
60 if (c == '+') {
61
62 if (sb.length() != 0) {
63
64 handleValue(sortBys, asc, sb.toString());
65
66 sb.setLength(0);
67 }
68
69 asc = true;
70
71 } else if (c == '-') {
72
73 if (sb.length() != 0) {
74
75 handleValue(sortBys, asc, sb.toString());
76
77 sb.setLength(0);
78 }
79
80 asc = false;
81
82 } else if (c == ' ' || c == ';' || c == ',' || c == '&') {
83
84 if (sb.length() != 0) {
85
86 handleValue(sortBys, asc, sb.toString());
87
88 sb.setLength(0);
89
90 asc = true;
91 }
92
93 } else {
94
95 sb.append(c);
96 }
97 }
98
99 if (sb.length() != 0) {
100
101 handleValue(sortBys, asc, sb.toString());
102 }
103
104 return sortBys.isEmpty() ? null : Iterables.toArray(sortBys, clazz);
105 }
106
107 private void handleValue(final List<T> sortBys, final boolean asc, final String s) {
108
109 final String lowercase;
110
111 if (s.endsWith("desc")) {
112
113 lowercase = "sortby" + substringBeforeLast(s, "desc") + (asc ? "desc" : "");
114
115 } else {
116
117 lowercase = "sortby" + s + (asc ? "" : "desc");
118 }
119
120 final T value = byLowercases.get(lowercase);
121
122 checkArgument (value != null,
123 "Unknown SortBy: %s", lowercase);
124
125 sortBys.add(value);
126 }
127 }