@ -34,6 +34,7 @@ import org.jspecify.annotations.Nullable;
@@ -34,6 +34,7 @@ import org.jspecify.annotations.Nullable;
import org.springframework.data.mongodb.core.mapping.Field ;
import org.springframework.data.mongodb.core.query.Collation ;
import org.springframework.data.mongodb.core.schema.IdentifiableJsonSchemaProperty ;
import org.springframework.data.mongodb.core.schema.IdentifiableJsonSchemaProperty.EncryptedJsonSchemaProperty ;
import org.springframework.data.mongodb.core.schema.IdentifiableJsonSchemaProperty.QueryableJsonSchemaProperty ;
import org.springframework.data.mongodb.core.schema.JsonSchemaProperty ;
import org.springframework.data.mongodb.core.schema.MongoJsonSchema ;
@ -681,17 +682,16 @@ public class CollectionOptions {
@@ -681,17 +682,16 @@ public class CollectionOptions {
private static final EncryptedFieldsOptions NONE = new EncryptedFieldsOptions ( ) ;
private final @Nullable MongoJsonSchema schema ;
private final List < Queryable JsonSchemaProperty> queryableP roperties;
private final List < JsonSchemaProperty > p roperties;
EncryptedFieldsOptions ( ) {
this ( null , List . of ( ) ) ;
}
private EncryptedFieldsOptions ( @Nullable MongoJsonSchema schema ,
List < QueryableJsonSchemaProperty > queryableProperties ) {
private EncryptedFieldsOptions ( @Nullable MongoJsonSchema schema , List < JsonSchemaProperty > queryableProperties ) {
this . schema = schema ;
this . queryableP roperties = queryableProperties ;
this . p roperties = queryableProperties ;
}
/ * *
@ -711,7 +711,7 @@ public class CollectionOptions {
@@ -711,7 +711,7 @@ public class CollectionOptions {
/ * *
* @return new instance of { @link EncryptedFieldsOptions } .
* /
public static EncryptedFieldsOptions fromProperties ( List < Queryable JsonSchemaProperty> properties ) {
public static EncryptedFieldsOptions fromProperties ( List < JsonSchemaProperty > properties ) {
return new EncryptedFieldsOptions ( null , List . copyOf ( properties ) ) ;
}
@ -731,13 +731,50 @@ public class CollectionOptions {
@@ -731,13 +731,50 @@ public class CollectionOptions {
@CheckReturnValue
public EncryptedFieldsOptions queryable ( JsonSchemaProperty property , QueryCharacteristic . . . characteristics ) {
List < Queryable JsonSchemaProperty> targetPropertyList = new ArrayList < > ( queryableP roperties. size ( ) + 1 ) ;
targetPropertyList . addAll ( queryableP roperties) ;
List < JsonSchemaProperty > targetPropertyList = new ArrayList < > ( p roperties. size ( ) + 1 ) ;
targetPropertyList . addAll ( p roperties) ;
targetPropertyList . add ( JsonSchemaProperty . queryable ( property , List . of ( characteristics ) ) ) ;
return new EncryptedFieldsOptions ( schema , targetPropertyList ) ;
}
/ * *
* Add an { @link EncryptedJsonSchemaProperty encrypted property } that should not be queryable .
*
* @param property must not be { @literal null } .
* @return new instance of { @link EncryptedFieldsOptions } .
* /
@Contract ( "_ -> new" )
@CheckReturnValue
public EncryptedFieldsOptions with ( EncryptedJsonSchemaProperty property ) {
return encrypted ( property , null ) ;
}
/ * *
* Add a { @link JsonSchemaProperty property } that should not be encrypted but not queryable .
*
* @param property must not be { @literal null } .
* @param key can be { @literal null } .
* @return new instance of { @link EncryptedFieldsOptions } .
* /
@Contract ( "_, _ -> new" )
@CheckReturnValue
public EncryptedFieldsOptions encrypted ( JsonSchemaProperty property , @Nullable Object key ) {
List < JsonSchemaProperty > targetPropertyList = new ArrayList < > ( properties . size ( ) + 1 ) ;
targetPropertyList . addAll ( properties ) ;
if ( property instanceof IdentifiableJsonSchemaProperty . EncryptedJsonSchemaProperty ) {
targetPropertyList . add ( property ) ;
} else {
EncryptedJsonSchemaProperty encryptedJsonSchemaProperty = new EncryptedJsonSchemaProperty ( property ) ;
if ( key ! = null ) {
targetPropertyList . add ( encryptedJsonSchemaProperty . keyId ( key ) ) ;
}
}
return new EncryptedFieldsOptions ( schema , targetPropertyList ) ;
}
public Document toDocument ( ) {
return new Document ( "fields" , selectPaths ( ) ) ;
}
@ -756,12 +793,12 @@ public class CollectionOptions {
@@ -756,12 +793,12 @@ public class CollectionOptions {
private List < Document > fromProperties ( ) {
if ( queryableP roperties. isEmpty ( ) ) {
if ( p roperties. isEmpty ( ) ) {
return List . of ( ) ;
}
List < Document > converted = new ArrayList < > ( queryableP roperties. size ( ) ) ;
for ( Queryable JsonSchemaProperty property : queryableP roperties) {
List < Document > converted = new ArrayList < > ( p roperties. size ( ) ) ;
for ( JsonSchemaProperty property : p roperties) {
Document field = new Document ( "path" , property . getIdentifier ( ) ) ;
@ -769,7 +806,7 @@ public class CollectionOptions {
@@ -769,7 +806,7 @@ public class CollectionOptions {
field . append ( "bsonType" , property . getTypes ( ) . iterator ( ) . next ( ) . toBsonType ( ) . value ( ) ) ;
}
if ( property
if ( property instanceof QueryableJsonSchemaProperty qproperty & & qproperty
. getTargetProperty ( ) instanceof IdentifiableJsonSchemaProperty . EncryptedJsonSchemaProperty encrypted ) {
if ( encrypted . getKeyId ( ) ! = null ) {
if ( encrypted . getKeyId ( ) instanceof String stringKey ) {
@ -779,11 +816,21 @@ public class CollectionOptions {
@@ -779,11 +816,21 @@ public class CollectionOptions {
field . append ( "keyId" , encrypted . getKeyId ( ) ) ;
}
}
} else if ( property instanceof IdentifiableJsonSchemaProperty . EncryptedJsonSchemaProperty encrypted ) {
if ( encrypted . getKeyId ( ) ! = null ) {
if ( encrypted . getKeyId ( ) instanceof String stringKey ) {
field . append ( "keyId" ,
new BsonBinary ( BsonBinarySubType . UUID_STANDARD , stringKey . getBytes ( StandardCharsets . UTF_8 ) ) ) ;
} else {
field . append ( "keyId" , encrypted . getKeyId ( ) ) ;
}
}
}
field . append ( "queries" , StreamSupport . stream ( property . getCharacteristics ( ) . spliterator ( ) , false )
. map ( QueryCharacteristic : : toDocument ) . toList ( ) ) ;
if ( property instanceof QueryableJsonSchemaProperty qproperty ) {
field . append ( "queries" , StreamSupport . stream ( qproperty . getCharacteristics ( ) . spliterator ( ) , false )
. map ( QueryCharacteristic : : toDocument ) . toList ( ) ) ;
}
if ( ! field . containsKey ( "keyId" ) ) {
field . append ( "keyId" , BsonNull . VALUE ) ;
}
@ -812,7 +859,9 @@ public class CollectionOptions {
@@ -812,7 +859,9 @@ public class CollectionOptions {
if ( entry . getValue ( ) . containsKey ( "bsonType" ) ) {
field . append ( "bsonType" , entry . getValue ( ) . get ( "bsonType" ) ) ;
}
field . put ( "queries" , entry . getValue ( ) . get ( "queries" ) ) ;
if ( entry . getValue ( ) . containsKey ( "queries" ) ) {
field . put ( "queries" , entry . getValue ( ) . get ( "queries" ) ) ;
}
fields . add ( field ) ;
}
}