DATAKV-105 - Polish implementation after recent addition of features.
Remove obsolete method hasKeyspace() from KeyValueAdapter. Transition from List to Iterable for find methods in KeyValueTemplate. We now offer a plug able KeySpace resolution by providing a KeySpaceResolver via the KeyValueMappingContext. By default an AnnotationBasedKeySpaceResolver will be used to examine the type for @KeySpace. In case of non explicit keySpace we fall back to using the class' fully-qualified name as the default key space. Key space resolution is now fixed on resolving @KeySpace on a given PersistentEntity. In case no annotation key space can be found we by default fall back to a class name based key space. It is possible to configure the fallback via the MappingContext. Refactored names & visibility of types required for tests. Removed shortcut for returning results not having an explicit key space, since we now can no longer rely on the type name strategy dividing non explicit types into separate key spaces. Original pull request: #11.
This commit is contained in:
committed by
Oliver Gierke
parent
02759f58ea
commit
f19a6c0faf
@@ -14,17 +14,17 @@ The Key/Value abstraction within Spring Data Commons requires an `Adapter` shiel
|
||||
----
|
||||
interface KeyValueOperations {
|
||||
|
||||
<T> T insert(T objectToInsert); <1>
|
||||
<T> T insert(T objectToInsert); <1>
|
||||
|
||||
void update(Object objectToUpdate); <2>
|
||||
void update(Object objectToUpdate); <2>
|
||||
|
||||
void delete(Class<?> type); <3>
|
||||
void delete(Class<?> type); <3>
|
||||
|
||||
<T> T findById(Serializable id, Class<T> type); <4>
|
||||
<T> T findById(Serializable id, Class<T> type); <4>
|
||||
|
||||
<T> List<T> findAllOf(Class<T> type); <5>
|
||||
<T> Iterable<T> findAllOf(Class<T> type); <5>
|
||||
|
||||
<T> List<T> find(KeyValueQuery<?> query, Class<T> type); <6>
|
||||
<T> Iterable<T> find(KeyValueQuery<?> query, Class<T> type); <6>
|
||||
|
||||
//... more functionality omitted.
|
||||
|
||||
@@ -44,7 +44,7 @@ In its very basic shape the `KeyValueTemplate` uses a `MapAdaper` wrapping a `Co
|
||||
|
||||
NOTE: The used `KeyValueAdapter` does the heavy lifting when it comes to storing and retrieving data. The data structure used will influence performance and/or multi threading behavior.
|
||||
|
||||
One may choose to use a different type or preinitialize the adapter with some values, and can do so using `MapKeyValueAdapterFactory`.
|
||||
One may choose to use a different type or preinitialize the adapter with some values, and can do so using various constructors on `MapKeyValueAdapter`.
|
||||
|
||||
[source, java]
|
||||
----
|
||||
@@ -55,13 +55,7 @@ public KeyValueOperations keyValueTemplate() {
|
||||
|
||||
@Bean
|
||||
public KeyValueAdapter keyValueAdapter() {
|
||||
|
||||
MapKeyValueAdapterFactory factory = new MapKeyValueAdapterFactory();
|
||||
factory.setMapType(ConcurrentSkipListMap.class);
|
||||
factory.setInitialValuesForKeyspace("lennister", singletonMap("1", "tyrion"));
|
||||
factory.setInitialValuesForKeyspace("stark", singletonMap("1", "sansa"));
|
||||
|
||||
return factory.getAdapter();
|
||||
return new MapKeyValueAdapter(ConcurrentHashMap.class);
|
||||
}
|
||||
----
|
||||
|
||||
@@ -91,6 +85,29 @@ template.findAllOf(User.class); <2>
|
||||
<1> Returns all entities for keyspace "persons".
|
||||
<2> Returns only elements of type `User` stored in keyspace "persons".
|
||||
|
||||
[[key-value.keyspaces-custom]]
|
||||
=== Custom KeySpace Annotation
|
||||
|
||||
It is possible to compose own `KeySpace` annotations for a more domain centric usage by annotating one of the attibutes with `@KeySpace`.
|
||||
|
||||
NOTE: The composed annotation needs to inherit `@Persistent`.
|
||||
|
||||
[source, java]
|
||||
----
|
||||
@Persistent
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ ElementType.TYPE })
|
||||
static @interface CacheCentricAnnotation {
|
||||
|
||||
@KeySpace String cacheRegion() default "";
|
||||
}
|
||||
|
||||
@CacheCentricAnnotation(cacheRegion = "customers")
|
||||
class Customer {
|
||||
//...
|
||||
}
|
||||
----
|
||||
|
||||
[[key-value.template-query]]
|
||||
== Querying
|
||||
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2015 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.keyvalue.core;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* Most trivial implementation of {@link KeySpaceResolver} returning the {@link Class#getName()}.
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
public enum ClassNameKeySpaceResolver implements KeySpaceResolver {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.keyvalue.core.KeySpaceResolver#resolveKeySpace(java.lang.Class)
|
||||
*/
|
||||
@Override
|
||||
public String resolveKeySpace(Class<?> type) {
|
||||
|
||||
Assert.notNull(type, "Type must not be null!");
|
||||
return ClassUtils.getUserClass(type).getName();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -53,16 +53,28 @@ public class ForwardingCloseableIterator<K, V> implements CloseableIterator<Map.
|
||||
this.closeHandler = closeHandler;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.util.Iterator#hasNext()
|
||||
*/
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return delegate.hasNext();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.util.Iterator#next()
|
||||
*/
|
||||
@Override
|
||||
public Map.Entry<K, V> next() {
|
||||
return delegate.next();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.util.CloseableIterator#close()
|
||||
*/
|
||||
@Override
|
||||
public void close() {
|
||||
if (closeHandler != null) {
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2015 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.keyvalue.core;
|
||||
|
||||
/**
|
||||
* {@link KeySpaceResolver} determines the {@literal keyspace} a given type is assigned to. A keyspace in this context
|
||||
* is a specific region/collection/grouping of elements sharing a common keyrange. <br />
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
public interface KeySpaceResolver {
|
||||
|
||||
/**
|
||||
* Determine the {@literal keySpace} to use for a given type.
|
||||
*
|
||||
* @param type must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
String resolveKeySpace(Class<?> type);
|
||||
}
|
||||
@@ -76,7 +76,7 @@ public interface KeyValueAdapter extends DisposableBean {
|
||||
Iterable<?> getAllOf(Serializable keyspace);
|
||||
|
||||
/**
|
||||
* Returns a {@link KeyValueIterator} that iterates over all entries.
|
||||
* Returns a {@link KeyValueIterator} that iterates over all entries.
|
||||
*
|
||||
* @param keyspace
|
||||
* @return
|
||||
@@ -119,12 +119,4 @@ public interface KeyValueAdapter extends DisposableBean {
|
||||
* @return
|
||||
*/
|
||||
long count(KeyValueQuery<?> query, Serializable keyspace);
|
||||
|
||||
/**
|
||||
* Check if values from the given keyspace are contained in the underlying key-value store.
|
||||
*
|
||||
* @param keyspace
|
||||
* @return true if {@literal keyspace} already present in adapter.
|
||||
*/
|
||||
boolean hasKeyspace(Serializable keyspace);
|
||||
}
|
||||
|
||||
@@ -15,15 +15,12 @@
|
||||
*/
|
||||
package org.springframework.data.keyvalue.core;
|
||||
|
||||
import static org.springframework.data.keyvalue.core.KeySpaceUtils.*;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
@@ -35,6 +32,8 @@ import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
import org.springframework.dao.support.PersistenceExceptionTranslator;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.keyvalue.core.event.KeyValueEvent;
|
||||
import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentEntity;
|
||||
import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentProperty;
|
||||
import org.springframework.data.keyvalue.core.mapping.context.KeyValueMappingContext;
|
||||
import org.springframework.data.keyvalue.core.query.KeyValueQuery;
|
||||
import org.springframework.data.mapping.PersistentEntity;
|
||||
@@ -43,7 +42,6 @@ import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Basic implementation of {@link KeyValueOperations}.
|
||||
@@ -57,8 +55,8 @@ public class KeyValueTemplate implements KeyValueOperations, ApplicationContextA
|
||||
private static final PersistenceExceptionTranslator DEFAULT_PERSISTENCE_EXCEPTION_TRANSLATOR = new KeyValuePersistenceExceptionTranslator();
|
||||
|
||||
private final KeyValueAdapter adapter;
|
||||
private final ConcurrentHashMap<Class<?>, String> keySpaceCache = new ConcurrentHashMap<Class<?>, String>();
|
||||
private final MappingContext<? extends PersistentEntity<?, ? extends PersistentProperty<?>>, ? extends PersistentProperty<?>> mappingContext;
|
||||
|
||||
private final MappingContext<? extends KeyValuePersistentEntity<?>, ? extends KeyValuePersistentProperty> mappingContext;
|
||||
private final IdentifierGenerator identifierGenerator;
|
||||
private ApplicationEventPublisher eventPublisher;
|
||||
private final Set<KeyValueEvent.Type> eventTypesToPublish = new HashSet<KeyValueEvent.Type>(4);
|
||||
@@ -80,10 +78,8 @@ public class KeyValueTemplate implements KeyValueOperations, ApplicationContextA
|
||||
* @param adapter must not be {@literal null}.
|
||||
* @param mappingContext must not be {@literal null}.
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
public KeyValueTemplate(
|
||||
KeyValueAdapter adapter,
|
||||
MappingContext<? extends PersistentEntity<?, ? extends PersistentProperty>, ? extends PersistentProperty<?>> mappingContext) {
|
||||
public KeyValueTemplate(KeyValueAdapter adapter,
|
||||
MappingContext<? extends KeyValuePersistentEntity<?>, ? extends KeyValuePersistentProperty> mappingContext) {
|
||||
|
||||
Assert.notNull(adapter, "Adapter must not be null!");
|
||||
Assert.notNull(mappingContext, "MappingContext must not be null!");
|
||||
@@ -192,20 +188,20 @@ public class KeyValueTemplate implements KeyValueOperations, ApplicationContextA
|
||||
* @see org.springframework.data.keyvalue.core.KeyValueOperations#findAllOf(java.lang.Class)
|
||||
*/
|
||||
@Override
|
||||
public <T> List<T> findAll(final Class<T> type) {
|
||||
public <T> Iterable<T> findAll(final Class<T> type) {
|
||||
|
||||
Assert.notNull(type, "Type to fetch must not be null!");
|
||||
|
||||
return execute(new KeyValueCallback<List<T>>() {
|
||||
return execute(new KeyValueCallback<Iterable<T>>() {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public List<T> doInKeyValue(KeyValueAdapter adapter) {
|
||||
public Iterable<T> doInKeyValue(KeyValueAdapter adapter) {
|
||||
|
||||
Iterable<?> values = adapter.getAllOf(resolveKeySpace(type));
|
||||
|
||||
if (getKeySpace(type) == null) {
|
||||
return new ArrayList<T>(IterableConverter.toList((Iterable<T>) values));
|
||||
if (values == null) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
ArrayList<T> filtered = new ArrayList<T>();
|
||||
@@ -242,7 +238,7 @@ public class KeyValueTemplate implements KeyValueOperations, ApplicationContextA
|
||||
|
||||
Object result = adapter.get(id, keyspace);
|
||||
|
||||
if (result == null || getKeySpace(type) == null || typeCheck(type, result)) {
|
||||
if (result == null || typeCheck(type, result)) {
|
||||
return (T) result;
|
||||
}
|
||||
|
||||
@@ -355,18 +351,17 @@ public class KeyValueTemplate implements KeyValueOperations, ApplicationContextA
|
||||
* @see org.springframework.data.keyvalue.core.KeyValueOperations#find(org.springframework.data.keyvalue.core.query.KeyValueQuery, java.lang.Class)
|
||||
*/
|
||||
@Override
|
||||
public <T> List<T> find(final KeyValueQuery<?> query, final Class<T> type) {
|
||||
public <T> Iterable<T> find(final KeyValueQuery<?> query, final Class<T> type) {
|
||||
|
||||
return execute(new KeyValueCallback<List<T>>() {
|
||||
return execute(new KeyValueCallback<Iterable<T>>() {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public List<T> doInKeyValue(KeyValueAdapter adapter) {
|
||||
public Iterable<T> doInKeyValue(KeyValueAdapter adapter) {
|
||||
|
||||
Iterable<?> result = adapter.find(query, resolveKeySpace(type));
|
||||
|
||||
if (getKeySpace(type) == null) {
|
||||
return new ArrayList<T>(IterableConverter.toList((Iterable<T>) result));
|
||||
if (result == null) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
List<T> filtered = new ArrayList<T>();
|
||||
@@ -388,7 +383,7 @@ public class KeyValueTemplate implements KeyValueOperations, ApplicationContextA
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
@Override
|
||||
public <T> List<T> findAll(Sort sort, Class<T> type) {
|
||||
public <T> Iterable<T> findAll(Sort sort, Class<T> type) {
|
||||
return find(new KeyValueQuery(sort), type);
|
||||
}
|
||||
|
||||
@@ -398,7 +393,7 @@ public class KeyValueTemplate implements KeyValueOperations, ApplicationContextA
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
@Override
|
||||
public <T> List<T> findInRange(int offset, int rows, Class<T> type) {
|
||||
public <T> Iterable<T> findInRange(int offset, int rows, Class<T> type) {
|
||||
return find(new KeyValueQuery().skip(offset).limit(rows), type);
|
||||
}
|
||||
|
||||
@@ -408,7 +403,7 @@ public class KeyValueTemplate implements KeyValueOperations, ApplicationContextA
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
@Override
|
||||
public <T> List<T> findInRange(int offset, int rows, Sort sort, Class<T> type) {
|
||||
public <T> Iterable<T> findInRange(int offset, int rows, Sort sort, Class<T> type) {
|
||||
return find(new KeyValueQuery(sort).skip(offset).limit(rows), type);
|
||||
}
|
||||
|
||||
@@ -480,29 +475,8 @@ public class KeyValueTemplate implements KeyValueOperations, ApplicationContextA
|
||||
}
|
||||
}
|
||||
|
||||
protected String resolveKeySpace(Class<?> type) {
|
||||
|
||||
Class<?> userClass = ClassUtils.getUserClass(type);
|
||||
|
||||
String potentialKeySpace = keySpaceCache.get(userClass);
|
||||
|
||||
if (potentialKeySpace != null) {
|
||||
return potentialKeySpace;
|
||||
}
|
||||
|
||||
String keySpaceString = null;
|
||||
Object keySpace = getKeySpace(type);
|
||||
|
||||
if (keySpace != null) {
|
||||
keySpaceString = keySpace.toString();
|
||||
}
|
||||
|
||||
if (!StringUtils.hasText(keySpaceString)) {
|
||||
keySpaceString = userClass.getName();
|
||||
}
|
||||
|
||||
keySpaceCache.put(userClass, keySpaceString);
|
||||
return keySpaceString;
|
||||
private String resolveKeySpace(Class<?> type) {
|
||||
return this.mappingContext.getPersistentEntity(type).getKeySpace();
|
||||
}
|
||||
|
||||
private static boolean typeCheck(Class<?> requiredType, Object candidate) {
|
||||
@@ -525,4 +499,5 @@ public class KeyValueTemplate implements KeyValueOperations, ApplicationContextA
|
||||
eventPublisher.publishEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
* Copyright 2015 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.
|
||||
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.keyvalue.core;
|
||||
package org.springframework.data.keyvalue.core.mapping;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Method;
|
||||
@@ -26,24 +26,39 @@ import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.core.style.ToStringCreator;
|
||||
import org.springframework.data.annotation.Persistent;
|
||||
import org.springframework.data.keyvalue.annotation.KeySpace;
|
||||
import org.springframework.data.keyvalue.core.KeySpaceUtils.MetaAnnotationUtils.AnnotationDescriptor;
|
||||
import org.springframework.data.keyvalue.core.KeySpaceResolver;
|
||||
import org.springframework.data.keyvalue.core.mapping.AnnotationBasedKeySpaceResolver.MetaAnnotationUtils.AnnotationDescriptor;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
* {@link AnnotationBasedKeySpaceResolver} looks up {@link Persistent} and checks for presence of either meta or direct
|
||||
* usage of {@link KeySpace}. If non found it will default the keyspace to {@link Class#getName()}.
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
abstract class KeySpaceUtils {
|
||||
enum AnnotationBasedKeySpaceResolver implements KeySpaceResolver {
|
||||
|
||||
private KeySpaceUtils() {}
|
||||
INSTANCE;
|
||||
|
||||
/**
|
||||
* Looks up {@link Persistent} when used as meta annotation to find the {@link KeySpace} attribute.
|
||||
*
|
||||
* @return
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.keyvalue.core.KeySpaceResolver#resolveKeySpace(java.lang.Class)
|
||||
*/
|
||||
public static Object getKeySpace(Class<?> type) {
|
||||
@Override
|
||||
public String resolveKeySpace(Class<?> type) {
|
||||
|
||||
Assert.notNull(type, "Type for keyspace for null!");
|
||||
|
||||
Class<?> userClass = ClassUtils.getUserClass(type);
|
||||
Object keySpace = getKeySpace(userClass);
|
||||
|
||||
return keySpace != null ? keySpace.toString() : null;
|
||||
}
|
||||
|
||||
private Object getKeySpace(Class<?> type) {
|
||||
|
||||
KeySpace keyspace = AnnotationUtils.findAnnotation(type, KeySpace.class);
|
||||
|
||||
@@ -51,8 +66,7 @@ abstract class KeySpaceUtils {
|
||||
return AnnotationUtils.getValue(keyspace);
|
||||
}
|
||||
|
||||
AnnotationDescriptor<Persistent> descriptor = KeySpaceUtils.MetaAnnotationUtils.findAnnotationDescriptor(type,
|
||||
Persistent.class);
|
||||
AnnotationDescriptor<Persistent> descriptor = MetaAnnotationUtils.findAnnotationDescriptor(type, Persistent.class);
|
||||
|
||||
if (descriptor != null && descriptor.getComposedAnnotation() != null) {
|
||||
|
||||
@@ -392,6 +406,6 @@ abstract class KeySpaceUtils {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 2015 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.keyvalue.core.mapping;
|
||||
|
||||
import org.springframework.data.keyvalue.core.KeySpaceResolver;
|
||||
import org.springframework.data.mapping.model.BasicPersistentEntity;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* {@link KeyValuePersistentEntity} implementation that adds specific meta-data such as the {@literal keySpace}..
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
* @param <T>
|
||||
*/
|
||||
public class BasicKeyValuePersistentEntity<T> extends BasicPersistentEntity<T, KeyValuePersistentProperty> implements
|
||||
KeyValuePersistentEntity<T> {
|
||||
|
||||
private final String keyspace;
|
||||
|
||||
/**
|
||||
* @param information must not be {@literal null}.
|
||||
* @param keySpaceResolver must not be {@literal null}.
|
||||
*/
|
||||
public BasicKeyValuePersistentEntity(TypeInformation<T> information, KeySpaceResolver fallbackKeySpaceResolver) {
|
||||
|
||||
super(information);
|
||||
|
||||
Assert.notNull(fallbackKeySpaceResolver, "FallbackKeySpaceResolver must not be null!");
|
||||
|
||||
String resolvedKeySpace = AnnotationBasedKeySpaceResolver.INSTANCE.resolveKeySpace(information.getType());
|
||||
this.keyspace = StringUtils.hasText(resolvedKeySpace) ? resolvedKeySpace : fallbackKeySpaceResolver
|
||||
.resolveKeySpace(information.getType());
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.keyvalue.core.mapping.KeyValuePersistentEntity#getKeySpace()
|
||||
*/
|
||||
@Override
|
||||
public String getKeySpace() {
|
||||
return this.keyspace;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2015 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.keyvalue.core.mapping;
|
||||
|
||||
import org.springframework.data.mapping.model.MutablePersistentEntity;
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
* @param <T>
|
||||
*/
|
||||
public interface KeyValuePersistentEntity<T> extends MutablePersistentEntity<T, KeyValuePersistentProperty> {
|
||||
|
||||
/**
|
||||
* Get the {@literal keySpace} a given entity assigns to.
|
||||
*
|
||||
* @return never {@literal null}.
|
||||
*/
|
||||
String getKeySpace();
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
* Copyright 2014-2015 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.
|
||||
@@ -18,26 +18,54 @@ package org.springframework.data.keyvalue.core.mapping.context;
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import org.springframework.data.keyvalue.core.ClassNameKeySpaceResolver;
|
||||
import org.springframework.data.keyvalue.core.KeySpaceResolver;
|
||||
import org.springframework.data.keyvalue.core.mapping.BasicKeyValuePersistentEntity;
|
||||
import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentEntity;
|
||||
import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentProperty;
|
||||
import org.springframework.data.mapping.context.AbstractMappingContext;
|
||||
import org.springframework.data.mapping.model.BasicPersistentEntity;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.mapping.model.SimpleTypeHolder;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Default implementation of a {@link MappingContext} using {@link KeyValuePersistentEntity} and
|
||||
* {@link KeyValuePersistentProperty} as primary abstractions.
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
public class KeyValueMappingContext extends
|
||||
AbstractMappingContext<BasicPersistentEntity<?, KeyValuePersistentProperty>, KeyValuePersistentProperty> {
|
||||
AbstractMappingContext<KeyValuePersistentEntity<?>, KeyValuePersistentProperty> {
|
||||
|
||||
private final KeySpaceResolver fallbackKeySpaceResolver;
|
||||
|
||||
/**
|
||||
* Creates new {@link KeyValueMappingContext} using an {@link ClassNameKeySpaceResolver} for {@literal keyspace}
|
||||
* resolution.
|
||||
*/
|
||||
public KeyValueMappingContext() {
|
||||
this(ClassNameKeySpaceResolver.INSTANCE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new {@link KeyValueMappingContext} using given {@link KeySpaceResolver}
|
||||
*
|
||||
* @param keySpaceResolver must not be {@literal null}.
|
||||
*/
|
||||
public KeyValueMappingContext(KeySpaceResolver fallbackKeySpaceResolver) {
|
||||
|
||||
Assert.notNull(fallbackKeySpaceResolver, "FallbackKeySpaceResolver must not be null!");
|
||||
this.fallbackKeySpaceResolver = fallbackKeySpaceResolver;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mapping.context.AbstractMappingContext#createPersistentEntity(org.springframework.data.util.TypeInformation)
|
||||
*/
|
||||
@Override
|
||||
protected <T> BasicPersistentEntity<?, KeyValuePersistentProperty> createPersistentEntity(
|
||||
TypeInformation<T> typeInformation) {
|
||||
return new BasicPersistentEntity<T, KeyValuePersistentProperty>(typeInformation);
|
||||
protected <T> KeyValuePersistentEntity<T> createPersistentEntity(TypeInformation<T> typeInformation) {
|
||||
return new BasicKeyValuePersistentEntity<T>(typeInformation, fallbackKeySpaceResolver);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -46,7 +74,7 @@ public class KeyValueMappingContext extends
|
||||
*/
|
||||
@Override
|
||||
protected KeyValuePersistentProperty createPersistentProperty(Field field, PropertyDescriptor descriptor,
|
||||
BasicPersistentEntity<?, KeyValuePersistentProperty> owner, SimpleTypeHolder simpleTypeHolder) {
|
||||
KeyValuePersistentEntity<?> owner, SimpleTypeHolder simpleTypeHolder) {
|
||||
return new KeyValuePersistentProperty(field, descriptor, owner, simpleTypeHolder);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,9 +17,7 @@ package org.springframework.data.map;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.springframework.core.CollectionFactory;
|
||||
@@ -163,17 +161,6 @@ public class MapKeyValueAdapter extends AbstractKeyValueAdapter {
|
||||
getKeySpaceMap(keyspace).clear();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.keyvalue.core.KeyValueAdapter#hasKeyspace(java.io.Serializable)
|
||||
*/
|
||||
@Override
|
||||
public boolean hasKeyspace(Serializable keyspace) {
|
||||
|
||||
Assert.notNull(keyspace, "Collection must not be null for lookup.");
|
||||
return store.containsKey(keyspace);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.keyvalue.core.KeyValueAdapter#clear()
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2015 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.keyvalue;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.data.annotation.Persistent;
|
||||
import org.springframework.data.keyvalue.annotation.KeySpace;
|
||||
|
||||
/**
|
||||
* Custom composed {@link Persistent} annotation using {@link KeySpace} on name attribute.
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
@Persistent
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ ElementType.TYPE })
|
||||
public @interface CustomKeySpaceAnnotation {
|
||||
|
||||
@KeySpace
|
||||
String name() default "";
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2015 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.keyvalue;
|
||||
|
||||
import org.springframework.data.keyvalue.annotation.KeySpace;
|
||||
|
||||
/**
|
||||
* Class that inherits its {@link KeySpace} from a super class annotated with a custom {@link CustomKeySpaceAnnotation} annotation.
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
public class SubclassOfTypeWithCustomComposedKeySpaceAnnotation extends TypeWithCustomComposedKeySpaceAnnotation {
|
||||
|
||||
public SubclassOfTypeWithCustomComposedKeySpaceAnnotation(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright 2015 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.keyvalue;
|
||||
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.annotation.Persistent;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
* A {@link Persistent} type with {@link CustomKeySpaceAnnotation}.
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
@CustomKeySpaceAnnotation(name = "aliased")
|
||||
public class TypeWithCustomComposedKeySpaceAnnotation {
|
||||
|
||||
@Id String id;
|
||||
String name;
|
||||
|
||||
public TypeWithCustomComposedKeySpaceAnnotation(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ObjectUtils.nullSafeHashCode(this.id);
|
||||
result = prime * result + ObjectUtils.nullSafeHashCode(this.name);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (!(obj instanceof TypeWithCustomComposedKeySpaceAnnotation)) {
|
||||
return false;
|
||||
}
|
||||
TypeWithCustomComposedKeySpaceAnnotation other = (TypeWithCustomComposedKeySpaceAnnotation) obj;
|
||||
if (!ObjectUtils.nullSafeEquals(this.id, other.id)) {
|
||||
return false;
|
||||
}
|
||||
if (!ObjectUtils.nullSafeEquals(this.name, other.name)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright 2015 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.keyvalue;
|
||||
|
||||
import org.springframework.data.annotation.Persistent;
|
||||
import org.springframework.data.keyvalue.annotation.KeySpace;
|
||||
|
||||
/**
|
||||
* A {@link Persistent} type with explict {@link KeySpace}.
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
@KeySpace("rhaegar")
|
||||
public class TypeWithDirectKeySpaceAnnotation {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2015 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.keyvalue;
|
||||
|
||||
import org.springframework.data.annotation.Persistent;
|
||||
import org.springframework.data.annotation.TypeAlias;
|
||||
import org.springframework.data.keyvalue.annotation.KeySpace;
|
||||
|
||||
/**
|
||||
* A type inheriting {@link Persistent} from {@link TypeAlias} not having a {@link KeySpace} defined.
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
@TypeAlias("foo")
|
||||
public class TypeWithInhteritedPersistentAnnotationNotHavingKeySpace {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright 2015 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.keyvalue;
|
||||
|
||||
import org.springframework.data.annotation.Persistent;
|
||||
import org.springframework.data.keyvalue.annotation.KeySpace;
|
||||
|
||||
/**
|
||||
* A {@link Persistent} class without a defined {@link KeySpace}.
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
@Persistent
|
||||
public class TypeWithPersistentAnnotationNotHavingKeySpace {
|
||||
|
||||
}
|
||||
@@ -16,7 +16,7 @@
|
||||
package org.springframework.data.keyvalue.core;
|
||||
|
||||
import static org.hamcrest.collection.IsCollectionWithSize.*;
|
||||
import static org.hamcrest.collection.IsEmptyCollection.*;
|
||||
import static org.hamcrest.collection.IsEmptyIterable.*;
|
||||
import static org.hamcrest.collection.IsIterableContainingInAnyOrder.*;
|
||||
import static org.hamcrest.core.Is.*;
|
||||
import static org.hamcrest.core.IsNull.*;
|
||||
@@ -191,7 +191,7 @@ public class KeyValueTemplateTests {
|
||||
operations.insert("2", FOO_TWO);
|
||||
operations.insert("3", FOO_THREE);
|
||||
|
||||
assertThat(operations.findInRange(5, 5, Foo.class), empty());
|
||||
assertThat(operations.findInRange(5, 5, Foo.class), emptyIterable());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -22,10 +22,6 @@ import static org.mockito.Matchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
@@ -42,9 +38,8 @@ import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.dao.DuplicateKeyException;
|
||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.annotation.Persistent;
|
||||
import org.springframework.data.annotation.TypeAlias;
|
||||
import org.springframework.data.keyvalue.annotation.KeySpace;
|
||||
import org.springframework.data.keyvalue.TypeWithCustomComposedKeySpaceAnnotation;
|
||||
import org.springframework.data.keyvalue.SubclassOfTypeWithCustomComposedKeySpaceAnnotation;
|
||||
import org.springframework.data.keyvalue.core.event.KeyValueEvent;
|
||||
import org.springframework.data.keyvalue.core.event.KeyValueEvent.DeleteEvent;
|
||||
import org.springframework.data.keyvalue.core.event.KeyValueEvent.DropKeyspaceEvent;
|
||||
@@ -66,8 +61,8 @@ public class KeyValueTemplateUnitTests {
|
||||
|
||||
private static final Foo FOO_ONE = new Foo("one");
|
||||
private static final Foo FOO_TWO = new Foo("two");
|
||||
private static final ClassWithTypeAlias ALIASED = new ClassWithTypeAlias("super");
|
||||
private static final SubclassOfAliasedType SUBCLASS_OF_ALIASED = new SubclassOfAliasedType("sub");
|
||||
private static final TypeWithCustomComposedKeySpaceAnnotation ALIASED = new TypeWithCustomComposedKeySpaceAnnotation("super");
|
||||
private static final SubclassOfTypeWithCustomComposedKeySpaceAnnotation SUBCLASS_OF_ALIASED = new SubclassOfTypeWithCustomComposedKeySpaceAnnotation("sub");
|
||||
|
||||
private static final KeyValueQuery<String> STRING_QUERY = new KeyValueQuery<String>("foo == 'two'");
|
||||
|
||||
@@ -683,7 +678,7 @@ public class KeyValueTemplateUnitTests {
|
||||
|
||||
}
|
||||
|
||||
static class Bar {
|
||||
class Bar {
|
||||
|
||||
String bar;
|
||||
|
||||
@@ -753,94 +748,4 @@ public class KeyValueTemplateUnitTests {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ExplicitKeySpace(name = "aliased")
|
||||
static class ClassWithTypeAlias {
|
||||
|
||||
@Id String id;
|
||||
String name;
|
||||
|
||||
public ClassWithTypeAlias(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ObjectUtils.nullSafeHashCode(this.id);
|
||||
result = prime * result + ObjectUtils.nullSafeHashCode(this.name);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (!(obj instanceof ClassWithTypeAlias)) {
|
||||
return false;
|
||||
}
|
||||
ClassWithTypeAlias other = (ClassWithTypeAlias) obj;
|
||||
if (!ObjectUtils.nullSafeEquals(this.id, other.id)) {
|
||||
return false;
|
||||
}
|
||||
if (!ObjectUtils.nullSafeEquals(this.name, other.name)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class SubclassOfAliasedType extends ClassWithTypeAlias {
|
||||
|
||||
public SubclassOfAliasedType(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Persistent
|
||||
static class EntityWithPersistentAnnotation {
|
||||
|
||||
}
|
||||
|
||||
@TypeAlias("foo")
|
||||
static class AliasedEntity {
|
||||
|
||||
}
|
||||
|
||||
@KeySpace("rhaegar")
|
||||
static class ClassWithDirectKeySpaceAnnotation {
|
||||
|
||||
}
|
||||
|
||||
@Persistent
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ ElementType.TYPE })
|
||||
private static @interface ExplicitKeySpace {
|
||||
|
||||
@KeySpace
|
||||
String name() default "";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,39 +13,45 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.keyvalue.core;
|
||||
package org.springframework.data.keyvalue.core.mapping;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.springframework.data.keyvalue.core.KeySpaceUtils.*;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.annotation.Persistent;
|
||||
import org.springframework.data.keyvalue.TypeWithDirectKeySpaceAnnotation;
|
||||
import org.springframework.data.keyvalue.TypeWithInhteritedPersistentAnnotationNotHavingKeySpace;
|
||||
import org.springframework.data.keyvalue.TypeWithPersistentAnnotationNotHavingKeySpace;
|
||||
import org.springframework.data.keyvalue.annotation.KeySpace;
|
||||
import org.springframework.data.keyvalue.core.KeyValueTemplateUnitTests.AliasedEntity;
|
||||
import org.springframework.data.keyvalue.core.KeyValueTemplateUnitTests.ClassWithDirectKeySpaceAnnotation;
|
||||
import org.springframework.data.keyvalue.core.KeyValueTemplateUnitTests.EntityWithPersistentAnnotation;
|
||||
import org.springframework.data.keyvalue.core.KeyValueTemplateUnitTests.Foo;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link KeySpaceUtils}.
|
||||
* Unit tests for {@link AnnotationBasedKeySpaceResolver}.
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class KeySpaceUtilsUnitTests {
|
||||
public class AnnotationBasedKeySpaceResolverUnitTests {
|
||||
|
||||
private AnnotationBasedKeySpaceResolver resolver;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
resolver = AnnotationBasedKeySpaceResolver.INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-525
|
||||
*/
|
||||
@Test
|
||||
public void shouldResolveKeySpaceDefaultValueCorrectly() {
|
||||
assertThat(getKeySpace(EntityWithDefaultKeySpace.class), is((Object) "daenerys"));
|
||||
assertThat(resolver.resolveKeySpace(EntityWithDefaultKeySpace.class), is("daenerys"));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -53,31 +59,31 @@ public class KeySpaceUtilsUnitTests {
|
||||
*/
|
||||
@Test
|
||||
public void shouldResolveKeySpaceCorrectly() {
|
||||
assertThat(getKeySpace(EntityWithSetKeySpace.class), is((Object) "viserys"));
|
||||
assertThat(resolver.resolveKeySpace(EntityWithSetKeySpace.class), is("viserys"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-525
|
||||
* @see DATAKV-105
|
||||
*/
|
||||
@Test
|
||||
public void shouldReturnNullWhenNoKeySpaceFoundOnComposedPersistentAnnotation() {
|
||||
assertThat(getKeySpace(AliasedEntity.class), nullValue());
|
||||
assertThat(resolver.resolveKeySpace(TypeWithInhteritedPersistentAnnotationNotHavingKeySpace.class), nullValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-525
|
||||
* @see DATAKV-105
|
||||
*/
|
||||
@Test
|
||||
public void shouldReturnNullWhenPersistentIsFoundOnNonComposedAnnotation() {
|
||||
assertThat(getKeySpace(EntityWithPersistentAnnotation.class), nullValue());
|
||||
assertThat(resolver.resolveKeySpace(TypeWithPersistentAnnotationNotHavingKeySpace.class), nullValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-525
|
||||
* @see DATAKV-105
|
||||
*/
|
||||
@Test
|
||||
public void shouldReturnNullWhenPersistentIsNotFound() {
|
||||
assertThat(getKeySpace(Foo.class), nullValue());
|
||||
assertThat(resolver.resolveKeySpace(TypeWithoutKeySpace.class), nullValue());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -85,7 +91,7 @@ public class KeySpaceUtilsUnitTests {
|
||||
*/
|
||||
@Test
|
||||
public void shouldResolveInheritedKeySpaceCorrectly() {
|
||||
assertThat(getKeySpace(EntityWithInheritedKeySpace.class), is((Object) "viserys"));
|
||||
assertThat(resolver.resolveKeySpace(EntityWithInheritedKeySpace.class), is("viserys"));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -93,7 +99,7 @@ public class KeySpaceUtilsUnitTests {
|
||||
*/
|
||||
@Test
|
||||
public void shouldResolveDirectKeySpaceAnnotationCorrectly() {
|
||||
assertThat(getKeySpace(ClassWithDirectKeySpaceAnnotation.class), is((Object) "rhaegar"));
|
||||
assertThat(resolver.resolveKeySpace(TypeWithDirectKeySpaceAnnotation.class), is("rhaegar"));
|
||||
}
|
||||
|
||||
@PersistentAnnotationWithExplicitKeySpace
|
||||
@@ -121,12 +127,9 @@ public class KeySpaceUtilsUnitTests {
|
||||
String lastnamne() default "targaryen";
|
||||
}
|
||||
|
||||
@Persistent
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ ElementType.TYPE })
|
||||
static @interface ExplicitKeySpace {
|
||||
static class TypeWithoutKeySpace {
|
||||
|
||||
String foo;
|
||||
|
||||
@KeySpace
|
||||
String name() default "";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2015 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 ort.springframework.data.keyvalue.core.mapping.context;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.keyvalue.core.mapping.context.KeyValueMappingContext;
|
||||
|
||||
public class KeyValueMappingContextUnitTests {
|
||||
|
||||
/**
|
||||
* @see DATAKV-105
|
||||
*/
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void shouldThrowExceptionWhenKeySpaceResolverIsNull() {
|
||||
new KeyValueMappingContext(null);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user