Skip to content

Commit eedad43

Browse files
committed
Merge branch 'main' of github.com:spring-projects/spring-data-couchbase into datacouch_763_fle_implementation_with_property_value_converter
2 parents dea9b86 + b7d1654 commit eedad43

20 files changed

+275
-339
lines changed

README.adoc

-7
Original file line numberDiff line numberDiff line change
@@ -200,13 +200,6 @@ The generated documentation is available from `target/site/reference/html/index.
200200
popd
201201
----
202202

203-
=== Intellij Issue with Importing pom.xml
204-
205-
There is an issue in Intellij that prevents it from importing modules when one of the module
206-
directories has the same name as the project directory. The work-around is to create a new module (any name, any type will suffice).
207-
When Intellij creates the new module, it will also recognize the existing modules. Once the new module is
208-
created, it can be deleted and Intellij will now recognize the existing modules.
209-
210203
The generated documentation is available from `target/site/reference/html/index.html`.
211204

212205
== Examples

spring-data-couchbase/pom.xml

+10-1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333
<com.couchbase.mock>1.5.25</com.couchbase.mock>
3434
<com.squareup.okhttp3>4.8.1</com.squareup.okhttp3>
3535
<org.awaitility>4.0.3</org.awaitility>
36+
<jackson-joda>2.13.4</jackson-joda>
37+
<couchbase.encryption>3.1.0</couchbase.encryption>
3638
</properties>
3739

3840
<dependencyManagement>
@@ -116,6 +118,13 @@
116118
<optional>true</optional>
117119
</dependency>
118120

121+
<dependency>
122+
<groupId>com.fasterxml.jackson.datatype</groupId>
123+
<artifactId>jackson-datatype-joda</artifactId>
124+
<version>${jackson-joda}</version>
125+
<scope>test</scope>
126+
</dependency>
127+
119128
<dependency>
120129
<groupId>org.testcontainers</groupId>
121130
<artifactId>testcontainers</artifactId>
@@ -221,7 +230,7 @@
221230
<dependency>
222231
<groupId>com.couchbase.client</groupId>
223232
<artifactId>couchbase-encryption</artifactId>
224-
<version>3.1.0</version>
233+
<version>${couchbase.encryption}</version>
225234
<scope>test</scope>
226235
</dependency>
227236

spring-data-couchbase/src/main/java/org/springframework/data/couchbase/config/AbstractCouchbaseConfiguration.java

+12-18
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
import java.util.ArrayList;
2222
import java.util.HashSet;
2323
import java.util.List;
24-
import java.util.Map;
2524
import java.util.Set;
2625

2726
import org.springframework.beans.factory.config.BeanDefinition;
@@ -32,7 +31,6 @@
3231
import org.springframework.core.convert.converter.GenericConverter;
3332
import org.springframework.core.type.filter.AnnotationTypeFilter;
3433
import org.springframework.data.convert.CustomConversions;
35-
import org.springframework.data.convert.PropertyValueConverterFactory;
3634
import org.springframework.data.convert.PropertyValueConverterRegistrar;
3735
import org.springframework.data.convert.SimplePropertyValueConversions;
3836
import org.springframework.data.couchbase.CouchbaseClientFactory;
@@ -43,10 +41,8 @@
4341
import org.springframework.data.couchbase.core.convert.CouchbasePropertyValueConverterFactory;
4442
import org.springframework.data.couchbase.core.convert.CryptoConverter;
4543
import org.springframework.data.couchbase.core.convert.MappingCouchbaseConverter;
46-
import org.springframework.data.couchbase.core.convert.OtherConverters;
4744
import org.springframework.data.couchbase.core.convert.translation.JacksonTranslationService;
4845
import org.springframework.data.couchbase.core.convert.translation.TranslationService;
49-
import org.springframework.data.couchbase.core.mapping.CouchbaseDocument;
5046
import org.springframework.data.couchbase.core.mapping.CouchbaseMappingContext;
5147
import org.springframework.data.couchbase.core.mapping.Document;
5248
import org.springframework.data.couchbase.repository.config.ReactiveRepositoryOperationsMapping;
@@ -319,8 +315,7 @@ public CouchbaseMappingContext couchbaseMappingContext(CustomConversions customC
319315
*
320316
* @return ObjectMapper
321317
*/
322-
323-
public ObjectMapper couchbaseObjectMapper() {
318+
private ObjectMapper couchbaseObjectMapper() {
324319
return couchbaseObjectMapper(cryptoManager());
325320
}
326321

@@ -337,7 +332,7 @@ public ObjectMapper couchbaseObjectMapper(CryptoManager cryptoManager) {
337332
if (mapper != null) {
338333
return mapper;
339334
}
340-
mapper = new ObjectMapper(); // or use the one from the Java SDK (?) JacksonTransformers.MAPPER
335+
mapper = new ObjectMapper(); // or use the one from the Java SDK (?) JacksonTransformers.MAPPER
341336
mapper.configure(com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
342337
mapper.registerModule(new JsonValueModule());
343338
if (cryptoManager != null) {
@@ -424,19 +419,13 @@ public CustomConversions customConversions() {
424419
*/
425420
public CustomConversions customConversions(CryptoManager cryptoManager) {
426421
List<GenericConverter> newConverters = new ArrayList();
427-
// the cryptoConverters take an argument, so they cannot be created in the
428-
// static block of CouchbaseCustomConversions. And they must be set before the super() constructor
429-
// in CouchbaseCustomConversions
430-
CustomConversions customConversions = CouchbaseCustomConversions.create( configurationAdapter -> {
431-
SimplePropertyValueConversions valueConversions = new SimplePropertyValueConversions();
432-
valueConversions.setConverterFactory(new CouchbasePropertyValueConverterFactory(cryptoManager));
433-
valueConversions.setValueConverterRegistry(new PropertyValueConverterRegistrar()
434-
.registerConverter(CouchbaseDocument.class, "", new CryptoConverter(cryptoManager))// unnecessary?
435-
.buildRegistry());
422+
CustomConversions customConversions = CouchbaseCustomConversions.create(configurationAdapter -> {
423+
SimplePropertyValueConversions valueConversions = new SimplePropertyValueConversions();
424+
valueConversions.setConverterFactory(new CouchbasePropertyValueConverterFactory(cryptoManager));
425+
valueConversions.setValueConverterRegistry(new PropertyValueConverterRegistrar().buildRegistry());
436426
configurationAdapter.setPropertyValueConversions(valueConversions);
437427
configurationAdapter.registerConverters(newConverters);
438-
});
439-
428+
});
440429
return customConversions;
441430
}
442431

@@ -445,6 +434,11 @@ protected CryptoManager cryptoManager() {
445434
return null;
446435
}
447436

437+
@Bean
438+
protected CryptoConverter cryptoConverter(CryptoManager cryptoManager) {
439+
return cryptoManager == null ? null : new CryptoConverter(cryptoManager);
440+
}
441+
448442
/**
449443
* Return the base package to scan for mapped {@link Document}s. Will return the package name of the configuration
450444
* class (the concrete class, not this one here) by default.

spring-data-couchbase/src/main/java/org/springframework/data/couchbase/core/convert/AbstractCouchbaseConverter.java

+9-71
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
package org.springframework.data.couchbase.core.convert;
1818

1919
import java.util.Collections;
20-
import java.util.Map;
2120

2221
import org.springframework.beans.factory.InitializingBean;
2322
import org.springframework.core.convert.ConversionService;
@@ -107,64 +106,22 @@ public void afterPropertiesSet() {
107106
* @return
108107
*/
109108
@Override
110-
public Object convertForWriteIfNeeded(CouchbasePersistentProperty prop, ConvertingPropertyAccessor<Object> accessor) {
109+
public Object convertForWriteIfNeeded(CouchbasePersistentProperty prop, ConvertingPropertyAccessor<Object> accessor,
110+
boolean processValueConverter) {
111111
Object value = accessor.getProperty(prop, prop.getType());
112112
if (value == null) {
113113
return null;
114114
}
115-
if (conversions.hasValueConverter(prop)) {
115+
if (processValueConverter && conversions.hasValueConverter(prop)) {
116116
CouchbaseDocument encrypted = (CouchbaseDocument) conversions.getPropertyValueConversions()
117-
.getValueConverter(prop).write(value, new CouchbaseConversionContext(prop, (MappingCouchbaseConverter)this, accessor));
117+
.getValueConverter(prop)
118+
.write(value, new CouchbaseConversionContext(prop, (MappingCouchbaseConverter) this, accessor));
118119
return encrypted;
119120
}
120-
Class<?> targetClass = Object.class;
121+
Class<?> targetClass = this.conversions.getCustomWriteTarget(value.getClass()).orElse(null);
121122

122-
if (prop.findAnnotation(com.couchbase.client.java.encryption.annotation.Encrypted.class) != null) {
123-
targetClass = Map.class;
124-
}
125-
boolean canConvert = this.conversionService.canConvert(new TypeDescriptor(prop.getField()),
126-
TypeDescriptor.valueOf(targetClass));
127-
if (canConvert) {
128-
return this.conversionService.convert(value, new TypeDescriptor(prop.getField()),
129-
TypeDescriptor.valueOf(targetClass));
130-
}
131-
132-
Object result = this.conversions.getCustomWriteTarget(prop.getType()) //
133-
.map(it -> this.conversionService.convert(value, new TypeDescriptor(prop.getField()),
134-
TypeDescriptor.valueOf(it))) //
135-
.orElseGet(() -> Enum.class.isAssignableFrom(value.getClass()) ? ((Enum<?>) value).name() : value);
136-
137-
return result;
138-
139-
}
140-
141-
/**
142-
* This convertForWriteIfNeeded takes a property and accessor so that the annotations can be accessed (ie. @Encrypted)
143-
*
144-
* @param prop the property to be converted to the class that would actually be stored.
145-
* @param accessor the property accessor
146-
* @return
147-
*/
148-
//@Override
149-
public Object convertForWriteIfNeeded2(CouchbasePersistentProperty prop, ConvertingPropertyAccessor<Object> accessor) {
150-
Object value = accessor.getProperty(prop, prop.getType());
151-
if (value == null) {
152-
return null;
153-
}
154-
/*
155-
if (conversions.hasValueConverter(prop)) {
156-
CouchbaseDocument encrypted = (CouchbaseDocument) conversions.getPropertyValueConversions()
157-
.getValueConverter(prop).write(value, new CouchbaseConversionContext(prop, (MappingCouchbaseConverter)this, accessor));
158-
return encrypted;
159-
}
160-
*/
161-
Class<?> targetClass = Object.class;
162-
163-
if (prop.findAnnotation(com.couchbase.client.java.encryption.annotation.Encrypted.class) != null) {
164-
targetClass = Map.class;
165-
}
166-
boolean canConvert = this.conversionService.canConvert(new TypeDescriptor(prop.getField()),
167-
TypeDescriptor.valueOf(targetClass));
123+
boolean canConvert = targetClass == null ? false
124+
: this.conversionService.canConvert(new TypeDescriptor(prop.getField()), TypeDescriptor.valueOf(targetClass));
168125
if (canConvert) {
169126
return this.conversionService.convert(value, new TypeDescriptor(prop.getField()),
170127
TypeDescriptor.valueOf(targetClass));
@@ -198,32 +155,13 @@ public Object convertForWriteIfNeeded(Object value) {
198155

199156
}
200157

201-
/* TODO needed later
202-
@Override
203-
public Object convertToCouchbaseType(Object value, TypeInformation<?> typeInformation) {
204-
if (value == null) {
205-
return null;
206-
}
207-
208-
return this.conversions.getCustomWriteTarget(value.getClass()) //
209-
.map(it -> (Object) this.conversionService.convert(value, it)) //
210-
.orElseGet(() -> Enum.class.isAssignableFrom(value.getClass()) ? ((Enum<?>) value).name() : value);
211-
212-
}
213-
214-
@Override
215-
public Object convertToCouchbaseType(String source) {
216-
return source;
217-
}
218-
*/
219-
220158
@Override
221159
public Class<?> getWriteClassFor(Class<?> clazz) {
222160
return this.conversions.getCustomWriteTarget(clazz).orElse(clazz);
223161
}
224162

225163
@Override
226-
public CustomConversions getConversions(){
164+
public CustomConversions getConversions() {
227165
return conversions;
228166
}
229167
}

spring-data-couchbase/src/main/java/org/springframework/data/couchbase/core/convert/CouchbaseConversionContext.java

+20-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,20 @@
1+
/*
2+
* Copyright 2022 the original author or authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
116
package org.springframework.data.couchbase.core.convert;
217

3-
import org.springframework.beans.PropertyAccessor;
418
import org.springframework.data.convert.ValueConversionContext;
519
import org.springframework.data.couchbase.core.mapping.CouchbasePersistentProperty;
620
import org.springframework.data.mapping.model.ConvertingPropertyAccessor;
@@ -10,8 +24,8 @@
1024
/**
1125
* {@link ValueConversionContext} that allows to delegate read/write to an underlying {@link CouchbaseConverter}.
1226
*
13-
* @author Christoph Strobl
14-
* @since 3.4
27+
* @author Michael Reiche
28+
* @since 5.0
1529
*/
1630
public class CouchbaseConversionContext implements ValueConversionContext<CouchbasePersistentProperty> {
1731

@@ -20,7 +34,7 @@ public class CouchbaseConversionContext implements ValueConversionContext<Couchb
2034
private final ConvertingPropertyAccessor propertyAccessor;
2135

2236
public CouchbaseConversionContext(CouchbasePersistentProperty persistentProperty,
23-
MappingCouchbaseConverter couchbaseConverter, ConvertingPropertyAccessor accessor) {
37+
MappingCouchbaseConverter couchbaseConverter, ConvertingPropertyAccessor accessor) {
2438

2539
this.persistentProperty = persistentProperty;
2640
this.couchbaseConverter = couchbaseConverter;
@@ -42,11 +56,11 @@ public <T> T read(@Nullable Object value, TypeInformation<T> target) {
4256
return ValueConversionContext.super.read(value, target);
4357
}
4458

45-
public MappingCouchbaseConverter getConverter(){
59+
public MappingCouchbaseConverter getConverter() {
4660
return couchbaseConverter;
4761
}
4862

49-
public ConvertingPropertyAccessor getAccessor(){
63+
public ConvertingPropertyAccessor getAccessor() {
5064
return propertyAccessor;
5165
}
5266
}

spring-data-couchbase/src/main/java/org/springframework/data/couchbase/core/convert/CouchbaseConverter.java

+2-7
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ public interface CouchbaseConverter
5555
* @return the converted value (or the same value if no conversion necessary).
5656
*/
5757
Object convertForWriteIfNeeded(final CouchbasePersistentProperty source,
58-
final ConvertingPropertyAccessor<Object> accessor);
58+
final ConvertingPropertyAccessor<Object> accessor, boolean processValueConverter);
5959

6060
/**
6161
* Return the Class that would actually be stored for a given Class.
@@ -76,14 +76,9 @@ Object convertForWriteIfNeeded(final CouchbasePersistentProperty source,
7676
*/
7777
Alias getTypeAlias(TypeInformation<?> info);
7878

79-
// TODO needed later
80-
// CouchbaseTypeMapper getMapper();
81-
// Object convertToCouchbaseType(Object source, TypeInformation<?> typeInformation);
82-
//
83-
// Object convertToCouchbaseType(String source);
84-
8579
/**
8680
* return the conversions
81+
*
8782
* @return conversions
8883
*/
8984
CustomConversions getConversions();

0 commit comments

Comments
 (0)