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 @Schema(description = "The sort order items.")
66 @XmlElementRef
67 private final List<SortOrderItem> items = new ArrayList<>();
68
69
70
71
72 protected SortOrder() {
73 super();
74 }
75
76
77
78
79
80
81 @JsonCreator
82 public SortOrder(@JsonProperty("items") Collection<? extends SortOrderItem> sortOrderItems) {
83 if (!isNull(sortOrderItems)) {
84 this.items.addAll(sortOrderItems);
85 }
86 }
87
88
89
90
91
92
93 public List<SortOrderItem> getItems() {
94 return Collections.unmodifiableList(items);
95 }
96
97
98
99
100
101
102 @XmlTransient
103 @JsonIgnore
104 public boolean isEmpty() {
105 return items.isEmpty();
106 }
107
108
109
110
111
112
113
114
115 @XmlTransient
116 @JsonIgnore
117 public boolean isSorted() {
118 return !isEmpty();
119 }
120
121
122
123
124
125
126
127
128 @XmlTransient
129 @JsonIgnore
130 public boolean isUnsorted() {
131 return !isSorted();
132 }
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149 @JsonIgnore
150 @XmlTransient
151 public String getSortOrderText() {
152 return getSortOrderText(SortOrderTextSeparators.defaults());
153 }
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171 public String getSortOrderText(SortOrderTextSeparators separators) {
172 String separator = Optional.ofNullable(separators)
173 .orElseGet(SortOrderTextSeparators::defaults)
174 .getChainSeparator();
175 return items.stream()
176 .map(item -> item.getSortOrderText(separators))
177 .collect(Collectors.joining(separator));
178 }
179
180 @Override
181 public String toString() {
182 return getSortOrderText();
183 }
184
185
186
187
188
189
190
191 public static SortOrder fromSortOrderText(String source) {
192 return fromSortOrderText(source, SortOrderTextSeparators.defaults());
193 }
194
195
196
197
198
199
200
201
202 public static SortOrder fromSortOrderText(String source, SortOrderTextSeparators separators) {
203 if (isNull(source)) {
204 return unsorted();
205 }
206 String separator = Optional.ofNullable(separators)
207 .orElseGet(SortOrderTextSeparators::defaults)
208 .getChainSeparator();
209 return Optional.of(source.trim())
210 .map(text -> {
211 List<SortOrderItem> sortOrderItems = new ArrayList<>();
212 StringTokenizer tokenizer = new StringTokenizer(text, separator);
213 while (tokenizer.hasMoreTokens()) {
214 sortOrderItems.add(SortOrderItem
215 .fromSortOrderText(tokenizer.nextToken(), separators));
216 }
217 if (sortOrderItems.isEmpty()) {
218 sortOrderItems.add(new SortOrderItem());
219 }
220 return new SortOrder(sortOrderItems);
221 })
222 .orElseGet(SortOrder::new);
223 }
224
225
226
227
228
229
230
231 public static SortOrder by(SortOrderItem... sortOrderItems) {
232 return Optional.ofNullable(sortOrderItems)
233 .map(so -> new SortOrder(Arrays.asList(so)))
234 .orElseGet(SortOrder::new);
235 }
236
237 public static SortOrder unsorted() {
238 return new SortOrder();
239 }
240
241 }