21 changed files with 885 additions and 238 deletions
@ -0,0 +1,34 @@
@@ -0,0 +1,34 @@
|
||||
/* |
||||
* Copyright 2020. the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
package org.springframework.data.mapping; |
||||
|
||||
import org.springframework.lang.Nullable; |
||||
|
||||
/** |
||||
* @author Christoph Strobl |
||||
* @since 2020/10 |
||||
*/ |
||||
public interface PreferredConstructorProvider<T> { |
||||
|
||||
@Nullable |
||||
<P extends PersistentProperty<P>> PreferredConstructor<T, P> getPreferredConstructor(); |
||||
|
||||
default <P extends PersistentProperty<P>> PreferredConstructor<T, P> getPreferredConstructorOrDefault(PreferredConstructor<T, P> fallback) { |
||||
|
||||
PreferredConstructor<T, P> preferredConstructor = getPreferredConstructor(); |
||||
return preferredConstructor != null ? preferredConstructor : fallback; |
||||
} |
||||
} |
||||
@ -0,0 +1,54 @@
@@ -0,0 +1,54 @@
|
||||
/* |
||||
* Copyright 2020. the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
/* |
||||
* Copyright 2020 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
package org.springframework.data.mapping.model; |
||||
|
||||
import java.util.function.BiFunction; |
||||
import java.util.function.Function; |
||||
|
||||
/** |
||||
* @author Christoph Strobl |
||||
* @since 2020/10 |
||||
*/ |
||||
public interface AccessorFunctionProvider<S> { |
||||
|
||||
default boolean hasSetFunctionFor(String fieldName) { |
||||
return getSetFunctionFor(fieldName) != null; |
||||
} |
||||
|
||||
default boolean hasGetFunctionFor(String fieldName) { |
||||
return getGetFunctionFor(fieldName) != null; |
||||
} |
||||
|
||||
BiFunction<S, Object, S> getSetFunctionFor(String fieldName); |
||||
|
||||
Function<S, Object> getGetFunctionFor(String fieldName); |
||||
} |
||||
@ -0,0 +1,50 @@
@@ -0,0 +1,50 @@
|
||||
/* |
||||
* Copyright 2020. the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
/* |
||||
* Copyright 2020 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
package org.springframework.data.mapping.model; |
||||
|
||||
import org.springframework.lang.Nullable; |
||||
|
||||
/** |
||||
* @author Christoph Strobl |
||||
* @since 2020/10 |
||||
*/ |
||||
public interface EntiyInstantiatorProvider { |
||||
|
||||
@Nullable |
||||
EntityInstantiator getEntityInstantiator(); |
||||
|
||||
default EntityInstantiator getEntiyInstantiatorOrDefault(EntityInstantiator fallback) { |
||||
|
||||
EntityInstantiator entityInstantiator = getEntityInstantiator(); |
||||
return entityInstantiator != null ? entityInstantiator : fallback; |
||||
} |
||||
} |
||||
@ -0,0 +1,35 @@
@@ -0,0 +1,35 @@
|
||||
/* |
||||
* Copyright 2020. the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
package org.springframework.data.mapping.model; |
||||
|
||||
import org.springframework.lang.Nullable; |
||||
|
||||
/** |
||||
* @author Christoph Strobl |
||||
* @since 2020/10 |
||||
*/ |
||||
public interface PersistentPropertyAccessorFactoryProvider { |
||||
|
||||
@Nullable |
||||
PersistentPropertyAccessorFactory getPersistentPropertyAccessorFactory(); |
||||
|
||||
default PersistentPropertyAccessorFactory getPersistentPropertyAccessorFactoryOrDefault( |
||||
PersistentPropertyAccessorFactory fallback) { |
||||
|
||||
PersistentPropertyAccessorFactory factory = getPersistentPropertyAccessorFactory(); |
||||
return factory != null ? factory : fallback; |
||||
} |
||||
} |
||||
@ -0,0 +1,32 @@
@@ -0,0 +1,32 @@
|
||||
/* |
||||
* Copyright 2020. the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
package org.springframework.data.util; |
||||
|
||||
import java.lang.annotation.Annotation; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* @author Christoph Strobl |
||||
* @since 2020/10 |
||||
*/ |
||||
public interface AnnotationProvider { |
||||
|
||||
List<Annotation> getAnnotations(); |
||||
|
||||
boolean hasAnnotation(Class<?> annotationType); |
||||
|
||||
<T extends Annotation> List<T> findAnnotation(Class<T> annotation); |
||||
} |
||||
@ -0,0 +1,179 @@
@@ -0,0 +1,179 @@
|
||||
/* |
||||
* Copyright 2020. the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
/* |
||||
* Copyright 2020 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
package org.springframework.data.util; |
||||
|
||||
import java.lang.annotation.Annotation; |
||||
import java.util.ArrayList; |
||||
import java.util.Collections; |
||||
import java.util.List; |
||||
import java.util.function.BiConsumer; |
||||
import java.util.function.BiFunction; |
||||
import java.util.function.Function; |
||||
|
||||
import org.springframework.lang.Nullable; |
||||
import org.springframework.util.LinkedMultiValueMap; |
||||
import org.springframework.util.MultiValueMap; |
||||
|
||||
/** |
||||
* @author Christoph Strobl |
||||
* @since 2020/10 |
||||
*/ |
||||
public class Field<T, O> implements AnnotationProvider { |
||||
|
||||
@Nullable Class<O> owner; |
||||
String propertyName; |
||||
|
||||
TypeInformation<T> typeInformation; |
||||
@Nullable TypeInformation<?> componentType; |
||||
@Nullable TypeInformation<?> keyType; |
||||
|
||||
MultiValueMap<Class<? extends Annotation>, Annotation> annotations; |
||||
|
||||
@Nullable Function<O, T> getterFunction; |
||||
@Nullable BiFunction<O, T, O> setterFunction; |
||||
|
||||
public Field(String propertyName, TypeInformation<T> propertyTypeInformation) { |
||||
|
||||
this.propertyName = propertyName; |
||||
this.typeInformation = propertyTypeInformation; |
||||
this.annotations = new LinkedMultiValueMap<>(); |
||||
} |
||||
|
||||
public static <T, O> Field<T, O> simple(Class<T> type, String propertyName) { |
||||
|
||||
if (type == String.class) { |
||||
return (Field<T, O>) string(propertyName); |
||||
} |
||||
|
||||
throw new IllegalArgumentException("Unknown simple type: " + type); |
||||
} |
||||
|
||||
public static <S> Field<String, S> string(String propertyName) { |
||||
return new Field<>(propertyName, StringTypeInformation.instance()); |
||||
} |
||||
|
||||
public static <S> Field<Long, S> int64(String propertyName) { |
||||
return new Field<>(propertyName, StaticTypeInformation.from(Long.class)); |
||||
} |
||||
|
||||
public static <S> Field<Integer, S> int32(String propertyName) { |
||||
return new Field<>(propertyName, StaticTypeInformation.from(Integer.class)); |
||||
} |
||||
|
||||
public static <S, T> Field<T, S> type(String propertyName, TypeInformation<T> type) { |
||||
return new Field<>(propertyName, type); |
||||
} |
||||
|
||||
public Field<T, O> annotation(Annotation annotation) { |
||||
|
||||
annotations.add(annotation.annotationType(), annotation); |
||||
return this; |
||||
} |
||||
|
||||
public Field<T, O> wither(BiFunction<O, T, O> setterFunction) { |
||||
|
||||
this.setterFunction = setterFunction; |
||||
return this; |
||||
} |
||||
|
||||
public Field<T, O> setter(BiConsumer<O, T> setterFunction) { |
||||
|
||||
return wither((o, t) -> { |
||||
|
||||
setterFunction.accept(o, t); |
||||
return o; |
||||
}); |
||||
} |
||||
|
||||
public Field<T, O> getter(Function<O, T> getterFunction) { |
||||
|
||||
this.getterFunction = getterFunction; |
||||
return this; |
||||
} |
||||
|
||||
public Field<T, O> valueType(TypeInformation<?> valueTypeInformation) { |
||||
this.componentType = valueTypeInformation; |
||||
return this; |
||||
} |
||||
|
||||
Field<T, O> owner(Class<O> owner) { |
||||
|
||||
this.owner = owner; |
||||
return this; |
||||
} |
||||
|
||||
public TypeInformation<?> getValueType() { |
||||
return componentType != null ? componentType : typeInformation; |
||||
} |
||||
|
||||
public String getFieldName() { |
||||
return propertyName; |
||||
} |
||||
|
||||
public TypeInformation<T> getTypeInformation() { |
||||
return typeInformation; |
||||
} |
||||
|
||||
public boolean hasSetter() { |
||||
return setterFunction != null; |
||||
} |
||||
|
||||
public boolean hasGetter() { |
||||
return getterFunction != null; |
||||
} |
||||
|
||||
public BiFunction<O, T, O> getSetter() { |
||||
return setterFunction; |
||||
} |
||||
|
||||
@Nullable |
||||
public Function<O, T> getGetter() { |
||||
return getterFunction; |
||||
} |
||||
|
||||
@Override |
||||
public List<Annotation> getAnnotations() { |
||||
List<Annotation> all = new ArrayList<>(); |
||||
annotations.values().forEach(all::addAll); |
||||
return all; |
||||
} |
||||
|
||||
@Override |
||||
public boolean hasAnnotation(Class<?> annotationType) { |
||||
return annotations.containsKey(annotationType); |
||||
} |
||||
|
||||
@Override |
||||
public <T extends Annotation> List<T> findAnnotation(Class<T> annotation) { |
||||
return (List<T>) annotations.getOrDefault(annotation, Collections.emptyList()); |
||||
} |
||||
} |
||||
@ -0,0 +1,76 @@
@@ -0,0 +1,76 @@
|
||||
/* |
||||
* Copyright 2020. the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
/* |
||||
* Copyright 2020 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
package org.springframework.data.util; |
||||
|
||||
import java.util.Iterator; |
||||
import java.util.LinkedHashMap; |
||||
import java.util.Map; |
||||
import java.util.function.BiConsumer; |
||||
|
||||
/** |
||||
* @author Christoph Strobl |
||||
* @since 2020/10 |
||||
*/ |
||||
public class Fields<O> implements Iterable<Field<?, O>> { |
||||
|
||||
private final Class<O> owner; |
||||
private final Map<String, Field<?, O>> fields; |
||||
|
||||
public Fields(Class<O> owner) { |
||||
|
||||
this.owner = owner; |
||||
this.fields = new LinkedHashMap<>(); |
||||
} |
||||
|
||||
public Fields<O> add(Field<?, O> field) { |
||||
|
||||
this.fields.put(field.getFieldName(), field.owner(owner)); |
||||
return this; |
||||
} |
||||
|
||||
public boolean hasField(String fieldName) { |
||||
return this.fields.containsKey(fieldName); |
||||
} |
||||
|
||||
public <S> Field<S, O> getField(String fieldName) { |
||||
return (Field<S, O>) this.fields.get(fieldName); |
||||
} |
||||
|
||||
public void doWithFields(BiConsumer<String, Field<?, O>> consumer) { |
||||
fields.forEach(consumer); |
||||
} |
||||
|
||||
@Override |
||||
public Iterator<Field<?, O>> iterator() { |
||||
return fields.values().iterator(); |
||||
} |
||||
} |
||||
@ -0,0 +1,109 @@
@@ -0,0 +1,109 @@
|
||||
/* |
||||
* Copyright 2020. the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
/* |
||||
* Copyright 2020 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
package org.springframework.data.mongodb.core.staticmetadata; |
||||
|
||||
import static org.assertj.core.api.Assertions.*; |
||||
import static org.springframework.data.mongodb.core.query.Criteria.*; |
||||
import static org.springframework.data.mongodb.core.query.Query.*; |
||||
|
||||
import java.util.Arrays; |
||||
import java.util.LinkedHashSet; |
||||
|
||||
import org.bson.Document; |
||||
import org.junit.jupiter.api.BeforeAll; |
||||
import org.junit.jupiter.api.BeforeEach; |
||||
import org.junit.jupiter.api.Test; |
||||
import org.springframework.data.mongodb.core.MongoTemplate; |
||||
import org.springframework.data.mongodb.core.SimpleMongoClientDatabaseFactory; |
||||
import org.springframework.data.mongodb.core.convert.MappingMongoConverter; |
||||
import org.springframework.data.mongodb.core.convert.NoOpDbRefResolver; |
||||
import org.springframework.data.mongodb.core.mapping.MongoMappingContext; |
||||
import org.springframework.data.util.AddressTypeInformation; |
||||
import org.springframework.data.util.ClassTypeInformation; |
||||
import org.springframework.data.util.Person; |
||||
import org.springframework.data.util.PersonTypeInformation; |
||||
|
||||
import com.mongodb.client.MongoClients; |
||||
|
||||
/** |
||||
* @author Christoph Strobl |
||||
* @since 2020/10 |
||||
*/ |
||||
public class StaticMetadataTests { |
||||
|
||||
MongoMappingContext mappingContext; |
||||
MappingMongoConverter mongoConverter; |
||||
MongoTemplate template; |
||||
|
||||
Person luke; |
||||
|
||||
@BeforeAll |
||||
static void beforeAll() { |
||||
ClassTypeInformation.warmCache(PersonTypeInformation.instance(), AddressTypeInformation.instance()); |
||||
} |
||||
|
||||
@BeforeEach |
||||
void beforeEach() { |
||||
|
||||
mappingContext = new MongoMappingContext(); |
||||
mappingContext.setInitialEntitySet(new LinkedHashSet<>( |
||||
Arrays.asList(org.springframework.data.util.Person.class, org.springframework.data.util.Address.class))); |
||||
mappingContext.initialize(); |
||||
|
||||
mongoConverter = new MappingMongoConverter(NoOpDbRefResolver.INSTANCE, mappingContext); |
||||
mongoConverter.afterPropertiesSet(); |
||||
|
||||
template = new MongoTemplate(new SimpleMongoClientDatabaseFactory(MongoClients.create(), "sem"), mongoConverter); |
||||
|
||||
luke = new Person("luke", "skywalker"); |
||||
luke.setAddress(new org.springframework.data.util.Address("Mos Eisley", "WB154")); |
||||
luke.setAge(22); |
||||
luke = luke.withId(9876); |
||||
luke.setNicknames(Arrays.asList("jedi", "wormie")); |
||||
} |
||||
|
||||
@Test |
||||
void readWrite() { |
||||
|
||||
template.save(luke); |
||||
|
||||
Document savedDocument = template.execute("star-wars", |
||||
collection -> collection.find(new Document("_id", luke.getId())).first()); |
||||
System.out.println("savedDocument.toJson(): " + savedDocument.toJson()); |
||||
|
||||
Person savedEntity = template.findOne(query(where("id").is(luke.getId())), Person.class); |
||||
System.out.println("savedEntity: " + savedEntity); |
||||
|
||||
assertThat(savedEntity).isEqualTo(luke); |
||||
} |
||||
|
||||
} |
||||
Loading…
Reference in new issue