24
24
import java .util .Map .Entry ;
25
25
import java .util .Optional ;
26
26
import java .util .function .Function ;
27
- import java .util .stream .StreamSupport ;
28
27
29
28
import org .bson .BsonBinary ;
30
29
import org .bson .BsonBinarySubType ;
31
30
import org .bson .BsonNull ;
32
31
import org .bson .Document ;
32
+
33
33
import org .springframework .data .mongodb .core .mapping .Field ;
34
34
import org .springframework .data .mongodb .core .query .Collation ;
35
35
import org .springframework .data .mongodb .core .schema .IdentifiableJsonSchemaProperty ;
@@ -391,6 +391,7 @@ public CollectionOptions changeStream(CollectionChangeStreamOptions changeStream
391
391
*
392
392
* @param encryptedFieldsOptions must not be {@literal null}.
393
393
* @return new instance of {@link CollectionOptions}.
394
+ * @since 4.5
394
395
*/
395
396
@ Contract ("_ -> new" )
396
397
@ CheckReturnValue
@@ -708,7 +709,7 @@ public static EncryptedFieldsOptions fromSchema(MongoJsonSchema schema) {
708
709
/**
709
710
* @return new instance of {@link EncryptedFieldsOptions}.
710
711
*/
711
- public static EncryptedFieldsOptions fromProperties (List <JsonSchemaProperty > properties ) {
712
+ public static EncryptedFieldsOptions fromProperties (List <? extends JsonSchemaProperty > properties ) {
712
713
return new EncryptedFieldsOptions (null , List .copyOf (properties ));
713
714
}
714
715
@@ -740,6 +741,7 @@ public EncryptedFieldsOptions queryable(JsonSchemaProperty property, QueryCharac
740
741
*
741
742
* @param property must not be {@literal null}.
742
743
* @return new instance of {@link EncryptedFieldsOptions}.
744
+ * @since 4.5.1
743
745
*/
744
746
@ Contract ("_ -> new" )
745
747
@ CheckReturnValue
@@ -748,24 +750,26 @@ public EncryptedFieldsOptions with(EncryptedJsonSchemaProperty property) {
748
750
}
749
751
750
752
/**
751
- * Add a {@link JsonSchemaProperty property} that should not be encrypted but not queryable.
753
+ * Add a {@link JsonSchemaProperty property} that should be encrypted but not queryable.
752
754
*
753
755
* @param property must not be {@literal null}.
754
- * @param key can be {@literal null}.
756
+ * @param keyId the key identifier to be used, can be {@literal null}.
755
757
* @return new instance of {@link EncryptedFieldsOptions}.
758
+ * @since 4.5.1
756
759
*/
757
760
@ Contract ("_, _ -> new" )
758
761
@ CheckReturnValue
759
- public EncryptedFieldsOptions encrypted (JsonSchemaProperty property , @ Nullable Object key ) {
762
+ public EncryptedFieldsOptions encrypted (JsonSchemaProperty property , @ Nullable Object keyId ) {
760
763
761
764
List <JsonSchemaProperty > targetPropertyList = new ArrayList <>(properties .size () + 1 );
762
765
targetPropertyList .addAll (properties );
766
+
763
767
if (property instanceof IdentifiableJsonSchemaProperty .EncryptedJsonSchemaProperty ) {
764
768
targetPropertyList .add (property );
765
769
} else {
766
770
EncryptedJsonSchemaProperty encryptedJsonSchemaProperty = new EncryptedJsonSchemaProperty (property );
767
- if (key != null ) {
768
- targetPropertyList .add (encryptedJsonSchemaProperty .keyId (key ));
771
+ if (keyId != null ) {
772
+ targetPropertyList .add (encryptedJsonSchemaProperty .keyId (keyId ));
769
773
}
770
774
}
771
775
@@ -796,45 +800,48 @@ private List<Document> fromProperties() {
796
800
797
801
List <Document > converted = new ArrayList <>(properties .size ());
798
802
for (JsonSchemaProperty property : properties ) {
803
+ converted .add (getEncryptedField (property ));
804
+ }
805
+ return converted ;
806
+ }
799
807
800
- Document field = new Document ( "path" , property . getIdentifier ());
808
+ private Document getEncryptedField ( JsonSchemaProperty property ) {
801
809
802
- if (!property .getTypes ().isEmpty ()) {
803
- field .append ("bsonType" , property .getTypes ().iterator ().next ().toBsonType ().value ());
804
- }
810
+ Document field = new Document ("path" , property .getIdentifier ());
805
811
806
- if (property instanceof QueryableJsonSchemaProperty qproperty && qproperty
807
- .getTargetProperty () instanceof IdentifiableJsonSchemaProperty .EncryptedJsonSchemaProperty encrypted ) {
808
- if (encrypted .getKeyId () != null ) {
809
- if (encrypted .getKeyId () instanceof String stringKey ) {
810
- field .append ("keyId" ,
811
- new BsonBinary (BsonBinarySubType .UUID_STANDARD , stringKey .getBytes (StandardCharsets .UTF_8 )));
812
- } else {
813
- field .append ("keyId" , encrypted .getKeyId ());
814
- }
815
- }
816
- } else if (property instanceof IdentifiableJsonSchemaProperty .EncryptedJsonSchemaProperty encrypted ) {
817
- if (encrypted .getKeyId () != null ) {
818
- if (encrypted .getKeyId () instanceof String stringKey ) {
819
- field .append ("keyId" ,
820
- new BsonBinary (BsonBinarySubType .UUID_STANDARD , stringKey .getBytes (StandardCharsets .UTF_8 )));
821
- } else {
822
- field .append ("keyId" , encrypted .getKeyId ());
823
- }
824
- }
825
- }
812
+ if (!property .getTypes ().isEmpty ()) {
813
+ field .append ("bsonType" , property .getTypes ().iterator ().next ().toBsonType ().value ());
814
+ }
815
+
816
+ if (property instanceof QueryableJsonSchemaProperty qp
817
+ && qp .getTargetProperty () instanceof IdentifiableJsonSchemaProperty .EncryptedJsonSchemaProperty encrypted
818
+ && encrypted .getKeyId () != null ) {
826
819
827
- if (property instanceof QueryableJsonSchemaProperty qproperty ) {
828
- field .append ("queries" , StreamSupport .stream (qproperty .getCharacteristics ().spliterator (), false )
829
- .map (QueryCharacteristic ::toDocument ).toList ());
820
+ if (encrypted .getKeyId () instanceof String stringKey ) {
821
+ field .append ("keyId" ,
822
+ new BsonBinary (BsonBinarySubType .UUID_STANDARD , stringKey .getBytes (StandardCharsets .UTF_8 )));
823
+ } else {
824
+ field .append ("keyId" , encrypted .getKeyId ());
830
825
}
831
- if (!field .containsKey ("keyId" )) {
832
- field .append ("keyId" , BsonNull .VALUE );
826
+ } else if (property instanceof IdentifiableJsonSchemaProperty .EncryptedJsonSchemaProperty encrypted
827
+ && encrypted .getKeyId () != null ) {
828
+ if (encrypted .getKeyId () instanceof String stringKey ) {
829
+ field .append ("keyId" ,
830
+ new BsonBinary (BsonBinarySubType .UUID_STANDARD , stringKey .getBytes (StandardCharsets .UTF_8 )));
831
+ } else {
832
+ field .append ("keyId" , encrypted .getKeyId ());
833
833
}
834
+ }
834
835
835
- converted .add (field );
836
+ if (property instanceof QueryableJsonSchemaProperty qp ) {
837
+ field .append ("queries" , qp .getCharacteristics ().map (QueryCharacteristic ::toDocument ).toList ());
836
838
}
837
- return converted ;
839
+
840
+ if (!field .containsKey ("keyId" )) {
841
+ field .append ("keyId" , BsonNull .VALUE );
842
+ }
843
+
844
+ return field ;
838
845
}
839
846
840
847
private List <Document > fromSchema () {
@@ -848,19 +855,25 @@ private List<Document> fromSchema() {
848
855
collectPaths (root , null , paths );
849
856
850
857
List <Document > fields = new ArrayList <>();
851
- if (!paths .isEmpty ()) {
858
+ if (paths .isEmpty ()) {
859
+ return fields ;
860
+ }
852
861
853
- for (Entry <String , Document > entry : paths .entrySet ()) {
854
- Document field = new Document ("path" , entry .getKey ());
855
- field .append ("keyId" , entry .getValue ().getOrDefault ("keyId" , BsonNull .VALUE ));
856
- if (entry .getValue ().containsKey ("bsonType" )) {
857
- field .append ("bsonType" , entry .getValue ().get ("bsonType" ));
858
- }
859
- if (entry .getValue ().containsKey ("queries" )) {
860
- field .put ("queries" , entry .getValue ().get ("queries" ));
861
- }
862
- fields .add (field );
862
+ for (Entry <String , Document > entry : paths .entrySet ()) {
863
+
864
+ Document field = new Document ("path" , entry .getKey ());
865
+
866
+ field .append ("keyId" , entry .getValue ().getOrDefault ("keyId" , BsonNull .VALUE ));
867
+
868
+ if (entry .getValue ().containsKey ("bsonType" )) {
869
+ field .append ("bsonType" , entry .getValue ().get ("bsonType" ));
870
+ }
871
+
872
+ if (entry .getValue ().containsKey ("queries" )) {
873
+ field .put ("queries" , entry .getValue ().get ("queries" ));
863
874
}
875
+
876
+ fields .add (field );
864
877
}
865
878
866
879
return fields ;
@@ -870,28 +883,29 @@ private List<Document> fromSchema() {
870
883
private static void collectPaths (Document document , @ Nullable String currentPath , Map <String , Document > paths ) {
871
884
872
885
if (document .containsKey ("type" ) && document .get ("type" ).equals ("object" )) {
886
+
873
887
Object o = document .get ("properties" );
874
- if (o == null ) {
888
+
889
+ if (!(o instanceof Document properties )) {
875
890
return ;
876
891
}
877
892
878
- if (o instanceof Document properties ) {
879
- for (Entry <String , Object > entry : properties .entrySet ()) {
880
- if (entry .getValue () instanceof Document nested ) {
881
-
882
- String path = currentPath == null ? entry .getKey () : (currentPath + "." + entry .getKey ());
883
- if (nested .containsKey ("encrypt" )) {
884
- Document target = new Document (nested .get ("encrypt" , Document .class ));
885
- if (nested .containsKey ("queries" )) {
886
- List <?> queries = nested .get ("queries" , List .class );
887
- if (!queries .isEmpty () && queries .iterator ().next () instanceof Document qd ) {
888
- target .putAll (qd );
889
- }
893
+ for (Entry <String , Object > entry : properties .entrySet ()) {
894
+
895
+ if (entry .getValue () instanceof Document nested ) {
896
+
897
+ String path = currentPath == null ? entry .getKey () : (currentPath + "." + entry .getKey ());
898
+ if (nested .containsKey ("encrypt" )) {
899
+ Document target = new Document (nested .get ("encrypt" , Document .class ));
900
+ if (nested .containsKey ("queries" )) {
901
+ List <?> queries = nested .get ("queries" , List .class );
902
+ if (!queries .isEmpty () && queries .iterator ().next () instanceof Document qd ) {
903
+ target .putAll (qd );
890
904
}
891
- paths .put (path , target );
892
- } else {
893
- collectPaths (nested , path , paths );
894
905
}
906
+ paths .put (path , target );
907
+ } else {
908
+ collectPaths (nested , path , paths );
895
909
}
896
910
}
897
911
}
0 commit comments