1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.bremersee.comparator.model;
18
19 import static java.util.Objects.isNull;
20
21 import com.fasterxml.jackson.annotation.JsonCreator;
22 import com.fasterxml.jackson.annotation.JsonIgnore;
23 import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
24 import com.fasterxml.jackson.annotation.JsonProperty;
25 import io.swagger.v3.oas.annotations.media.Schema;
26 import jakarta.xml.bind.annotation.XmlAccessType;
27 import jakarta.xml.bind.annotation.XmlAccessorType;
28 import jakarta.xml.bind.annotation.XmlElementRef;
29 import jakarta.xml.bind.annotation.XmlRootElement;
30 import jakarta.xml.bind.annotation.XmlTransient;
31 import jakarta.xml.bind.annotation.XmlType;
32 import java.io.Serial;
33 import java.io.Serializable;
34 import java.util.ArrayList;
35 import java.util.Arrays;
36 import java.util.Collection;
37 import java.util.Collections;
38 import java.util.List;
39 import java.util.Optional;
40 import java.util.StringTokenizer;
41 import java.util.stream.Collectors;
42 import lombok.EqualsAndHashCode;
43
44
45
46
47
48
49 @XmlAccessorType(XmlAccessType.FIELD)
50 @XmlRootElement(name = "sortOrder")
51 @XmlType(name = "sortOrderType")
52 @JsonIgnoreProperties(ignoreUnknown = true)
53 @Schema(description = "The sort order.")
54 @EqualsAndHashCode
55 public class SortOrder implements Serializable {
56
57 @Serial
58 private static final long serialVersionUID = 1;
59
60
61
62
63 public static final String DEFAULT_SEPARATOR = ";";
64
65
66
67
68 @Schema(description = "The sort order items.")
69 @XmlElementRef
70 private final List<SortOrderItem> items = new ArrayList<>();
71
72
73
74
75 protected SortOrder() {
76 super();
77 }
78
79
80
81
82
83
84 @JsonCreator
85 public SortOrder(@JsonProperty("items") Collection<? extends SortOrderItem> sortOrderItems) {
86 if (!isNull(sortOrderItems)) {
87 this.items.addAll(sortOrderItems);
88 }
89 }
90
91
92
93
94
95
96 public List<SortOrderItem> getItems() {
97 return Collections.unmodifiableList(items);
98 }
99
100
101
102
103
104
105 @XmlTransient
106 @JsonIgnore
107 public boolean isEmpty() {
108 return items.isEmpty();
109 }
110
111
112
113
114
115
116
117
118 @XmlTransient
119 @JsonIgnore
120 public boolean isSorted() {
121 return !isEmpty();
122 }
123
124
125
126
127
128
129
130
131 @XmlTransient
132 @JsonIgnore
133 public boolean isUnsorted() {
134 return !isSorted();
135 }
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152 @JsonIgnore
153 @XmlTransient
154 public String getSortOrderText() {
155 return getSortOrderText(SortOrderTextSeparators.defaults());
156 }
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174 public String getSortOrderText(SortOrderTextSeparators separators) {
175 String separator = Optional.ofNullable(separators)
176 .orElseGet(SortOrderTextSeparators::defaults)
177 .getChainSeparator();
178 return items.stream()
179 .map(item -> item.getSortOrderText(separators))
180 .collect(Collectors.joining(separator));
181 }
182
183 @Override
184 public String toString() {
185 return getSortOrderText();
186 }
187
188
189
190
191
192
193
194 public static SortOrder fromSortOrderText(String source) {
195 return fromSortOrderText(source, SortOrderTextSeparators.defaults());
196 }
197
198
199
200
201
202
203
204
205 public static SortOrder fromSortOrderText(String source, SortOrderTextSeparators separators) {
206 if (isNull(source)) {
207 return unsorted();
208 }
209 String separator = Optional.ofNullable(separators)
210 .orElseGet(SortOrderTextSeparators::defaults)
211 .getChainSeparator();
212 return Optional.of(source.trim())
213 .map(text -> {
214 List<SortOrderItem> sortOrderItems = new ArrayList<>();
215 StringTokenizer tokenizer = new StringTokenizer(text, separator);
216 while (tokenizer.hasMoreTokens()) {
217 sortOrderItems.add(SortOrderItem
218 .fromSortOrderText(tokenizer.nextToken(), separators));
219 }
220 if (sortOrderItems.isEmpty()) {
221 sortOrderItems.add(new SortOrderItem());
222 }
223 return new SortOrder(sortOrderItems);
224 })
225 .orElseGet(SortOrder::new);
226 }
227
228
229
230
231
232
233
234 public static SortOrder by(SortOrderItem... sortOrderItems) {
235 return Optional.ofNullable(sortOrderItems)
236 .map(so -> new SortOrder(Arrays.asList(so)))
237 .orElseGet(SortOrder::new);
238 }
239
240
241
242
243
244
245 public static SortOrder unsorted() {
246 return new SortOrder();
247 }
248
249 }