99import java .util .stream .Collectors ;
1010import java .util .stream .Stream ;
1111
12+ /**
13+ * Represents sorting parameters for data retrieval and manipulation.
14+ * This class provides methods for creating, customizing, and applying sorting criteria
15+ * based on enum constants and associated sort properties. Sorting criteria can be defined
16+ * with various configurations, including direction and null-handling behavior.
17+ */
1218public record SortParameter <T extends Enum <?> & SortParameter .Definition >(List <SortField > sortFields ) {
1319 private static final String DEFAULT_SORT_PROPERTY = "id" ;
14- private static final Sort DEFAULT_SORT = Sort .by (
15- Sort .Direction .ASC ,
16- DEFAULT_SORT_PROPERTY
17- );
20+ private static final Sort .Direction DEFAULT_SORT_DIRETION = Sort .Direction .ASC ;
1821
22+ /**
23+ * Creates a {@link SortParameter} that represents an unsorted state.
24+ *
25+ * @param <T> a type that extends both {@link Enum} and {@link Definition}.
26+ * @return an instance of {@link SortParameter} configured with no sorting fields.
27+ */
1928 public static <T extends Enum <?> & Definition > SortParameter <T > unsorted () {
2029 return new SortParameter <>(Collections .emptyList ());
2130 }
2231
32+ /**
33+ * Creates a {@link SortParameter} initialized with the provided sort definitions.
34+ * Each provided enum constant is converted into a {@link SortField} with ascending
35+ * order direction and default null-handling behavior. This method allows the
36+ * specification of multiple sorting criteria.
37+ *
38+ * @param <T> a type parameter representing an enum that implements the {@link Definition} interface.
39+ * @param sortDefinitions an array of enum constants defining the sort properties. Must not be null.
40+ * @return a {@link SortParameter} instance configured with the given sort definitions.
41+ */
2342 @ SafeVarargs
2443 public static <T extends Enum <?> & Definition > SortParameter <T > by (
2544 @ NonNull T ... sortDefinitions
@@ -36,6 +55,42 @@ public static <T extends Enum<?> & Definition> SortParameter<T> by(
3655 );
3756 }
3857
58+ /**
59+ * Creates a {@link SortParameter} initialized with a single sort definition.
60+ * This method allows specifying the property to sort by, the direction of sorting,
61+ * and uses the default null-handling behavior ({@link Sort.NullHandling#NATIVE}).
62+ *
63+ * @param <T> a type that extends both {@link Enum} and {@link Definition}.
64+ * @param sortDefinition an enum constant defining the property to sort by. Must not be null.
65+ * @param direction the direction of sorting, either {@link Sort.Direction#ASC} or {@link Sort.Direction#DESC}.
66+ * Must not be null.
67+ * @return an instance of {@link SortParameter} configured with the given sort definition and direction.
68+ */
69+ public static <T extends Enum <?> & Definition > SortParameter <T > by (
70+ @ NonNull T sortDefinition ,
71+ @ NonNull Sort .Direction direction
72+ ) {
73+ return new SortParameter <>(
74+ List .of (new SortField (
75+ sortDefinition .name (),
76+ direction ,
77+ Sort .NullHandling .NATIVE
78+ )
79+ )
80+ );
81+ }
82+
83+ /**
84+ * Creates a {@link SortParameter} instance configured with a single sort definition.
85+ * This method allows specifying the property to sort by, the direction of sorting,
86+ * and null-handling behavior.
87+ *
88+ * @param <T> the type parameter extending both {@link Enum} and {@link Definition}.
89+ * @param sortDefinition an enum constant defining the property to sort by. Must not be null.
90+ * @param direction the direction of sorting, either {@link Sort.Direction#ASC} or {@link Sort.Direction#DESC}. Must not be null.
91+ * @param nullHandling the strategy for handling null values during sorting, specified by {@link Sort.NullHandling}. Must not be null.
92+ * @return an instance of {@link SortParameter} configured with the given sort definition, direction, and null-handling behavior.
93+ */
3994 public static <T extends Enum <?> & Definition > SortParameter <T > by (
4095 @ NonNull T sortDefinition ,
4196 @ NonNull Sort .Direction direction ,
@@ -51,10 +106,105 @@ public static <T extends Enum<?> & Definition> SortParameter<T> by(
51106 );
52107 }
53108
109+ /**
110+ * Adds additional sorting criteria to the existing {@link SortParameter}.
111+ * Each provided enum constant is converted into a {@link SortField} with ascending
112+ * order direction and default null-handling behavior.
113+ *
114+ * @param sortDefinitions an array of enum constants defining the additional sort properties. Must not be null.
115+ * @return the updated {@link SortParameter} instance containing the new sort definitions.
116+ */
117+ @ SafeVarargs
118+ public final SortParameter <T > and (
119+ @ NonNull T ... sortDefinitions
120+ ) {
121+ sortFields .addAll (
122+ Stream .of (sortDefinitions )
123+ .map (sortDefinition -> new SortField (
124+ sortDefinition .name (),
125+ Sort .Direction .ASC ,
126+ Sort .NullHandling .NATIVE
127+ )
128+ )
129+ .toList ()
130+ );
131+
132+ return this ;
133+ }
134+
135+ /**
136+ * Adds a sorting criterion to the current {@link SortParameter} instance.
137+ * The provided sort definition and direction are converted into a {@link SortField}
138+ * with default null-handling behavior and appended to the existing sort fields.
139+ *
140+ * @param sortDefinition the enum constant defining the property to sort by. Must not be null.
141+ * @param direction the direction of sorting, either {@link Sort.Direction#ASC} or {@link Sort.Direction#DESC}. Must not be null.
142+ * @return the updated {@link SortParameter} instance containing the new sorting criterion.
143+ */
144+ public SortParameter <T > and (
145+ @ NonNull T sortDefinition ,
146+ @ NonNull Sort .Direction direction
147+ ) {
148+ sortFields .add (
149+ new SortField (
150+ sortDefinition .name (),
151+ direction ,
152+ Sort .NullHandling .NATIVE
153+ )
154+ );
155+
156+ return this ;
157+ }
158+
159+ /**
160+ * Adds a sorting criterion to the current {@link SortParameter} instance. The provided sort definition,
161+ * direction, and null-handling behavior are converted into a {@link SortField} and appended to the
162+ * existing sort fields.
163+ *
164+ * @param sortDefinition the enum constant defining the property to sort by. Must not be null.
165+ * @param direction the direction of sorting, either {@link Sort.Direction#ASC} or {@link Sort.Direction#DESC}. Must not be null.
166+ * @param nullHandling the strategy for handling null values during sorting, specified by {@link Sort.NullHandling}. Must not be null.
167+ * @return the updated {@link SortParameter} instance containing the new sorting criterion.
168+ */
169+ public SortParameter <T > and (
170+ @ NonNull T sortDefinition ,
171+ @ NonNull Sort .Direction direction ,
172+ @ NonNull Sort .NullHandling nullHandling
173+ ) {
174+ sortFields .add (
175+ new SortField (
176+ sortDefinition .name (),
177+ direction ,
178+ nullHandling
179+ )
180+ );
181+
182+ return this ;
183+ }
184+
185+ /**
186+ * Returns the current {@link SortParameter} instance if it has defined sorting fields.
187+ * Otherwise, returns the provided fallback {@link SortParameter}.
188+ *
189+ * @param fallback the {@link SortParameter} to use as a fallback in case the current instance
190+ * has no defined sorting fields. Must not be null.
191+ * @return the current {@link SortParameter} if it has defined sorting fields,
192+ * or the provided fallback if it does not.
193+ */
54194 public SortParameter <T > or (@ NonNull SortParameter <T > fallback ) {
55195 return sortFields == null || sortFields .isEmpty () ? fallback : this ;
56196 }
57197
198+ /**
199+ * Builds a {@link Sort} object without applying any default sorting parameters. Converts the enum keys
200+ * of the provided map to their string names and generates the sort object.
201+ *
202+ * @param mapping a non-null map where the keys are enumeration values representing sort properties
203+ * and the values are their associated sort directions. The enumeration keys must
204+ * have a `name()` method for string conversion. Must not be null.
205+ * @return an instance of {@link Sort} created using the transformed key-value mapping,
206+ * excluding default sorting behavior.
207+ */
58208 public Sort buildSortWithoutDefault (@ NonNull Map <T , String > mapping ) {
59209 var stringMapping = mapping .entrySet ().stream ()
60210 .collect (Collectors .toMap (
@@ -65,6 +215,16 @@ public Sort buildSortWithoutDefault(@NonNull Map<T, String> mapping) {
65215 return buildSort (stringMapping , false );
66216 }
67217
218+ /**
219+ * Builds a {@link Sort} object based on the provided mapping of enumeration values to string properties.
220+ * Converts enum keys to their respective string names and generates the sort object.
221+ * <p>
222+ * If a sort mapping for "id" is provided, it will be used as the default sort property. Unless specified, this sort will be applied last.
223+ *
224+ * @param mapping a non-null map where the keys represent enumeration values and the values represent sort property names.
225+ * The enumeration keys must implement the `name()` method to retrieve their string representation.
226+ * @return an instance of {@link Sort} created using the transformed key-value mapping with default sorting behavior.
227+ */
68228 public Sort buildSort (@ NonNull Map <T , String > mapping ) {
69229 var stringMapping = mapping .entrySet ().stream ()
70230 .collect (Collectors .toMap (
@@ -79,7 +239,7 @@ public Sort buildSort(@NonNull Map<T, String> mapping) {
79239 @ SuppressWarnings ("java:S6204" )
80240 private Sort buildSort (@ NonNull Map <String , String > mapping , boolean withDefault ) {
81241 if (sortFields == null || sortFields .isEmpty ()) {
82- return withDefault ? DEFAULT_SORT : Sort .unsorted ();
242+ return withDefault ? getMappedDefaultSort ( mapping ) : Sort .unsorted ();
83243 }
84244
85245 var additionalSort = Sort .by (
@@ -97,19 +257,26 @@ private Sort buildSort(@NonNull Map<String, String> mapping, boolean withDefault
97257 if (withDefault ) {
98258 var includesDefault = additionalSort .getOrderFor (DEFAULT_SORT_PROPERTY ) != null ;
99259 if (!includesDefault ) {
100- return additionalSort .and (DEFAULT_SORT );
260+ return additionalSort .and (getMappedDefaultSort ( mapping ) );
101261 }
102262 }
103263 return additionalSort ;
104264 }
105265
266+ private static Sort getMappedDefaultSort (Map <String , String > mapping ) {
267+ return Sort .by (DEFAULT_SORT_DIRETION , mapping .getOrDefault (DEFAULT_SORT_PROPERTY , DEFAULT_SORT_PROPERTY ));
268+ }
269+
106270 public record SortField (
107271 @ NonNull String property ,
108272 @ NonNull Sort .Direction direction ,
109273 @ NonNull Sort .NullHandling nullHandling
110274 ) {
111275 }
112276
277+ /**
278+ * Interface to give enums the purpose of listing sortable keys.
279+ */
113280 public interface Definition {
114281 }
115282}
0 commit comments