3131
3232import org .springframework .data .util .MethodInvocationRecorder ;
3333import org .springframework .data .util .MethodInvocationRecorder .Recorded ;
34+ import org .springframework .data .util .PropertyPath ;
3435import org .springframework .data .util .Streamable ;
36+ import org .springframework .data .util .TypedPropertyPath ;
3537import org .springframework .lang .CheckReturnValue ;
3638import org .springframework .lang .Contract ;
3739import org .springframework .util .Assert ;
@@ -94,6 +96,24 @@ public static Sort by(String... properties) {
9496 : new Sort (DEFAULT_DIRECTION , Arrays .asList (properties ));
9597 }
9698
99+ /**
100+ * Creates a new {@link Sort} for the given properties.
101+ *
102+ * @param properties must not be {@literal null}.
103+ * @return {@link Sort} for the given properties.
104+ * @since 4.1
105+ */
106+ @ SafeVarargs
107+ public static <T > Sort by (TypedPropertyPath <T , ?>... properties ) {
108+
109+ Assert .notNull (properties , "Properties must not be null" );
110+
111+ return properties .length == 0 //
112+ ? Sort .unsorted () //
113+ : new Sort (DEFAULT_DIRECTION , Arrays .stream (properties ).map (TypedPropertyPath ::of ).map (PropertyPath ::toDotPath )
114+ .collect (Collectors .toList ()));
115+ }
116+
97117 /**
98118 * Creates a new {@link Sort} for the given {@link Order}s.
99119 *
@@ -120,6 +140,25 @@ public static Sort by(Order... orders) {
120140 return new Sort (Arrays .asList (orders ));
121141 }
122142
143+ /**
144+ * Creates a new {@link Sort} for the given {@link Direction} and properties.
145+ *
146+ * @param direction must not be {@literal null}.
147+ * @param properties must not be {@literal null}.
148+ * @return {@link Sort} for the given {@link Direction} and properties.
149+ * @since 4.1
150+ */
151+ @ SafeVarargs
152+ public static <T > Sort by (Direction direction , TypedPropertyPath <T , ?>... properties ) {
153+
154+ Assert .notNull (direction , "Direction must not be null" );
155+ Assert .notNull (properties , "Properties must not be null" );
156+ Assert .isTrue (properties .length > 0 , "At least one property must be given" );
157+
158+ return by (Arrays .stream (properties ).map (TypedPropertyPath ::of ).map (PropertyPath ::toDotPath )
159+ .map (it -> new Order (direction , it )).toList ());
160+ }
161+
123162 /**
124163 * Creates a new {@link Sort} for the given {@link Direction} and properties.
125164 *
@@ -144,7 +183,9 @@ public static Sort by(Direction direction, String... properties) {
144183 * @param type must not be {@literal null}.
145184 * @return {@link TypedSort} for the given type.
146185 * @since 2.2
186+ * @deprecated since 4.1 in favor of {@link Sort#by(TypedPropertyPath[])}.
147187 */
188+ @ Deprecated (since = "4.1" )
148189 public static <T > TypedSort <T > sort (Class <T > type ) {
149190 return new TypedSort <>(type );
150191 }
@@ -460,6 +501,17 @@ public Order(@Nullable Direction direction, String property, boolean ignoreCase,
460501 this .nullHandling = nullHandling ;
461502 }
462503
504+ /**
505+ * Creates a new {@link Order} instance. Takes a property path. Direction defaults to
506+ * {@link Sort#DEFAULT_DIRECTION}.
507+ *
508+ * @param propertyPath must not be {@literal null} or empty.
509+ * @since 4.1
510+ */
511+ public static <T , P > Order by (TypedPropertyPath <T , P > propertyPath ) {
512+ return by (TypedPropertyPath .of (propertyPath ).toDotPath ());
513+ }
514+
463515 /**
464516 * Creates a new {@link Order} instance. Takes a single property. Direction defaults to
465517 * {@link Sort#DEFAULT_DIRECTION}.
@@ -471,6 +523,17 @@ public static Order by(String property) {
471523 return new Order (DEFAULT_DIRECTION , property );
472524 }
473525
526+ /**
527+ * Creates a new {@link Order} instance. Takes a property path. Direction is {@link Direction#ASC} and NullHandling
528+ * {@link NullHandling#NATIVE}.
529+ *
530+ * @param propertyPath must not be {@literal null} or empty.
531+ * @since 4.1
532+ */
533+ public static <T , P > Order asc (TypedPropertyPath <T , P > propertyPath ) {
534+ return asc (TypedPropertyPath .of (propertyPath ).toDotPath ());
535+ }
536+
474537 /**
475538 * Creates a new {@link Order} instance. Takes a single property. Direction is {@link Direction#ASC} and
476539 * NullHandling {@link NullHandling#NATIVE}.
@@ -482,6 +545,17 @@ public static Order asc(String property) {
482545 return new Order (Direction .ASC , property , DEFAULT_NULL_HANDLING );
483546 }
484547
548+ /**
549+ * Creates a new {@link Order} instance. Takes a property path. Direction is {@link Direction#DESC} and NullHandling
550+ * {@link NullHandling#NATIVE}.
551+ *
552+ * @param propertyPath must not be {@literal null} or empty.
553+ * @since 4.1
554+ */
555+ public static <T , P > Order desc (TypedPropertyPath <T , P > propertyPath ) {
556+ return desc (TypedPropertyPath .of (propertyPath ).toDotPath ());
557+ }
558+
485559 /**
486560 * Creates a new {@link Order} instance. Takes a single property. Direction is {@link Direction#DESC} and
487561 * NullHandling {@link NullHandling#NATIVE}.
@@ -562,6 +636,19 @@ public Order reverse() {
562636 return with (this .direction == Direction .ASC ? Direction .DESC : Direction .ASC );
563637 }
564638
639+ /**
640+ * Returns a new {@link Order} with the {@code propertyPath} applied.
641+ *
642+ * @param propertyPath must not be {@literal null} or empty.
643+ * @return a new {@link Order} with the {@code propertyPath} applied.
644+ * @since 4.1
645+ */
646+ @ Contract ("_ -> new" )
647+ @ CheckReturnValue
648+ public <T , P > Order withProperty (TypedPropertyPath <T , P > propertyPath ) {
649+ return withProperty (TypedPropertyPath .of (propertyPath ).toDotPath ());
650+ }
651+
565652 /**
566653 * Returns a new {@link Order} with the {@code property} name applied.
567654 *
@@ -575,6 +662,20 @@ public Order withProperty(String property) {
575662 return new Order (this .direction , property , this .ignoreCase , this .nullHandling );
576663 }
577664
665+ /**
666+ * Returns a new {@link Sort} instance for the given properties using {@link #getDirection()}.
667+ *
668+ * @param propertyPaths properties to sort by.
669+ * @return a new {@link Sort} instance for the given properties using {@link #getDirection()}.
670+ * @since 4.1
671+ */
672+ @ Contract ("_ -> new" )
673+ @ CheckReturnValue
674+ public <T > Sort withProperties (TypedPropertyPath <T , ?>... propertyPaths ) {
675+ return Sort .by (this .direction ,
676+ Arrays .stream (propertyPaths ).map (TypedPropertyPath ::toDotPath ).toArray (String []::new ));
677+ }
678+
578679 /**
579680 * Returns a new {@link Sort} instance for the given properties using {@link #getDirection()}.
580681 *
@@ -696,7 +797,9 @@ public String toString() {
696797 * @author Oliver Gierke
697798 * @since 2.2
698799 * @soundtrack The Intersphere - Linger (The Grand Delusion)
800+ * @deprecated since 4.1 in favor of {@link Sort#by(org.springframework.data.util.TypedPropertyPath...)}
699801 */
802+ @ Deprecated (since = "4.1" )
700803 public static class TypedSort <T > extends Sort {
701804
702805 private static final @ Serial long serialVersionUID = -3550403511206745880L ;
0 commit comments