1818import java .util .Optional ;
1919
2020import org .jspecify .annotations .Nullable ;
21+
22+ import org .springframework .data .core .PropertyPath ;
23+ import org .springframework .data .core .TypedPropertyPath ;
2124import org .springframework .util .Assert ;
2225
2326import com .datastax .oss .driver .api .core .CqlIdentifier ;
3639 */
3740public abstract class ColumnName {
3841
42+ /**
43+ * Create a {@link ColumnName} given a {@link TypedPropertyPath property}.
44+ *
45+ * @param property must not be {@literal null}.
46+ * @return the {@link ColumnName} for {@link PropertyPath}
47+ * @since 5.1
48+ */
49+ public static <T , P > ColumnName from (TypedPropertyPath <T , P > property ) {
50+ return from ((PropertyPath ) TypedPropertyPath .of (property ));
51+ }
52+
53+ /**
54+ * Create a {@link ColumnName} given a {@link PropertyPath property}.
55+ *
56+ * @param propertyPath must not be {@literal null}.
57+ * @return the {@link ColumnName} for {@link PropertyPath}
58+ * @since 5.1
59+ */
60+ public static ColumnName from (PropertyPath propertyPath ) {
61+ return new PropertyPathColumnName (propertyPath );
62+ }
63+
3964 /**
4065 * Create a {@link ColumnName} given {@link CqlIdentifier}. The resulting instance uses CQL identifier rules to
4166 * identify column names (quoting, case-sensitivity).
@@ -45,9 +70,6 @@ public abstract class ColumnName {
4570 * @see CqlIdentifier
4671 */
4772 public static ColumnName from (CqlIdentifier cqlIdentifier ) {
48-
49- Assert .notNull (cqlIdentifier , "Column name must not be null" );
50-
5173 return new CqlIdentifierColumnName (cqlIdentifier );
5274 }
5375
@@ -56,26 +78,79 @@ public static ColumnName from(CqlIdentifier cqlIdentifier) {
5678 * column names (case-sensitivity).
5779 *
5880 * @param columnName must not be {@literal null} or empty.
59- * @return the {@link ColumnName} for {@link CqlIdentifier }
81+ * @return the {@link ColumnName} for {@code columnName }
6082 */
6183 public static ColumnName from (String columnName ) {
62-
63- Assert .hasText (columnName , "Column name must not be null or empty" );
64-
6584 return new StringColumnName (columnName );
6685 }
6786
6887 /**
6988 * @return the optional column name.
7089 */
71- public abstract Optional <String > getColumnName ();
90+ public Optional <String > getColumnName () {
91+ return Optional .empty ();
92+ }
93+
94+ /**
95+ * Indicates whether a column name is available.
96+ *
97+ * @return {@literal true} if a (string or {@link CqlIdentifier}) column name is available; {@literal false}
98+ * otherwise.
99+ * @since 5.1
100+ */
101+ public boolean hasColumnName () {
102+ return getColumnName ().isPresent ();
103+ }
104+
105+ /**
106+ * @return the optional {@link PropertyPath}.
107+ */
108+ public @ Nullable PropertyPath getPropertyPath () {
109+ return null ;
110+ }
111+
112+ /**
113+ * Indicates whether a {@link PropertyPath} is available.
114+ *
115+ * @return {@literal true} if a {@link PropertyPath} is available; {@literal false} otherwise.
116+ * @since 5.1
117+ */
118+ public boolean hasPropertyPath () {
119+ return getPropertyPath () != null ;
120+ }
121+
122+ /**
123+ * Returns the required {@link PropertyPath} or throws an {@link IllegalStateException} if not available.
124+ *
125+ * @return the required {@link PropertyPath}.
126+ * @throws IllegalStateException if no {@link PropertyPath} is available.
127+ * @since 5.1
128+ */
129+ public PropertyPath getRequiredPropertyPath () {
130+
131+ PropertyPath propertyPath = getPropertyPath ();
132+
133+ if (propertyPath == null ) {
134+ throw new IllegalStateException ("No PropertyPath available" );
135+ }
136+
137+ return propertyPath ;
138+ }
72139
73140 /**
74141 * @return the optional {@link CqlIdentifier}.
75142 */
76- public abstract Optional <CqlIdentifier > getCqlIdentifier ();
143+ public Optional <CqlIdentifier > getCqlIdentifier () {
144+ return Optional .empty ();
145+ }
77146
78- CqlIdentifier getRequiredCqlIdentifier () {
147+ /**
148+ * Returns the required {@link CqlIdentifier} or constructs one from available information.
149+ *
150+ * @return the required {@link CqlIdentifier}.
151+ * @since 5.1
152+ */
153+ public CqlIdentifier getRequiredCqlIdentifier () {
79154 return getCqlIdentifier ().or (() -> getColumnName ().map (CqlIdentifier ::fromCql ))
80155 .orElseGet (() -> CqlIdentifier .fromCql (toCql ()));
81156 }
@@ -110,6 +185,54 @@ public int hashCode() {
110185 return hashValue ;
111186 }
112187
188+ /**
189+ * {@link PropertyPath}-based column name representation.
190+ *
191+ * @author Mark Paluch
192+ */
193+ static class PropertyPathColumnName extends ColumnName {
194+
195+ private final PropertyPath propertyPath ;
196+
197+ PropertyPathColumnName (PropertyPath propertyPath ) {
198+
199+ Assert .notNull (propertyPath , "Property path must not be null" );
200+
201+ this .propertyPath = propertyPath ;
202+ }
203+
204+ @ Override
205+ public Optional <String > getColumnName () {
206+ return Optional .of (toCql ());
207+ }
208+
209+ @ Override
210+ public PropertyPath getPropertyPath () {
211+ return propertyPath ;
212+ }
213+
214+ @ Override
215+ public boolean equals (@ Nullable Object obj ) {
216+ return super .equals (obj )
217+ && (obj instanceof PropertyPathColumnName that && this .propertyPath .equals (that .propertyPath ));
218+ }
219+
220+ @ Override
221+ public String toCql () {
222+ return this .propertyPath .toDotPath ();
223+ }
224+
225+ @ Override
226+ public String toString () {
227+
228+ if (this .propertyPath .hasNext ()) {
229+ return this .propertyPath .toString ();
230+ }
231+
232+ return this .propertyPath .toDotPath ();
233+ }
234+ }
235+
113236 /**
114237 * {@link String}-based column name representation. Preserves letter casing.
115238 *
@@ -120,6 +243,9 @@ static class StringColumnName extends ColumnName {
120243 private final String columnName ;
121244
122245 StringColumnName (String columnName ) {
246+
247+ Assert .hasText (columnName , "Column name must not be null or empty" );
248+
123249 this .columnName = columnName ;
124250 }
125251
@@ -128,11 +254,6 @@ public Optional<String> getColumnName() {
128254 return Optional .of (columnName );
129255 }
130256
131- @ Override
132- public Optional <CqlIdentifier > getCqlIdentifier () {
133- return Optional .empty ();
134- }
135-
136257 @ Override
137258 public String toCql () {
138259 return this .columnName ;
@@ -154,12 +275,10 @@ static class CqlIdentifierColumnName extends ColumnName {
154275 private final CqlIdentifier cqlIdentifier ;
155276
156277 CqlIdentifierColumnName (CqlIdentifier cqlIdentifier ) {
157- this .cqlIdentifier = cqlIdentifier ;
158- }
159278
160- @ Override
161- public Optional < String > getColumnName () {
162- return Optional . empty () ;
279+ Assert . notNull ( cqlIdentifier , "Column name must not be null" );
280+
281+ this . cqlIdentifier = cqlIdentifier ;
163282 }
164283
165284 @ Override
0 commit comments