View Javadoc
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 }