diff --git a/src/main/asciidoc/key-value-repositories.adoc b/src/main/asciidoc/key-value-repositories.adoc deleted file mode 100644 index e10fa862f..000000000 --- a/src/main/asciidoc/key-value-repositories.adoc +++ /dev/null @@ -1,147 +0,0 @@ -:spring-framework-docs: http://docs.spring.io/spring-framework/docs/current/spring-framework-reference/html - -[[key-value]] -= Key Value Repositories - -This chapter explains concepts and usage patterns when working with the key value abstraction and the `java.util.Map` based implementation provided by Spring Data Commons. - -[[key-value.core-concepts]] -== Core Concepts - -The Key/Value abstraction within Spring Data Commons requires an `Adapter` shielding the native store implementation freeing up `KeyValueTemplate` to work on top of any key/value pair like structure. Keys are distributed across <>. Unless otherwise specified the class name is used as the default keyspace for an entity. - -[source, java] ----- -interface KeyValueOperations { - - T insert(T objectToInsert); <1> - - void update(Object objectToUpdate); <2> - - void delete(Class type); <3> - - T findById(Serializable id, Class type); <4> - - List findAllOf(Class type); <5> - - List find(KeyValueQuery query, Class type); <6> - - //... more functionality omitted. - -} ----- -<1> Inserts the given entity and assigns id if required. -<2> Updates the given entity. -<3> Removes all entities of matching type. -<4> Returns the entity of given type with matching id. -<5> Returns all entities of matching type. -<6> Returns a List of all entities of given type matching the criteria of the query. - -[[key-value.template-configuration]] -== Configuring The KeyValueTemplate - -In its very basic shape the `KeyValueTemplate` uses a `MapAdaper` wrapping a `ConcurrentHashMap` using link:{spring-framework-docs}/expressions.html[Spring Expression Language] to perform queries and sorting. - -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`. - -[source, java] ----- -@Bean -public KeyValueOperations keyValueTemplate() { - return new KeyValueTemplate(keyValueAdapter()); -} - -@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(); -} ----- - -[[key-value.keyspaces]] -== Keyspaces - -Keyspaces define in which part of the data structure the entity should be kept. So this is a rather similar concept as collections in MongoDB and Elasticsearch, Cores in Solr, Tables in JPA. -By default the keyspace of an entity is extracted form its type, but one can also choose to store entities of different types within one keyspace. In that case any find operation will type check results. - -[source, java] ----- -@KeySpace("persons") -class Person { - - @Id String id; - String firstname; - String lastname; -} - -class User extends Person { - String username; -} - -template.findAllOf(Person.class); <1> -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.template-query]] -== Querying - -Query execution is managed by the `QueryEngine`. As mentioned before it is possible to instruct the `KeyValueAdapter` to use an implementation specific `QueryEngine` that allows access to native functionality. -When used without further customization queries are be executed using a `SpELQueryEngine`. - -NOTE: For performance reasons, we highly recommend to have at least Spring 4.1.2 or better to make use of link:{spring-framework-docs}/expressions.html#expressions-spel-compilation[compiled SpEL Expressions]. - -[source, java] ----- -KeyValueQuery query = new KeyValueQuery("lastname == 'targaryen'"); -List targaryens = template.find(query, Person.class); ----- - -WARNING: Please note that you need to have getters/setters present to query properties using SpEL. - -[[key-value.template-sort]] -== Sorting - -Depending on the store implementation provided by the adapter entities might already be stored in some sorted way but do not necessarily have to be. Again the underlying `QueryEngine` is capable of performing sort operations. -When used without further customization sorting is done using a `SpelPropertyComperator` extracted from the `Sort` clause provided - -[source, java] ----- -KeyValueQuery query = new KeyValueQuery("lastname == 'baratheon'"); -query.setSort(new Sort(DESC, "age")); -List targaryens = template.find(query, Person.class); ----- - -WARNING: Please note that you need to have getters/setters present to sort using SpEL. - -[[key-value.repositories]] -== Key Value Repositories - -KeyValue repositories reside on top of the `KeyValaueTemplate`. Using the default `SpelQueryCreator` allows deriving query and sort expressions from the given methodname. - -[source, java] ----- -@Configuration -@EnableKeyValueRepositories -class KeyValueConfig { - - @Bean - public KeyValueOperations keyValueTemplate() { - return new KeyValueTemplate(new MapKeyValueAdapter()); - } - -} - -interface PersonRepository implements CrudRepository { - List findByLastname(String lastname); -} ----- - diff --git a/src/main/java/org/springframework/data/keyvalue/annotation/KeySpace.java b/src/main/java/org/springframework/data/keyvalue/annotation/KeySpace.java deleted file mode 100644 index a4078f0f5..000000000 --- a/src/main/java/org/springframework/data/keyvalue/annotation/KeySpace.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2014 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.annotation; - -import static java.lang.annotation.ElementType.*; - -import java.lang.annotation.Documented; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.springframework.data.annotation.Persistent; - -/** - * Marker interface for methods with {@link Persistent} annotations indicating the presence of a dedicated keyspace the - * entity should reside in. If present the value will be picked up for resolving the keyspace. - * - *
- * 
- * @Persistent
- * @Documented
- * @Retention(RetentionPolicy.RUNTIME)
- * @Target({ ElementType.TYPE })
- * public @interface Document {
- * 
- * 		@KeySpace
- * 		String collection() default "person";
- * } 
- * 
- * 
- * - * Can also be directly used on types to indicate the keyspace. - * - *
- * 
- * @KeySpace("persons")
- * public class Foo {
- * 
- * } 
- * 
- * 
- * - * @author Christoph Strobl - * @since 1.10 - */ -@Documented -@Retention(RetentionPolicy.RUNTIME) -@Target(value = { METHOD, TYPE }) -public @interface KeySpace { - - String value() default ""; -} diff --git a/src/main/java/org/springframework/data/keyvalue/core/AbstractKeyValueAdapter.java b/src/main/java/org/springframework/data/keyvalue/core/AbstractKeyValueAdapter.java deleted file mode 100644 index 748c31e2f..000000000 --- a/src/main/java/org/springframework/data/keyvalue/core/AbstractKeyValueAdapter.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2014 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 java.io.Serializable; -import java.util.Collection; - -import org.springframework.data.keyvalue.core.query.KeyValueQuery; - -/** - * Base implementation of {@link KeyValueAdapter} holds {@link QueryEngine} to delegate {@literal find} and - * {@literal count} execution to. - * - * @author Christoph Strobl - * @since 1.10 - */ -public abstract class AbstractKeyValueAdapter implements KeyValueAdapter { - - private final QueryEngine engine; - - /** - * Creates new {@link AbstractKeyValueAdapter} with using the default query engine. - */ - protected AbstractKeyValueAdapter() { - this(null); - } - - /** - * Creates new {@link AbstractKeyValueAdapter} with using the default query engine. - * - * @param engine will be defaulted to {@link SpelQueryEngine} if {@literal null}. - */ - protected AbstractKeyValueAdapter(QueryEngine engine) { - - this.engine = engine != null ? engine : new SpelQueryEngine(); - this.engine.registerAdapter(this); - } - - /** - * Get the {@link QueryEngine} used. - * - * @return - */ - protected QueryEngine getQueryEngine() { - return engine; - } - - /* - * (non-Javadoc) - * @see org.springframework.data.keyvalue.core.KeyValueAdapter#find(org.springframework.data.keyvalue.core.query.KeyValueQuery, java.io.Serializable) - */ - @Override - public Collection find(KeyValueQuery query, Serializable keyspace) { - return engine.execute(query, keyspace); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.keyvalue.core.KeyValueAdapter#count(org.springframework.data.keyvalue.core.query.KeyValueQuery, java.io.Serializable) - */ - @Override - public long count(KeyValueQuery query, Serializable keyspace) { - return engine.count(query, keyspace); - } -} diff --git a/src/main/java/org/springframework/data/keyvalue/core/CriteriaAccessor.java b/src/main/java/org/springframework/data/keyvalue/core/CriteriaAccessor.java deleted file mode 100644 index d1804ceb9..000000000 --- a/src/main/java/org/springframework/data/keyvalue/core/CriteriaAccessor.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2014 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.data.keyvalue.core.query.KeyValueQuery; - -/** - * Resolves the criteria object from given {@link KeyValueQuery}. - * - * @author Christoph Strobl - * @since 1.10 - * @param - */ -public interface CriteriaAccessor { - - /** - * Checks and reads {@link KeyValueQuery#getCritieria()} of given {@link KeyValueQuery}. Might also apply additional - * transformation to match the desired type. - * - * @param query can be {@literal null}. - * @return the criteria extracted from the query. - * @throws IllegalArgumentException in case the criteria is not valid for usage with specific {@link CriteriaAccessor} - * . - */ - T resolve(KeyValueQuery query); -} diff --git a/src/main/java/org/springframework/data/keyvalue/core/DefaultIdentifierGenerator.java b/src/main/java/org/springframework/data/keyvalue/core/DefaultIdentifierGenerator.java deleted file mode 100644 index 95dc05467..000000000 --- a/src/main/java/org/springframework/data/keyvalue/core/DefaultIdentifierGenerator.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2014 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 java.security.NoSuchAlgorithmException; -import java.security.SecureRandom; -import java.util.UUID; - -import org.springframework.dao.InvalidDataAccessApiUsageException; -import org.springframework.data.util.TypeInformation; -import org.springframework.util.ClassUtils; - -/** - * Default implementation of {@link IdentifierGenerator} to generate identifiers of types {@link UUID}, String, - * - * @author Christoph Strobl - * @author Oliver Gierke - */ -enum DefaultIdentifierGenerator implements IdentifierGenerator { - - INSTANCE; - - private static final String ALGORITHM = "NativePRNGBlocking"; - - /* - * (non-Javadoc) - * @see org.springframework.data.keyvalue.core.IdentifierGenerator#newIdForType(org.springframework.data.util.TypeInformation) - */ - @Override - @SuppressWarnings("unchecked") - public T generateIdentifierOfType(TypeInformation identifierType) { - - Class type = identifierType.getType(); - - if (ClassUtils.isAssignable(UUID.class, type)) { - return (T) UUID.randomUUID(); - } else if (ClassUtils.isAssignable(String.class, type)) { - return (T) UUID.randomUUID().toString(); - } else if (ClassUtils.isAssignable(Integer.class, type)) { - - try { - return (T) SecureRandom.getInstance(ALGORITHM); - } catch (NoSuchAlgorithmException e) { - throw new InvalidDataAccessApiUsageException("Could not create SecureRandom instance.", e); - } - - } else if (ClassUtils.isAssignable(Long.class, type)) { - - try { - return (T) Long.valueOf(SecureRandom.getInstance(ALGORITHM).nextLong()); - } catch (NoSuchAlgorithmException e) { - throw new InvalidDataAccessApiUsageException("Could not create SecureRandom instance.", e); - } - } - - throw new InvalidDataAccessApiUsageException("Non gereratable id type...."); - } -} diff --git a/src/main/java/org/springframework/data/keyvalue/core/GeneratingIdAccessor.java b/src/main/java/org/springframework/data/keyvalue/core/GeneratingIdAccessor.java deleted file mode 100644 index ab0098901..000000000 --- a/src/main/java/org/springframework/data/keyvalue/core/GeneratingIdAccessor.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2014 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 java.io.Serializable; - -import org.springframework.data.mapping.IdentifierAccessor; -import org.springframework.data.mapping.PersistentProperty; -import org.springframework.data.mapping.PersistentPropertyAccessor; -import org.springframework.util.Assert; - -/** - * {@link IdentifierAccessor} adding a {@link #getOrGenerateIdentifier()} to automatically generate an identifier and - * set it on the underling bean instance. - * - * @author Oliver Gierke - * @see #getOrGenerateIdentifier() - */ -class GeneratingIdAccessor implements IdentifierAccessor { - - private final PersistentPropertyAccessor accessor; - private final PersistentProperty identifierProperty; - private final IdentifierGenerator generator; - - /** - * Creates a new {@link GeneratingIdAccessor} using the given {@link PersistentPropertyAccessor}, identifier property - * and {@link IdentifierGenerator}. - * - * @param accessor must not be {@literal null}. - * @param identifierProperty must not be {@literal null}. - * @param generator must not be {@literal null}. - */ - public GeneratingIdAccessor(PersistentPropertyAccessor accessor, PersistentProperty identifierProperty, - IdentifierGenerator generator) { - - Assert.notNull(accessor, "PersistentPropertyAccessor must not be null!"); - Assert.notNull(identifierProperty, "Identifier property must not be null!"); - Assert.notNull(generator, "IdentifierGenerator must not be null!"); - - this.accessor = accessor; - this.identifierProperty = identifierProperty; - this.generator = generator; - } - - /* - * (non-Javadoc) - * @see org.springframework.data.keyvalue.core.IdentifierAccessor#getIdentifier() - */ - @Override - public Object getIdentifier() { - return accessor.getProperty(identifierProperty); - } - - /** - * Returns the identifier value of the backing bean or generates a new one using the configured - * {@link IdentifierGenerator}. - * - * @return - */ - public Object getOrGenerateIdentifier() { - - Serializable existingIdentifier = (Serializable) getIdentifier(); - - if (existingIdentifier != null) { - return existingIdentifier; - } - - Object generatedIdentifier = generator.generateIdentifierOfType(identifierProperty.getTypeInformation()); - accessor.setProperty(identifierProperty, generatedIdentifier); - - return generatedIdentifier; - } -} diff --git a/src/main/java/org/springframework/data/keyvalue/core/IdentifierGenerator.java b/src/main/java/org/springframework/data/keyvalue/core/IdentifierGenerator.java deleted file mode 100644 index 25361d2c1..000000000 --- a/src/main/java/org/springframework/data/keyvalue/core/IdentifierGenerator.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2014 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.data.util.TypeInformation; - -/** - * API for components generating identifiers. - * - * @author Christoph Strobl - * @author Oliver Gierke - * @since 1.10 - */ -public interface IdentifierGenerator { - - /** - * Creates an identifier of the given type. - * - * @param type must not be {@literal null}. - * @return an identifier of the given type. - */ - T generateIdentifierOfType(TypeInformation type); -} diff --git a/src/main/java/org/springframework/data/keyvalue/core/KeySpaceUtils.java b/src/main/java/org/springframework/data/keyvalue/core/KeySpaceUtils.java deleted file mode 100644 index 640c2c6e2..000000000 --- a/src/main/java/org/springframework/data/keyvalue/core/KeySpaceUtils.java +++ /dev/null @@ -1,398 +0,0 @@ -/* - * Copyright 2014 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 java.lang.annotation.Annotation; -import java.lang.reflect.Method; -import java.util.HashSet; -import java.util.Set; - -import org.springframework.core.annotation.AnnotatedElementUtils; -import org.springframework.core.annotation.AnnotationAttributes; -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.util.Assert; -import org.springframework.util.ObjectUtils; - -/** - * @author Christoph Strobl - * @author Oliver Gierke - */ -abstract class KeySpaceUtils { - - private KeySpaceUtils() {} - - /** - * Looks up {@link Persistent} when used as meta annotation to find the {@link KeySpace} attribute. - * - * @return - * @since 1.10 - */ - public static Object getKeySpace(Class type) { - - KeySpace keyspace = AnnotationUtils.findAnnotation(type, KeySpace.class); - - if (keyspace != null) { - return AnnotationUtils.getValue(keyspace); - } - - AnnotationDescriptor descriptor = KeySpaceUtils.MetaAnnotationUtils.findAnnotationDescriptor(type, - Persistent.class); - - if (descriptor != null && descriptor.getComposedAnnotation() != null) { - - Annotation composed = descriptor.getComposedAnnotation(); - - for (Method method : descriptor.getComposedAnnotationType().getDeclaredMethods()) { - - keyspace = AnnotationUtils.findAnnotation(method, KeySpace.class); - - if (keyspace != null) { - return AnnotationUtils.getValue(composed, method.getName()); - } - } - } - return null; - } - - /** - * {@code MetaAnnotationUtils} is a collection of utility methods that complements the standard support already - * available in {@link AnnotationUtils}. - *

- * Whereas {@code AnnotationUtils} provides utilities for getting or finding an annotation, - * {@code MetaAnnotationUtils} goes a step further by providing support for determining the root class on - * which an annotation is declared, either directly or indirectly via a composed - * annotation. This additional information is encapsulated in an {@link AnnotationDescriptor}. - *

- * The additional information provided by an {@code AnnotationDescriptor} is required by the - * Spring TestContext Framework in order to be able to support class hierarchy traversals for annotations - * such as {@link org.springframework.test.context.ContextConfiguration @ContextConfiguration}, - * {@link org.springframework.test.context.TestExecutionListeners @TestExecutionListeners}, and - * {@link org.springframework.test.context.ActiveProfiles @ActiveProfiles} which offer support for merging and - * overriding various inherited annotation attributes (e.g., - * {@link org.springframework.test.context.ContextConfiguration#inheritLocations}). - * - * @author Sam Brannen - * @since 4.0 - * @see AnnotationUtils - * @see AnnotationDescriptor - */ - static abstract class MetaAnnotationUtils { - - private MetaAnnotationUtils() { - /* no-op */ - } - - /** - * Find the {@link AnnotationDescriptor} for the supplied {@code annotationType} on the supplied {@link Class}, - * traversing its annotations and superclasses if no annotation can be found on the given class itself. - *

- * This method explicitly handles class-level annotations which are not declared as - * {@linkplain java.lang.annotation.Inherited inherited} as - * well as meta-annotations. - *

- * The algorithm operates as follows: - *

    - *
  1. Search for the annotation on the given class and return a corresponding {@code AnnotationDescriptor} if - * found. - *
  2. Recursively search through all annotations that the given class declares. - *
  3. Recursively search through the superclass hierarchy of the given class. - *
- *

- * In this context, the term recursively means that the search process continues by returning to step #1 - * with the current annotation or superclass as the class to look for annotations on. - *

- * If the supplied {@code clazz} is an interface, only the interface itself will be checked; the inheritance - * hierarchy for interfaces will not be traversed. - * - * @param clazz the class to look for annotations on - * @param annotationType the type of annotation to look for - * @return the corresponding annotation descriptor if the annotation was found; otherwise {@code null} - * @see AnnotationUtils#findAnnotationDeclaringClass(Class, Class) - * @see #findAnnotationDescriptorForTypes(Class, Class...) - */ - public static AnnotationDescriptor findAnnotationDescriptor(Class clazz, - Class annotationType) { - return findAnnotationDescriptor(clazz, new HashSet(), annotationType); - } - - /** - * Perform the search algorithm for {@link #findAnnotationDescriptor(Class, Class)}, avoiding endless recursion by - * tracking which annotations have already been visited. - * - * @param clazz the class to look for annotations on - * @param visited the set of annotations that have already been visited - * @param annotationType the type of annotation to look for - * @return the corresponding annotation descriptor if the annotation was found; otherwise {@code null} - */ - private static AnnotationDescriptor findAnnotationDescriptor(Class clazz, - Set visited, Class annotationType) { - - Assert.notNull(annotationType, "Annotation type must not be null"); - - if (clazz == null || clazz.equals(Object.class)) { - return null; - } - - // Declared locally? - if (AnnotationUtils.isAnnotationDeclaredLocally(annotationType, clazz)) { - return new AnnotationDescriptor(clazz, clazz.getAnnotation(annotationType)); - } - - // Declared on a composed annotation (i.e., as a meta-annotation)? - for (Annotation composedAnnotation : clazz.getDeclaredAnnotations()) { - if (!AnnotationUtils.isInJavaLangAnnotationPackage(composedAnnotation) && visited.add(composedAnnotation)) { - AnnotationDescriptor descriptor = findAnnotationDescriptor(composedAnnotation.annotationType(), visited, - annotationType); - if (descriptor != null) { - return new AnnotationDescriptor(clazz, descriptor.getDeclaringClass(), composedAnnotation, - descriptor.getAnnotation()); - } - } - } - - // Declared on a superclass? - return findAnnotationDescriptor(clazz.getSuperclass(), visited, annotationType); - } - - /** - * Find the {@link UntypedAnnotationDescriptor} for the first {@link Class} in the inheritance hierarchy of the - * specified {@code clazz} (including the specified {@code clazz} itself) which declares at least one of the - * specified {@code annotationTypes}. - *

- * This method traverses the annotations and superclasses of the specified {@code clazz} if no annotation can be - * found on the given class itself. - *

- * This method explicitly handles class-level annotations which are not declared as - * {@linkplain java.lang.annotation.Inherited inherited} as - * well as meta-annotations. - *

- * The algorithm operates as follows: - *

    - *
  1. Search for a local declaration of one of the annotation types on the given class and return a corresponding - * {@code UntypedAnnotationDescriptor} if found. - *
  2. Recursively search through all annotations that the given class declares. - *
  3. Recursively search through the superclass hierarchy of the given class. - *
- *

- * In this context, the term recursively means that the search process continues by returning to step #1 - * with the current annotation or superclass as the class to look for annotations on. - *

- * If the supplied {@code clazz} is an interface, only the interface itself will be checked; the inheritance - * hierarchy for interfaces will not be traversed. - * - * @param clazz the class to look for annotations on - * @param annotationTypes the types of annotations to look for - * @return the corresponding annotation descriptor if one of the annotations was found; otherwise {@code null} - * @see AnnotationUtils#findAnnotationDeclaringClassForTypes(java.util.List, Class) - * @see #findAnnotationDescriptor(Class, Class) - */ - public static UntypedAnnotationDescriptor findAnnotationDescriptorForTypes(Class clazz, - Class... annotationTypes) { - return findAnnotationDescriptorForTypes(clazz, new HashSet(), annotationTypes); - } - - /** - * Perform the search algorithm for {@link #findAnnotationDescriptorForTypes(Class, Class...)}, avoiding endless - * recursion by tracking which annotations have already been visited. - * - * @param clazz the class to look for annotations on - * @param visited the set of annotations that have already been visited - * @param annotationTypes the types of annotations to look for - * @return the corresponding annotation descriptor if one of the annotations was found; otherwise {@code null} - */ - private static UntypedAnnotationDescriptor findAnnotationDescriptorForTypes(Class clazz, - Set visited, Class... annotationTypes) { - - assertNonEmptyAnnotationTypeArray(annotationTypes, "The list of annotation types must not be empty"); - - if (clazz == null || clazz.equals(Object.class)) { - return null; - } - - // Declared locally? - for (Class annotationType : annotationTypes) { - if (AnnotationUtils.isAnnotationDeclaredLocally(annotationType, clazz)) { - return new UntypedAnnotationDescriptor(clazz, clazz.getAnnotation(annotationType)); - } - } - - // Declared on a composed annotation (i.e., as a meta-annotation)? - for (Annotation composedAnnotation : clazz.getDeclaredAnnotations()) { - if (!AnnotationUtils.isInJavaLangAnnotationPackage(composedAnnotation) && visited.add(composedAnnotation)) { - UntypedAnnotationDescriptor descriptor = findAnnotationDescriptorForTypes( - composedAnnotation.annotationType(), visited, annotationTypes); - if (descriptor != null) { - return new UntypedAnnotationDescriptor(clazz, descriptor.getDeclaringClass(), composedAnnotation, - descriptor.getAnnotation()); - } - } - } - - // Declared on a superclass? - return findAnnotationDescriptorForTypes(clazz.getSuperclass(), visited, annotationTypes); - } - - /** - * Descriptor for an {@link Annotation}, including the {@linkplain #getDeclaringClass() class} on which the - * annotation is declared as well as the actual {@linkplain #getAnnotation() annotation} instance. - *

- * If the annotation is used as a meta-annotation, the descriptor also includes the - * {@linkplain #getComposedAnnotation() composed annotation} on which the annotation is present. In such cases, the - * root declaring class is not directly annotated with the annotation but rather indirectly via the - * composed annotation. - *

- * Given the following example, if we are searching for the {@code @Transactional} annotation on the - * {@code TransactionalTests} class, then the properties of the {@code AnnotationDescriptor} would be as follows. - *

    - *
  • rootDeclaringClass: {@code TransactionalTests} class object
  • - *
  • declaringClass: {@code TransactionalTests} class object
  • - *
  • composedAnnotation: {@code null}
  • - *
  • annotation: instance of the {@code Transactional} annotation
  • - *
- * - *
-		 * @Transactional
-		 * @ContextConfiguration({ "/test-datasource.xml", "/repository-config.xml" })
-		 * public class TransactionalTests {}
-		 * 
- *

- * Given the following example, if we are searching for the {@code @Transactional} annotation on the - * {@code UserRepositoryTests} class, then the properties of the {@code AnnotationDescriptor} would be as follows. - *

    - *
  • rootDeclaringClass: {@code UserRepositoryTests} class object
  • - *
  • declaringClass: {@code RepositoryTests} class object
  • - *
  • composedAnnotation: instance of the {@code RepositoryTests} annotation
  • - *
  • annotation: instance of the {@code Transactional} annotation
  • - *
- * - *
-		 * @Transactional
-		 * @ContextConfiguration({ "/test-datasource.xml", "/repository-config.xml" })
-		 * @Retention(RetentionPolicy.RUNTIME)
-		 * public @interface RepositoryTests {
-		 * }
-		 * 
-		 * @RepositoryTests
-		 * public class UserRepositoryTests {}
-		 * 
- * - * @author Sam Brannen - * @since 4.0 - */ - public static class AnnotationDescriptor { - - private final Class rootDeclaringClass; - private final Class declaringClass; - private final Annotation composedAnnotation; - private final T annotation; - private final AnnotationAttributes annotationAttributes; - - public AnnotationDescriptor(Class rootDeclaringClass, T annotation) { - this(rootDeclaringClass, rootDeclaringClass, null, annotation); - } - - public AnnotationDescriptor(Class rootDeclaringClass, Class declaringClass, Annotation composedAnnotation, - T annotation) { - Assert.notNull(rootDeclaringClass, "rootDeclaringClass must not be null"); - Assert.notNull(annotation, "annotation must not be null"); - - this.rootDeclaringClass = rootDeclaringClass; - this.declaringClass = declaringClass; - this.composedAnnotation = composedAnnotation; - this.annotation = annotation; - this.annotationAttributes = AnnotatedElementUtils.getAnnotationAttributes(rootDeclaringClass, annotation - .annotationType().getName()); - } - - public Class getRootDeclaringClass() { - return this.rootDeclaringClass; - } - - public Class getDeclaringClass() { - return this.declaringClass; - } - - public T getAnnotation() { - return this.annotation; - } - - public Class getAnnotationType() { - return this.annotation.annotationType(); - } - - public AnnotationAttributes getAnnotationAttributes() { - return this.annotationAttributes; - } - - public Annotation getComposedAnnotation() { - return this.composedAnnotation; - } - - public Class getComposedAnnotationType() { - return this.composedAnnotation == null ? null : this.composedAnnotation.annotationType(); - } - - /** - * Provide a textual representation of this {@code AnnotationDescriptor}. - */ - @Override - public String toString() { - return new ToStringCreator(this)// - .append("rootDeclaringClass", rootDeclaringClass)// - .append("declaringClass", declaringClass)// - .append("composedAnnotation", composedAnnotation)// - .append("annotation", annotation)// - .toString(); - } - } - - /** - * Untyped extension of {@code AnnotationDescriptor} that is used to describe the declaration of one of - * several candidate annotation types where the actual annotation type cannot be predetermined. - * - * @author Sam Brannen - * @since 4.0 - */ - public static class UntypedAnnotationDescriptor extends AnnotationDescriptor { - - public UntypedAnnotationDescriptor(Class rootDeclaringClass, Annotation annotation) { - this(rootDeclaringClass, rootDeclaringClass, null, annotation); - } - - public UntypedAnnotationDescriptor(Class rootDeclaringClass, Class declaringClass, - Annotation composedAnnotation, Annotation annotation) { - super(rootDeclaringClass, declaringClass, composedAnnotation, annotation); - } - } - - private static void assertNonEmptyAnnotationTypeArray(Class[] annotationTypes, String message) { - if (ObjectUtils.isEmpty(annotationTypes)) { - throw new IllegalArgumentException(message); - } - - for (Class clazz : annotationTypes) { - if (!Annotation.class.isAssignableFrom(clazz)) { - throw new IllegalArgumentException("Array elements must be of type Annotation"); - } - } - } - - } -} diff --git a/src/main/java/org/springframework/data/keyvalue/core/KeyValueAdapter.java b/src/main/java/org/springframework/data/keyvalue/core/KeyValueAdapter.java deleted file mode 100644 index 42be9c4ff..000000000 --- a/src/main/java/org/springframework/data/keyvalue/core/KeyValueAdapter.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright 2014 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 java.io.Serializable; -import java.util.Collection; - -import org.springframework.beans.factory.DisposableBean; -import org.springframework.data.keyvalue.core.query.KeyValueQuery; - -/** - * {@link KeyValueAdapter} unifies access and shields the underlying key/value specific implementation. - * - * @author Christoph Strobl - * @since 1.10 - */ -public interface KeyValueAdapter extends DisposableBean { - - /** - * Add object with given id to keyspace. - * - * @param id must not be {@literal null}. - * @param keyspace must not be {@literal null}. - * @return the item previously associated with the id. - */ - Object put(Serializable id, Object item, Serializable keyspace); - - /** - * Check if a object with given id exists in keyspace. - * - * @param id must not be {@literal null}. - * @param keyspace must not be {@literal null}. - * @return true if item of type with id exists. - */ - boolean contains(Serializable id, Serializable keyspace); - - /** - * Get the object with given id from keyspace. - * - * @param id must not be {@literal null}. - * @param keyspace must not be {@literal null}. - * @return {@literal null} in case no matching item exists. - */ - Object get(Serializable id, Serializable keyspace); - - /** - * Delete and return the obect with given type and id. - * - * @param id must not be {@literal null}. - * @param keyspace must not be {@literal null}. - * @return {@literal null} if object could not be found - */ - Object delete(Serializable id, Serializable keyspace); - - /** - * Get all elements for given keyspace. - * - * @param keyspace must not be {@literal null}. - * @return empty {@link Collection} if nothing found. - */ - Collection getAllOf(Serializable keyspace); - - /** - * Remove all objects of given type. - * - * @param keyspace must not be {@literal null}. - */ - void deleteAllOf(Serializable keyspace); - - /** - * Removes all objects. - */ - void clear(); - - /** - * Find all matching objects within {@literal keyspace}. - * - * @param query - * @param keyspace must not be {@literal null}. - * @return empty {@link Collection} if no match found. - */ - Collection find(KeyValueQuery query, Serializable keyspace); - - /** - * Count all matching objects within {@literal keyspace}. - * - * @param query - * @param keyspace must not be {@literal null}. - * @return - */ - long count(KeyValueQuery query, Serializable keyspace); -} diff --git a/src/main/java/org/springframework/data/keyvalue/core/KeyValueCallback.java b/src/main/java/org/springframework/data/keyvalue/core/KeyValueCallback.java deleted file mode 100644 index b30f49d2f..000000000 --- a/src/main/java/org/springframework/data/keyvalue/core/KeyValueCallback.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2014 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; - -/** - * Generic callback interface for code that operates on a {@link KeyValueAdapter}. This is particularly useful for - * delegating code that needs to work closely on the underlying key/value store implementation. - * - * @author Christoph Strobl - * @since 1.10 - * @param - */ -public interface KeyValueCallback { - - /** - * Gets called by {@code KeyValueTemplate#execute(KeyValueCallback)}. Allows for returning a result object created - * within the callback, i.e. a domain object or a collection of domain objects. - * - * @param adapter - * @return - */ - T doInKeyValue(KeyValueAdapter adapter); -} diff --git a/src/main/java/org/springframework/data/keyvalue/core/KeyValueOperations.java b/src/main/java/org/springframework/data/keyvalue/core/KeyValueOperations.java deleted file mode 100644 index 3495408b7..000000000 --- a/src/main/java/org/springframework/data/keyvalue/core/KeyValueOperations.java +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright 2014 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 java.io.Serializable; -import java.util.List; - -import org.springframework.beans.factory.DisposableBean; -import org.springframework.data.domain.Sort; -import org.springframework.data.keyvalue.annotation.KeySpace; -import org.springframework.data.keyvalue.core.query.KeyValueQuery; -import org.springframework.data.mapping.context.MappingContext; - -/** - * Interface that specifies a basic set of key/value operations. Implemented by {@link KeyValueTemplate}. - * - * @author Christoph Strobl - * @since 1.10 - */ -public interface KeyValueOperations extends DisposableBean { - - /** - * Add given object. Object needs to have id property to which a generated value will be assigned. - * - * @param objectToInsert - * @return - */ - T insert(T objectToInsert); - - /** - * Add object with given id. - * - * @param id must not be {@literal null}. - * @param objectToInsert must not be {@literal null}. - */ - void insert(Serializable id, Object objectToInsert); - - /** - * Get all elements of given type. Respects {@link KeySpace} if present and therefore returns all elements that can be - * assigned to requested type. - * - * @param type must not be {@literal null}. - * @return empty collection if no elements found. - */ - List findAll(Class type); - - /** - * Get all elements ordered by sort. Respects {@link KeySpace} if present and therefore returns all elements that can - * be assigned to requested type. - * - * @param sort must not be {@literal null}. - * @param type must not be {@literal null}. - * @return - */ - List findAll(Sort sort, Class type); - - /** - * Get element of given type with given id. Respects {@link KeySpace} if present and therefore returns all elements - * that can be assigned to requested type. - * - * @param id must not be {@literal null}. - * @param type must not be {@literal null}. - * @return null if not found. - */ - T findById(Serializable id, Class type); - - /** - * Execute operation against underlying store. - * - * @param action must not be {@literal null}. - * @return - */ - T execute(KeyValueCallback action); - - /** - * Get all elements matching the given query.
- * Respects {@link KeySpace} if present and therefore returns all elements that can be assigned to requested type.. - * - * @param query must not be {@literal null}. - * @param type must not be {@literal null}. - * @return empty collection if no match found. - */ - List find(KeyValueQuery query, Class type); - - /** - * Get all elements in given range. Respects {@link KeySpace} if present and therefore returns all elements that can - * be assigned to requested type. - * - * @param offset - * @param rows - * @param type must not be {@literal null}. - * @return - */ - List findInRange(int offset, int rows, Class type); - - /** - * Get all elements in given range ordered by sort. Respects {@link KeySpace} if present and therefore returns all - * elements that can be assigned to requested type. - * - * @param offset - * @param rows - * @param sort - * @param type - * @return - */ - List findInRange(int offset, int rows, Sort sort, Class type); - - /** - * @param objectToUpdate must not be {@literal null}. - */ - void update(Object objectToUpdate); - - /** - * @param id must not be {@literal null}. - * @param objectToUpdate must not be {@literal null}. - */ - void update(Serializable id, Object objectToUpdate); - - /** - * Remove all elements of type. Respects {@link KeySpace} if present and therefore removes all elements that can be - * assigned to requested type. - * - * @param type must not be {@literal null}. - */ - void delete(Class type); - - /** - * @param objectToDelete must not be {@literal null}. - * @return - */ - T delete(T objectToDelete); - - /** - * Delete item of type with given id. - * - * @param id must not be {@literal null}. - * @param type must not be {@literal null}. - * @return the deleted item or {@literal null} if no match found. - */ - T delete(Serializable id, Class type); - - /** - * Total number of elements with given type available. Respects {@link KeySpace} if present and therefore counts all - * elements that can be assigned to requested type. - * - * @param type must not be {@literal null}. - * @return - */ - long count(Class type); - - /** - * Total number of elements matching given query. Respects {@link KeySpace} if present and therefore counts all - * elements that can be assigned to requested type. - * - * @param query - * @param type - * @return - */ - long count(KeyValueQuery query, Class type); - - /** - * @return mapping context in use. - */ - MappingContext getMappingContext(); -} diff --git a/src/main/java/org/springframework/data/keyvalue/core/KeyValuePersistenceExceptionTranslator.java b/src/main/java/org/springframework/data/keyvalue/core/KeyValuePersistenceExceptionTranslator.java deleted file mode 100644 index 5a5ed663b..000000000 --- a/src/main/java/org/springframework/data/keyvalue/core/KeyValuePersistenceExceptionTranslator.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2014 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 java.util.NoSuchElementException; - -import org.springframework.dao.DataAccessException; -import org.springframework.dao.DataRetrievalFailureException; -import org.springframework.dao.support.PersistenceExceptionTranslator; - -/** - * Simple {@link PersistenceExceptionTranslator} implementation for key/value stores that converts the given runtime - * exception to an appropriate exception from the {@code org.springframework.dao} hierarchy. - * - * @author Christoph Strobl - * @since 1.10 - */ -public class KeyValuePersistenceExceptionTranslator implements PersistenceExceptionTranslator { - - /* - * (non-Javadoc) - * @see org.springframework.dao.support.PersistenceExceptionTranslator#translateExceptionIfPossible(java.lang.RuntimeException) - */ - @Override - public DataAccessException translateExceptionIfPossible(RuntimeException e) { - - if (e == null || e instanceof DataAccessException) { - return (DataAccessException) e; - } - - if (e instanceof NoSuchElementException || e instanceof IndexOutOfBoundsException - || e instanceof IllegalStateException) { - return new DataRetrievalFailureException(e.getMessage(), e); - } - - if (e.getClass().getName().startsWith("java")) { - return new UncategorizedKeyValueException(e.getMessage(), e); - } - return null; - } -} diff --git a/src/main/java/org/springframework/data/keyvalue/core/KeyValueTemplate.java b/src/main/java/org/springframework/data/keyvalue/core/KeyValueTemplate.java deleted file mode 100644 index 331c27019..000000000 --- a/src/main/java/org/springframework/data/keyvalue/core/KeyValueTemplate.java +++ /dev/null @@ -1,452 +0,0 @@ -/* - * Copyright 2014 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 static org.springframework.data.keyvalue.core.KeySpaceUtils.*; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.concurrent.ConcurrentHashMap; - -import org.springframework.dao.DataAccessException; -import org.springframework.dao.InvalidDataAccessApiUsageException; -import org.springframework.dao.support.PersistenceExceptionTranslator; -import org.springframework.data.domain.Sort; -import org.springframework.data.keyvalue.core.mapping.context.KeyValueMappingContext; -import org.springframework.data.keyvalue.core.query.KeyValueQuery; -import org.springframework.data.mapping.PersistentEntity; -import org.springframework.data.mapping.PersistentProperty; -import org.springframework.data.mapping.context.MappingContext; -import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; -import org.springframework.util.StringUtils; - -/** - * Basic implementation of {@link KeyValueOperations}. - * - * @author Christoph Strobl - * @author Oliver Gierke - * @since 1.10 - */ -public class KeyValueTemplate implements KeyValueOperations { - - private static final PersistenceExceptionTranslator DEFAULT_PERSISTENCE_EXCEPTION_TRANSLATOR = new KeyValuePersistenceExceptionTranslator(); - - private final KeyValueAdapter adapter; - private final ConcurrentHashMap, String> keySpaceCache = new ConcurrentHashMap, String>(); - private final MappingContext>, ? extends PersistentProperty> mappingContext; - private final IdentifierGenerator identifierGenerator; - private PersistenceExceptionTranslator exceptionTranslator = DEFAULT_PERSISTENCE_EXCEPTION_TRANSLATOR; - - /** - * Create new {@link KeyValueTemplate} using the given {@link KeyValueAdapter} with a default - * {@link KeyValueMappingContext}. - * - * @param adapter must not be {@literal null}. - */ - public KeyValueTemplate(KeyValueAdapter adapter) { - this(adapter, new KeyValueMappingContext()); - } - - /** - * Create new {@link KeyValueTemplate} using the given {@link KeyValueAdapter} and {@link MappingContext}. - * - * @param adapter must not be {@literal null}. - * @param mappingContext must not be {@literal null}. - */ - @SuppressWarnings("rawtypes") - public KeyValueTemplate( - KeyValueAdapter adapter, - MappingContext, ? extends PersistentProperty> mappingContext) { - - Assert.notNull(adapter, "Adapter must not be null!"); - Assert.notNull(mappingContext, "MappingContext must not be null!"); - - this.adapter = adapter; - this.mappingContext = mappingContext; - this.identifierGenerator = DefaultIdentifierGenerator.INSTANCE; - } - - /* - * (non-Javadoc) - * @see org.springframework.data.keyvalue.core.KeyValueOperations#insert(java.lang.Object) - */ - @Override - public T insert(T objectToInsert) { - - PersistentEntity entity = this.mappingContext.getPersistentEntity(ClassUtils.getUserClass(objectToInsert)); - - GeneratingIdAccessor generatingIdAccessor = new GeneratingIdAccessor(entity.getPropertyAccessor(objectToInsert), - entity.getIdProperty(), identifierGenerator); - Object id = generatingIdAccessor.getOrGenerateIdentifier(); - - insert((Serializable) id, objectToInsert); - return objectToInsert; - } - - /* - * (non-Javadoc) - * @see org.springframework.data.keyvalue.core.KeyValueOperations#insert(java.io.Serializable, java.lang.Object) - */ - @Override - public void insert(final Serializable id, final Object objectToInsert) { - - Assert.notNull(id, "Id for object to be inserted must not be null!"); - Assert.notNull(objectToInsert, "Object to be inserted must not be null!"); - - execute(new KeyValueCallback() { - - @Override - public Void doInKeyValue(KeyValueAdapter adapter) { - - String typeKey = resolveKeySpace(objectToInsert.getClass()); - - if (adapter.contains(id, typeKey)) { - throw new InvalidDataAccessApiUsageException("Cannot insert existing object. Please use update."); - } - - adapter.put(id, objectToInsert, typeKey); - return null; - } - }); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.keyvalue.core.KeyValueOperations#update(java.lang.Object) - */ - @SuppressWarnings("rawtypes") - @Override - public void update(Object objectToUpdate) { - - PersistentEntity entity = this.mappingContext.getPersistentEntity(ClassUtils - .getUserClass(objectToUpdate)); - - if (!entity.hasIdProperty()) { - throw new InvalidDataAccessApiUsageException(String.format("Cannot determine id for type %s", - ClassUtils.getUserClass(objectToUpdate))); - } - - update((Serializable) entity.getIdentifierAccessor(objectToUpdate).getIdentifier(), objectToUpdate); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.keyvalue.core.KeyValueOperations#update(java.io.Serializable, java.lang.Object) - */ - @Override - public void update(final Serializable id, final Object objectToUpdate) { - - Assert.notNull(id, "Id for object to be inserted must not be null!"); - Assert.notNull(objectToUpdate, "Object to be updated must not be null!"); - - execute(new KeyValueCallback() { - - @Override - public Void doInKeyValue(KeyValueAdapter adapter) { - adapter.put(id, objectToUpdate, resolveKeySpace(objectToUpdate.getClass())); - return null; - } - }); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.keyvalue.core.KeyValueOperations#findAllOf(java.lang.Class) - */ - @Override - public List findAll(final Class type) { - - Assert.notNull(type, "Type to fetch must not be null!"); - - return execute(new KeyValueCallback>() { - - @SuppressWarnings("unchecked") - @Override - public List doInKeyValue(KeyValueAdapter adapter) { - - Collection x = adapter.getAllOf(resolveKeySpace(type)); - - if (getKeySpace(type) == null) { - return new ArrayList((Collection) x); - } - - ArrayList filtered = new ArrayList(); - for (Object candidate : x) { - if (typeCheck(type, candidate)) { - filtered.add((T) candidate); - } - } - - return filtered; - } - }); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.keyvalue.core.KeyValueOperations#findById(java.io.Serializable, java.lang.Class) - */ - @Override - public T findById(final Serializable id, final Class type) { - - Assert.notNull(id, "Id for object to be inserted must not be null!"); - Assert.notNull(type, "Type to fetch must not be null!"); - - return execute(new KeyValueCallback() { - - @SuppressWarnings("unchecked") - @Override - public T doInKeyValue(KeyValueAdapter adapter) { - - Object result = adapter.get(id, resolveKeySpace(type)); - - if (result == null || getKeySpace(type) == null || typeCheck(type, result)) { - return (T) result; - } - - return null; - } - }); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.keyvalue.core.KeyValueOperations#delete(java.lang.Class) - */ - @Override - public void delete(final Class type) { - - Assert.notNull(type, "Type to delete must not be null!"); - - final String typeKey = resolveKeySpace(type); - - execute(new KeyValueCallback() { - - @Override - public Void doInKeyValue(KeyValueAdapter adapter) { - - adapter.deleteAllOf(typeKey); - return null; - } - }); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.keyvalue.core.KeyValueOperations#delete(java.lang.Object) - */ - @SuppressWarnings({ "unchecked", "rawtypes" }) - @Override - public T delete(T objectToDelete) { - - Class type = (Class) ClassUtils.getUserClass(objectToDelete); - PersistentEntity entity = this.mappingContext.getPersistentEntity(type); - - return delete((Serializable) entity.getIdentifierAccessor(objectToDelete).getIdentifier(), type); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.keyvalue.core.KeyValueOperations#delete(java.io.Serializable, java.lang.Class) - */ - @Override - public T delete(final Serializable id, final Class type) { - - Assert.notNull(id, "Id for object to be inserted must not be null!"); - Assert.notNull(type, "Type to delete must not be null!"); - - return execute(new KeyValueCallback() { - - @SuppressWarnings("unchecked") - @Override - public T doInKeyValue(KeyValueAdapter adapter) { - return (T) adapter.delete(id, resolveKeySpace(type)); - } - }); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.keyvalue.core.KeyValueOperations#count(java.lang.Class) - */ - @Override - public long count(Class type) { - - Assert.notNull(type, "Type for count must not be null!"); - return findAll(type).size(); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.keyvalue.core.KeyValueOperations#execute(org.springframework.data.keyvalue.core.KeyValueCallback) - */ - @Override - public T execute(KeyValueCallback action) { - - Assert.notNull(action, "KeyValueCallback must not be null!"); - - try { - return action.doInKeyValue(this.adapter); - } catch (RuntimeException e) { - throw resolveExceptionIfPossible(e); - } - } - - /* - * (non-Javadoc) - * @see org.springframework.data.keyvalue.core.KeyValueOperations#find(org.springframework.data.keyvalue.core.query.KeyValueQuery, java.lang.Class) - */ - @Override - public List find(final KeyValueQuery query, final Class type) { - - return execute(new KeyValueCallback>() { - - @SuppressWarnings("unchecked") - @Override - public List doInKeyValue(KeyValueAdapter adapter) { - - Collection result = adapter.find(query, resolveKeySpace(type)); - - if (getKeySpace(type) == null) { - return new ArrayList((Collection) result); - } - - List filtered = new ArrayList(); - - for (Object candidate : result) { - if (typeCheck(type, candidate)) { - filtered.add((T) candidate); - } - } - - return filtered; - } - }); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.keyvalue.core.KeyValueOperations#findAllOf(org.springframework.data.domain.Sort, java.lang.Class) - */ - @SuppressWarnings("rawtypes") - @Override - public List findAll(Sort sort, Class type) { - return find(new KeyValueQuery(sort), type); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.keyvalue.core.KeyValueOperations#findInRange(int, int, java.lang.Class) - */ - @SuppressWarnings("rawtypes") - @Override - public List findInRange(int offset, int rows, Class type) { - return find(new KeyValueQuery().skip(offset).limit(rows), type); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.keyvalue.core.KeyValueOperations#findInRange(int, int, org.springframework.data.domain.Sort, java.lang.Class) - */ - @SuppressWarnings("rawtypes") - @Override - public List findInRange(int offset, int rows, Sort sort, Class type) { - return find(new KeyValueQuery(sort).skip(offset).limit(rows), type); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.keyvalue.core.KeyValueOperations#count(org.springframework.data.keyvalue.core.query.KeyValueQuery, java.lang.Class) - */ - @Override - public long count(final KeyValueQuery query, final Class type) { - - return execute(new KeyValueCallback() { - - @Override - public Long doInKeyValue(KeyValueAdapter adapter) { - return adapter.count(query, resolveKeySpace(type)); - } - }); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.keyvalue.core.KeyValueOperations#getMappingContext() - */ - @Override - public MappingContext getMappingContext() { - return this.mappingContext; - } - - /* - * (non-Javadoc) - * @see org.springframework.beans.factory.DisposableBean#destroy() - */ - @Override - public void destroy() throws Exception { - this.adapter.clear(); - } - - /** - * Set the {@link PersistenceExceptionTranslator} used for converting {@link RuntimeException}. - * - * @param exceptionTranslator must not be {@literal null}. - */ - public void setExceptionTranslator(PersistenceExceptionTranslator exceptionTranslator) { - - Assert.notNull(exceptionTranslator, "ExceptionTranslator must not be null."); - this.exceptionTranslator = exceptionTranslator; - } - - protected String resolveKeySpace(Class type) { - - Class userClass = ClassUtils.getUserClass(type); - - String potentialAlias = keySpaceCache.get(userClass); - - if (potentialAlias != null) { - return potentialAlias; - } - - 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 static boolean typeCheck(Class requiredType, Object candidate) { - return candidate == null ? true : ClassUtils.isAssignable(requiredType, candidate.getClass()); - } - - private RuntimeException resolveExceptionIfPossible(RuntimeException e) { - - DataAccessException translatedException = exceptionTranslator.translateExceptionIfPossible(e); - return translatedException != null ? translatedException : e; - } -} diff --git a/src/main/java/org/springframework/data/keyvalue/core/QueryEngine.java b/src/main/java/org/springframework/data/keyvalue/core/QueryEngine.java deleted file mode 100644 index eea66798e..000000000 --- a/src/main/java/org/springframework/data/keyvalue/core/QueryEngine.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright 2014 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 java.io.Serializable; -import java.util.Collection; - -import org.springframework.data.keyvalue.core.query.KeyValueQuery; - -/** - * Base implementation for accessing and executing {@link KeyValueQuery} against a {@link KeyValueAdapter}. - * - * @author Christoph Strobl - * @since 1.10 - * @param - * @param - * @param - */ -public abstract class QueryEngine { - - private final CriteriaAccessor criteriaAccessor; - private final SortAccessor sortAccessor; - - private ADAPTER adapter; - - public QueryEngine(CriteriaAccessor criteriaAccessor, SortAccessor sortAccessor) { - - this.criteriaAccessor = criteriaAccessor; - this.sortAccessor = sortAccessor; - } - - /** - * Extract query attributes and delegate to concrete execution. - * - * @param query - * @param keyspace - * @return - */ - public Collection execute(KeyValueQuery query, Serializable keyspace) { - - CRITERIA criteria = this.criteriaAccessor != null ? this.criteriaAccessor.resolve(query) : null; - SORT sort = this.sortAccessor != null ? this.sortAccessor.resolve(query) : null; - - return execute(criteria, sort, query.getOffset(), query.getRows(), keyspace); - } - - /** - * Extract query attributes and delegate to concrete execution. - * - * @param query - * @param keyspace - * @return - */ - public long count(KeyValueQuery query, Serializable keyspace) { - - CRITERIA criteria = this.criteriaAccessor != null ? this.criteriaAccessor.resolve(query) : null; - return count(criteria, keyspace); - } - - /** - * @param criteria - * @param sort - * @param offset - * @param rows - * @param keyspace - * @return - */ - public abstract Collection execute(CRITERIA criteria, SORT sort, int offset, int rows, Serializable keyspace); - - /** - * @param criteria - * @param keyspace - * @return - */ - public abstract long count(CRITERIA criteria, Serializable keyspace); - - /** - * Get the {@link KeyValueAdapter} used. - * - * @return - */ - protected ADAPTER getAdapter() { - return this.adapter; - } - - /** - * @param adapter - */ - @SuppressWarnings("unchecked") - public void registerAdapter(KeyValueAdapter adapter) { - - if (this.adapter == null) { - this.adapter = (ADAPTER) adapter; - } else { - throw new IllegalArgumentException("Cannot register more than one adapter for this QueryEngine."); - } - } -} diff --git a/src/main/java/org/springframework/data/keyvalue/core/SortAccessor.java b/src/main/java/org/springframework/data/keyvalue/core/SortAccessor.java deleted file mode 100644 index 363dd4d44..000000000 --- a/src/main/java/org/springframework/data/keyvalue/core/SortAccessor.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2014 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.data.domain.Sort; -import org.springframework.data.keyvalue.core.query.KeyValueQuery; - -/** - * Resolves the {@link Sort} object from given {@link KeyValueQuery} and potentially converts it into a store specific - * representation that can be used by the {@link QueryEngine} implementation. - * - * @author Christoph Strobl - * @since 1.10 - * @param - */ -public interface SortAccessor { - - /** - * Reads {@link KeyValueQuery#getSort()} of given {@link KeyValueQuery} and applies required transformation to match - * the desired type. - * - * @param query can be {@literal null}. - * @return {@literal null} in case {@link Sort} has not been defined on {@link KeyValueQuery}. - */ - T resolve(KeyValueQuery query); -} diff --git a/src/main/java/org/springframework/data/keyvalue/core/SpelCriteriaAccessor.java b/src/main/java/org/springframework/data/keyvalue/core/SpelCriteriaAccessor.java deleted file mode 100644 index 9da2d713f..000000000 --- a/src/main/java/org/springframework/data/keyvalue/core/SpelCriteriaAccessor.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2014 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.data.keyvalue.core.query.KeyValueQuery; -import org.springframework.expression.spel.standard.SpelExpression; -import org.springframework.expression.spel.standard.SpelExpressionParser; -import org.springframework.util.Assert; - -/** - * {@link CriteriaAccessor} implementation capable of {@link SpelExpression}s. - * - * @author Christoph Strobl - * @author Oliver Gierke - * @since 1.10 - */ -class SpelCriteriaAccessor implements CriteriaAccessor { - - private final SpelExpressionParser parser; - - /** - * @param parser must not be {@literal null}. - */ - public SpelCriteriaAccessor(SpelExpressionParser parser) { - - Assert.notNull(parser, "SpelExpressionParser must not be null!"); - this.parser = parser; - } - - @Override - public SpelExpression resolve(KeyValueQuery query) { - - if (query.getCritieria() == null) { - return null; - } - - if (query.getCritieria() instanceof SpelExpression) { - return (SpelExpression) query.getCritieria(); - } - - if (query.getCritieria() instanceof String) { - return parser.parseRaw((String) query.getCritieria()); - } - - throw new IllegalArgumentException("Cannot create SpelCriteria for " + query.getCritieria()); - } -} diff --git a/src/main/java/org/springframework/data/keyvalue/core/SpelPropertyComparator.java b/src/main/java/org/springframework/data/keyvalue/core/SpelPropertyComparator.java deleted file mode 100644 index b1458600a..000000000 --- a/src/main/java/org/springframework/data/keyvalue/core/SpelPropertyComparator.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright 2014 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 java.util.Comparator; - -import org.springframework.expression.spel.standard.SpelExpression; -import org.springframework.expression.spel.standard.SpelExpressionParser; - -/** - * {@link Comparator} implementation using {@link SpelExpression}. - * - * @author Christoph Strobl - * @author Oliver Gierke - * @since 1.10 - * @param - */ -public class SpelPropertyComparator implements Comparator { - - private final String path; - private final SpelExpressionParser parser; - - private boolean asc = true; - private boolean nullsFirst = true; - private SpelExpression expression; - - /** - * Create new {@link SpelPropertyComparator} for the given property path an {@link SpelExpressionParser}.. - * - * @param path must not be {@literal null} or empty. - * @param parser must not be {@literal null}. - */ - public SpelPropertyComparator(String path, SpelExpressionParser parser) { - - this.path = path; - this.parser = parser; - } - - /** - * Sort {@literal ascending}. - * - * @return - */ - public SpelPropertyComparator asc() { - this.asc = true; - return this; - } - - /** - * Sort {@literal descending}. - * - * @return - */ - public SpelPropertyComparator desc() { - this.asc = false; - return this; - } - - /** - * Sort {@literal null} values first. - * - * @return - */ - public SpelPropertyComparator nullsFirst() { - this.nullsFirst = true; - return this; - } - - /** - * Sort {@literal null} values last. - * - * @return - */ - public SpelPropertyComparator nullsLast() { - this.nullsFirst = false; - return this; - } - - /** - * Parse values to {@link SpelExpression} - * - * @return - */ - protected SpelExpression getExpression() { - - if (this.expression == null) { - this.expression = parser.parseRaw(buildExpressionForPath()); - } - - return this.expression; - } - - /** - * Create the expression raw value. - * - * @return - */ - protected String buildExpressionForPath() { - - StringBuilder rawExpression = new StringBuilder( - "new org.springframework.util.comparator.NullSafeComparator(new org.springframework.util.comparator.ComparableComparator(), " - + Boolean.toString(this.nullsFirst) + ").compare("); - - rawExpression.append("#arg1?."); - rawExpression.append(path != null ? path.replace(".", "?.") : ""); - rawExpression.append(","); - rawExpression.append("#arg2?."); - rawExpression.append(path != null ? path.replace(".", "?.") : ""); - rawExpression.append(")"); - - return rawExpression.toString(); - } - - /* - * (non-Javadoc) - * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object) - */ - @Override - public int compare(T arg1, T arg2) { - - SpelExpression expressionToUse = getExpression(); - - expressionToUse.getEvaluationContext().setVariable("arg1", arg1); - expressionToUse.getEvaluationContext().setVariable("arg2", arg2); - - return expressionToUse.getValue(Integer.class) * (asc ? 1 : -1); - } - - /** - * Get dot path to property. - * - * @return - */ - public String getPath() { - return path; - } -} diff --git a/src/main/java/org/springframework/data/keyvalue/core/SpelQueryEngine.java b/src/main/java/org/springframework/data/keyvalue/core/SpelQueryEngine.java deleted file mode 100644 index bc5cd76bc..000000000 --- a/src/main/java/org/springframework/data/keyvalue/core/SpelQueryEngine.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright 2014 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 java.io.Serializable; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; - -import org.springframework.data.keyvalue.core.query.KeyValueQuery; -import org.springframework.expression.spel.SpelEvaluationException; -import org.springframework.expression.spel.standard.SpelExpression; -import org.springframework.expression.spel.standard.SpelExpressionParser; - -/** - * {@link QueryEngine} implementation specific for executing {@link SpelExpression} based {@link KeyValueQuery} against - * {@link KeyValueAdapter}. - * - * @author Christoph Strobl - * @author Oliver Gierke - * @since 1.10 - * @param - */ -class SpelQueryEngine extends QueryEngine> { - - private static final SpelExpressionParser PARSER = new SpelExpressionParser(); - - /** - * Creates a new {@link SpelQueryEngine}. - */ - public SpelQueryEngine() { - super(new SpelCriteriaAccessor(PARSER), new SpelSortAccessor(PARSER)); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.keyvalue.core.QueryEngine#execute(java.lang.Object, java.lang.Object, int, int, java.io.Serializable) - */ - @Override - public Collection execute(SpelExpression criteria, Comparator sort, int offset, int rows, Serializable keyspace) { - return sortAndFilterMatchingRange(getAdapter().getAllOf(keyspace), criteria, sort, offset, rows); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.keyvalue.core.QueryEngine#count(java.lang.Object, java.io.Serializable) - */ - @Override - public long count(SpelExpression criteria, Serializable keyspace) { - return filterMatchingRange(getAdapter().getAllOf(keyspace), criteria, -1, -1).size(); - } - - @SuppressWarnings({ "unchecked" }) - private List sortAndFilterMatchingRange(Collection source, SpelExpression criteria, Comparator sort, - int offset, int rows) { - - List tmp = new ArrayList(source); - if (sort != null) { - Collections.sort(tmp, sort); - } - - return filterMatchingRange(tmp, criteria, offset, rows); - } - - private static List filterMatchingRange(Iterable source, SpelExpression criteria, int offset, int rows) { - - List result = new ArrayList(); - - boolean compareOffsetAndRows = 0 < offset || 0 <= rows; - int remainingRows = rows; - int curPos = 0; - - for (S candidate : source) { - - boolean matches = criteria == null; - - if (!matches) { - try { - matches = criteria.getValue(candidate, Boolean.class); - } catch (SpelEvaluationException e) { - criteria.getEvaluationContext().setVariable("it", candidate); - matches = criteria.getValue(Boolean.class); - } - } - - if (matches) { - if (compareOffsetAndRows) { - if (curPos >= offset && rows > 0) { - result.add(candidate); - remainingRows--; - if (remainingRows <= 0) { - break; - } - } - curPos++; - } else { - result.add(candidate); - } - } - } - - return result; - } -} diff --git a/src/main/java/org/springframework/data/keyvalue/core/SpelSortAccessor.java b/src/main/java/org/springframework/data/keyvalue/core/SpelSortAccessor.java deleted file mode 100644 index 3f4a419ef..000000000 --- a/src/main/java/org/springframework/data/keyvalue/core/SpelSortAccessor.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2014 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 java.util.Comparator; - -import org.springframework.data.domain.Sort.Direction; -import org.springframework.data.domain.Sort.NullHandling; -import org.springframework.data.domain.Sort.Order; -import org.springframework.data.keyvalue.core.query.KeyValueQuery; -import org.springframework.expression.spel.standard.SpelExpressionParser; -import org.springframework.util.Assert; -import org.springframework.util.comparator.CompoundComparator; - -/** - * {@link SortAccessor} implementation capable of creating {@link SpelPropertyComparator}. - * - * @author Christoph Strobl - * @author Oliver Gierke - * @since 1.10 - */ -class SpelSortAccessor implements SortAccessor> { - - private final SpelExpressionParser parser; - - /** - * @param parser must not be {@literal null}. - */ - public SpelSortAccessor(SpelExpressionParser parser) { - - Assert.notNull(parser, "SpelExpressionParser must not be null!"); - this.parser = parser; - } - - /* - * (non-Javadoc) - * @see org.springframework.data.keyvalue.core.SortAccessor#resolve(org.springframework.data.keyvalue.core.query.KeyValueQuery) - */ - @SuppressWarnings({ "rawtypes", "unchecked" }) - @Override - public Comparator resolve(KeyValueQuery query) { - - if (query == null || query.getSort() == null) { - return null; - } - - CompoundComparator compoundComperator = new CompoundComparator(); - for (Order order : query.getSort()) { - - SpelPropertyComparator spelSort = new SpelPropertyComparator(order.getProperty(), parser); - - if (Direction.DESC.equals(order.getDirection())) { - - spelSort.desc(); - - if (order.getNullHandling() != null && !NullHandling.NATIVE.equals(order.getNullHandling())) { - spelSort = NullHandling.NULLS_FIRST.equals(order.getNullHandling()) ? spelSort.nullsFirst() : spelSort - .nullsLast(); - } - } - compoundComperator.addComparator(spelSort); - } - - return compoundComperator; - } -} diff --git a/src/main/java/org/springframework/data/keyvalue/core/UncategorizedKeyValueException.java b/src/main/java/org/springframework/data/keyvalue/core/UncategorizedKeyValueException.java deleted file mode 100644 index 47df71324..000000000 --- a/src/main/java/org/springframework/data/keyvalue/core/UncategorizedKeyValueException.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2014 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.dao.UncategorizedDataAccessException; - -/** - * @author Christoph Strobl - * @since 1.10 - */ -public class UncategorizedKeyValueException extends UncategorizedDataAccessException { - - private static final long serialVersionUID = -8087116071859122297L; - - public UncategorizedKeyValueException(String msg, Throwable cause) { - super(msg, cause); - } -} diff --git a/src/main/java/org/springframework/data/keyvalue/core/mapping/KeyValuePersistentProperty.java b/src/main/java/org/springframework/data/keyvalue/core/mapping/KeyValuePersistentProperty.java deleted file mode 100644 index 453b0013b..000000000 --- a/src/main/java/org/springframework/data/keyvalue/core/mapping/KeyValuePersistentProperty.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2014 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 java.beans.PropertyDescriptor; -import java.lang.reflect.Field; - -import org.springframework.data.mapping.Association; -import org.springframework.data.mapping.PersistentEntity; -import org.springframework.data.mapping.PersistentProperty; -import org.springframework.data.mapping.model.AnnotationBasedPersistentProperty; -import org.springframework.data.mapping.model.SimpleTypeHolder; - -/** - * Most trivial implementation of {@link PersistentProperty}. - * - * @author Christoph Strobl - * @since 1.10 - */ -public class KeyValuePersistentProperty extends AnnotationBasedPersistentProperty { - - public KeyValuePersistentProperty(Field field, PropertyDescriptor propertyDescriptor, - PersistentEntity owner, SimpleTypeHolder simpleTypeHolder) { - super(field, propertyDescriptor, owner, simpleTypeHolder); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.mapping.model.AbstractPersistentProperty#createAssociation() - */ - @Override - protected Association createAssociation() { - return new Association(this, null); - } -} diff --git a/src/main/java/org/springframework/data/keyvalue/core/mapping/context/KeyValueMappingContext.java b/src/main/java/org/springframework/data/keyvalue/core/mapping/context/KeyValueMappingContext.java deleted file mode 100644 index f3266fed2..000000000 --- a/src/main/java/org/springframework/data/keyvalue/core/mapping/context/KeyValueMappingContext.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2014 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.context; - -import java.beans.PropertyDescriptor; -import java.lang.reflect.Field; - -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.model.SimpleTypeHolder; -import org.springframework.data.util.TypeInformation; - -/** - * @author Christoph Strobl - * @since 1.10 - */ -public class KeyValueMappingContext extends - AbstractMappingContext, KeyValuePersistentProperty> { - - /* - * (non-Javadoc) - * @see org.springframework.data.mapping.context.AbstractMappingContext#createPersistentEntity(org.springframework.data.util.TypeInformation) - */ - @Override - protected BasicPersistentEntity createPersistentEntity( - TypeInformation typeInformation) { - return new BasicPersistentEntity(typeInformation); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.mapping.context.AbstractMappingContext#createPersistentProperty(java.lang.reflect.Field, java.beans.PropertyDescriptor, org.springframework.data.mapping.model.MutablePersistentEntity, org.springframework.data.mapping.model.SimpleTypeHolder) - */ - @Override - protected KeyValuePersistentProperty createPersistentProperty(Field field, PropertyDescriptor descriptor, - BasicPersistentEntity owner, SimpleTypeHolder simpleTypeHolder) { - return new KeyValuePersistentProperty(field, descriptor, owner, simpleTypeHolder); - } -} diff --git a/src/main/java/org/springframework/data/keyvalue/core/query/KeyValueQuery.java b/src/main/java/org/springframework/data/keyvalue/core/query/KeyValueQuery.java deleted file mode 100644 index 79d683efc..000000000 --- a/src/main/java/org/springframework/data/keyvalue/core/query/KeyValueQuery.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright 2014 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.query; - -import org.springframework.data.domain.Sort; - -/** - * @author Christoph Strobl - * @since 1.10 - * @param Criteria type - */ -public class KeyValueQuery { - - private Sort sort; - private int offset = -1; - private int rows = -1; - private T criteria; - - /** - * Creates new instance of {@link KeyValueQuery}. - */ - public KeyValueQuery() {} - - /** - * Creates new instance of {@link KeyValueQuery} with given criteria. - * - * @param criteria can be {@literal null}. - */ - public KeyValueQuery(T criteria) { - this.criteria = criteria; - } - - /** - * Creates new instance of {@link KeyValueQuery} with given {@link Sort}. - * - * @param sort can be {@literal null}. - */ - public KeyValueQuery(Sort sort) { - this.sort = sort; - } - - /** - * Get the criteria object. - * - * @return - */ - public T getCritieria() { - return criteria; - } - - /** - * Get {@link Sort}. - * - * @return - */ - public Sort getSort() { - return sort; - } - - /** - * Number of elements to skip. - * - * @return negative value if not set. - */ - public int getOffset() { - return this.offset; - } - - /** - * Number of elements to read. - * - * @return negative value if not set. - */ - public int getRows() { - return this.rows; - } - - /** - * Set the number of elements to skip. - * - * @param offset use negative value for none. - */ - public void setOffset(int offset) { - this.offset = offset; - } - - /** - * Set the number of elements to read. - * - * @param offset use negative value for all. - */ - public void setRows(int rows) { - this.rows = rows; - } - - /** - * Set {@link Sort} to be applied. - * - * @param sort - */ - public void setSort(Sort sort) { - this.sort = sort; - } - - /** - * Add given {@link Sort}. - * - * @param sort {@literal null} {@link Sort} will be ignored. - * @return - */ - public KeyValueQuery orderBy(Sort sort) { - - if (sort == null) { - return this; - } - - if (this.sort != null) { - this.sort.and(sort); - } else { - this.sort = sort; - } - return this; - } - - /** - * @see KeyValueQuery#setOffset(int) - * @param offset - * @return - */ - public KeyValueQuery skip(int offset) { - setOffset(offset); - return this; - } - - /** - * @see KeyValueQuery#setRows(int) - * @param rows - * @return - */ - public KeyValueQuery limit(int rows) { - setRows(rows); - return this; - } - -} diff --git a/src/main/java/org/springframework/data/keyvalue/map/MapKeyValueAdapter.java b/src/main/java/org/springframework/data/keyvalue/map/MapKeyValueAdapter.java deleted file mode 100644 index b55efc213..000000000 --- a/src/main/java/org/springframework/data/keyvalue/map/MapKeyValueAdapter.java +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright 2014 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.map; - -import java.io.Serializable; -import java.util.Collection; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import org.springframework.core.CollectionFactory; -import org.springframework.data.keyvalue.core.AbstractKeyValueAdapter; -import org.springframework.data.keyvalue.core.KeyValueAdapter; -import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; - -/** - * {@link KeyValueAdapter} implementation for {@link Map}. - * - * @author Christoph Strobl - * @since 1.10 - */ -public class MapKeyValueAdapter extends AbstractKeyValueAdapter { - - private final Map> data; - - @SuppressWarnings("rawtypes")// - private final Class mapType; - - /** - * Create new instance of {@link MapKeyValueAdapter} using {@link ConcurrentHashMap}. - */ - public MapKeyValueAdapter() { - this(new ConcurrentHashMap>()); - } - - /** - * Create new instance of {@link MapKeyValueAdapter} using given dataStore for persistence. - * - * @param dataStore must not be {@literal null}. - */ - @SuppressWarnings({ "rawtypes", "unchecked" }) - public MapKeyValueAdapter(Map> dataStore) { - - Assert.notNull(dataStore, "Cannot initilalize adapter with 'null' datastore."); - - this.data = dataStore; - this.mapType = (Class) ClassUtils.getUserClass(dataStore); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.keyvalue.core.KeyValueAdapter#put(java.io.Serializable, java.lang.Object, java.io.Serializable) - */ - @Override - public Object put(Serializable id, Object item, Serializable keyspace) { - - Assert.notNull(id, "Cannot add item with 'null' id."); - Assert.notNull(keyspace, "Cannot add item for 'null' collection."); - - return getKeySpaceMap(keyspace).put(id, item); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.keyvalue.core.KeyValueAdapter#contains(java.io.Serializable, java.io.Serializable) - */ - @Override - public boolean contains(Serializable id, Serializable keyspace) { - return get(id, keyspace) != null; - } - - /* - * (non-Javadoc) - * @see org.springframework.data.keyvalue.core.KeyValueAdapter#get(java.io.Serializable, java.io.Serializable) - */ - @Override - public Object get(Serializable id, Serializable keyspace) { - - Assert.notNull(id, "Cannot get item with 'null' id."); - return getKeySpaceMap(keyspace).get(id); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.keyvalue.core.KeyValueAdapter#delete(java.io.Serializable, java.io.Serializable) - */ - @Override - public Object delete(Serializable id, Serializable keyspace) { - - Assert.notNull(id, "Cannot delete item with 'null' id."); - return getKeySpaceMap(keyspace).remove(id); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.keyvalue.core.KeyValueAdapter#getAllOf(java.io.Serializable) - */ - @Override - public Collection getAllOf(Serializable keyspace) { - return getKeySpaceMap(keyspace).values(); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.keyvalue.core.KeyValueAdapter#deleteAllOf(java.io.Serializable) - */ - @Override - public void deleteAllOf(Serializable keyspace) { - getKeySpaceMap(keyspace).clear(); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.keyvalue.core.KeyValueAdapter#clear() - */ - @Override - public void clear() { - data.clear(); - } - - /* - * (non-Javadoc) - * @see org.springframework.beans.factory.DisposableBean#destroy() - */ - @Override - public void destroy() throws Exception { - clear(); - } - - /** - * Get map associated with given keyspace. - * - * @param keyspace must not be {@literal null}. - * @return - */ - protected Map getKeySpaceMap(Serializable keyspace) { - - Assert.notNull(keyspace, "Collection must not be 'null' for lookup."); - - Map map = data.get(keyspace); - - if (map != null) { - return map; - } - - addMapForKeySpace(keyspace); - return data.get(keyspace); - } - - private void addMapForKeySpace(Serializable keyspace) { - data.put(keyspace, CollectionFactory. createMap(mapType, 1000)); - } -} diff --git a/src/main/java/org/springframework/data/keyvalue/map/MapKeyValueAdapterFactory.java b/src/main/java/org/springframework/data/keyvalue/map/MapKeyValueAdapterFactory.java deleted file mode 100644 index 6a97c7232..000000000 --- a/src/main/java/org/springframework/data/keyvalue/map/MapKeyValueAdapterFactory.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright 2014 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.map; - -import java.io.Serializable; -import java.util.HashMap; -import java.util.Map; -import java.util.Map.Entry; -import java.util.concurrent.ConcurrentHashMap; - -import org.springframework.core.CollectionFactory; -import org.springframework.util.Assert; - -/** - * @author Christoph Strobl - * @since 1.10 - */ -public class MapKeyValueAdapterFactory { - - @SuppressWarnings("rawtypes")// - private static final Class DEFAULT_MAP_TYPE = ConcurrentHashMap.class; - - @SuppressWarnings("rawtypes")// - private Class mapType; - private Map> initialValues; - - /** - * Creates a new {@link MapKeyValueAdapterFactory}. - * - * @see MapKeyValueAdapterFactory#MapKeyValueAdapterFactory(Class) - */ - public MapKeyValueAdapterFactory() { - this(null); - } - - /** - * Creates a new MKVAF with the given {@link Map} type to be used to hold the values in. - * - * @param type any {@link Class} of type {@link Map}. Can be {@literal null} and will be defaulted to - * {@link ConcurrentHashMap}. - */ - @SuppressWarnings("rawtypes") - public MapKeyValueAdapterFactory(Class type) { - - this.mapType = type; - this.initialValues = new HashMap>(); - } - - /** - * Set values for a given {@literal keyspace} that to populate the adapter after creation. - * - * @param keyspace must not be {@literal null}. - * @param values must not be {@literal null}. - */ - public void setInitialValuesForKeyspace(Serializable keyspace, Map values) { - - Assert.notNull(keyspace, "KeySpace must not be null!"); - Assert.notNull(values, "Values must not be null!"); - - initialValues.put(keyspace, values); - } - - /** - * Configures the {@link Map} type to be used as backing store. - * - * @param mapType must not be {@literal null}. - */ - @SuppressWarnings("rawtypes") - public void setMapType(Class mapType) { - - Assert.notNull(mapType, "May type must not be null!"); - - this.mapType = mapType; - } - - /** - * Creates and populates the adapter. - * - * @return - */ - public MapKeyValueAdapter getAdapter() { - - MapKeyValueAdapter adapter = createAdapter(); - populateAdapter(adapter); - - return adapter; - } - - private MapKeyValueAdapter createAdapter() { - - Class type = this.mapType == null ? DEFAULT_MAP_TYPE : this.mapType; - - MapKeyValueAdapter adapter = new MapKeyValueAdapter( - CollectionFactory.> createMap(type, 100)); - return adapter; - } - - private void populateAdapter(MapKeyValueAdapter adapter) { - - if (!initialValues.isEmpty()) { - for (Entry> entry : initialValues.entrySet()) { - for (Entry obj : entry.getValue().entrySet()) { - adapter.put(obj.getKey(), obj.getValue(), entry.getKey()); - } - } - } - } -} diff --git a/src/main/java/org/springframework/data/keyvalue/repository/KeyValueRepository.java b/src/main/java/org/springframework/data/keyvalue/repository/KeyValueRepository.java deleted file mode 100644 index 2a703948d..000000000 --- a/src/main/java/org/springframework/data/keyvalue/repository/KeyValueRepository.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2014 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.repository; - -import java.io.Serializable; - -import org.springframework.data.repository.PagingAndSortingRepository; - -/** - * @author Christoph Strobl - * @since 1.10 - * @param - * @param - */ -public interface KeyValueRepository extends PagingAndSortingRepository { - -} diff --git a/src/main/java/org/springframework/data/keyvalue/repository/config/EnableKeyValueRepositories.java b/src/main/java/org/springframework/data/keyvalue/repository/config/EnableKeyValueRepositories.java deleted file mode 100644 index 1b32a7894..000000000 --- a/src/main/java/org/springframework/data/keyvalue/repository/config/EnableKeyValueRepositories.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright 2014 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.repository.config; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Inherited; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.springframework.beans.factory.FactoryBean; -import org.springframework.context.annotation.ComponentScan.Filter; -import org.springframework.context.annotation.Import; -import org.springframework.data.keyvalue.core.KeyValueOperations; -import org.springframework.data.keyvalue.repository.query.SpelQueryCreator; -import org.springframework.data.keyvalue.repository.support.KeyValueRepositoryFactoryBean; -import org.springframework.data.repository.query.QueryLookupStrategy; -import org.springframework.data.repository.query.QueryLookupStrategy.Key; - -/** - * Annotation to activate KeyValue repositories. If no base package is configured through either {@link #value()}, - * {@link #basePackages()} or {@link #basePackageClasses()} it will trigger scanning of the package of annotated class. - * - * @author Christoph Strobl - * @since 1.10 - */ -@Target({ ElementType.TYPE, ElementType.ANNOTATION_TYPE }) -@Retention(RetentionPolicy.RUNTIME) -@Documented -@Inherited -@Import(KeyValueRepositoriesRegistrar.class) -@QueryCreatorType(SpelQueryCreator.class) -public @interface EnableKeyValueRepositories { - - /** - * Alias for the {@link #basePackages()} attribute. Allows for more concise annotation declarations e.g.: - * {@code @EnableJpaRepositories("org.my.pkg")} instead of {@code @EnableJpaRepositories(basePackages="org.my.pkg")}. - */ - String[] value() default {}; - - /** - * Base packages to scan for annotated components. {@link #value()} is an alias for (and mutually exclusive with) this - * attribute. Use {@link #basePackageClasses()} for a type-safe alternative to String-based package names. - */ - String[] basePackages() default {}; - - /** - * Type-safe alternative to {@link #basePackages()} for specifying the packages to scan for annotated components. The - * package of each class specified will be scanned. Consider creating a special no-op marker class or interface in - * each package that serves no purpose other than being referenced by this attribute. - */ - Class[] basePackageClasses() default {}; - - /** - * Specifies which types are not eligible for component scanning. - */ - Filter[] excludeFilters() default {}; - - /** - * Specifies which types are eligible for component scanning. Further narrows the set of candidate components from - * everything in {@link #basePackages()} to everything in the base packages that matches the given filter or filters. - */ - Filter[] includeFilters() default {}; - - /** - * Returns the postfix to be used when looking up custom repository implementations. Defaults to {@literal Impl}. So - * for a repository named {@code PersonRepository} the corresponding implementation class will be looked up scanning - * for {@code PersonRepositoryImpl}. - * - * @return - */ - String repositoryImplementationPostfix() default "Impl"; - - /** - * Configures the location of where to find the Spring Data named queries properties file. - * - * @return - */ - String namedQueriesLocation() default ""; - - /** - * Returns the key of the {@link QueryLookupStrategy} to be used for lookup queries for query methods. Defaults to - * {@link Key#CREATE_IF_NOT_FOUND}. - * - * @return - */ - Key queryLookupStrategy() default Key.CREATE_IF_NOT_FOUND; - - /** - * Returns the {@link FactoryBean} class to be used for each repository instance. Defaults to - * {@link KeyValueRepositoryFactoryBean}. - * - * @return - */ - Class repositoryFactoryBeanClass() default KeyValueRepositoryFactoryBean.class; - - /** - * Configures the name of the {@link KeyValueOperations} bean to be used with the repositories detected. - * - * @return - */ - String keyValueTemplateRef() default "keyValueTemplate"; - - /** - * Configures whether nested repository-interfaces (e.g. defined as inner classes) should be discovered by the - * repositories infrastructure. - */ - boolean considerNestedRepositories() default false; -} diff --git a/src/main/java/org/springframework/data/keyvalue/repository/config/KeyValueRepositoriesRegistrar.java b/src/main/java/org/springframework/data/keyvalue/repository/config/KeyValueRepositoriesRegistrar.java deleted file mode 100644 index dba368914..000000000 --- a/src/main/java/org/springframework/data/keyvalue/repository/config/KeyValueRepositoriesRegistrar.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2014 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.repository.config; - -import java.lang.annotation.Annotation; - -import org.springframework.data.repository.config.RepositoryBeanDefinitionRegistrarSupport; -import org.springframework.data.repository.config.RepositoryConfigurationExtension; - -/** - * KeyValue specific {@link org.springframework.context.annotation.ImportBeanDefinitionRegistrar} - * - * @author Christoph Strobl - * @since 1.10 - */ -public class KeyValueRepositoriesRegistrar extends RepositoryBeanDefinitionRegistrarSupport { - - /* - * (non-Javadoc) - * @see org.springframework.data.repository.config.RepositoryBeanDefinitionRegistrarSupport#getAnnotation() - */ - @Override - protected Class getAnnotation() { - return EnableKeyValueRepositories.class; - } - - /* - * (non-Javadoc) - * @see org.springframework.data.repository.config.RepositoryBeanDefinitionRegistrarSupport#getExtension() - */ - @Override - protected RepositoryConfigurationExtension getExtension() { - return new KeyValueRepositoryConfigurationExtension(); - } -} diff --git a/src/main/java/org/springframework/data/keyvalue/repository/config/KeyValueRepositoryConfigurationExtension.java b/src/main/java/org/springframework/data/keyvalue/repository/config/KeyValueRepositoryConfigurationExtension.java deleted file mode 100644 index 4130c45b5..000000000 --- a/src/main/java/org/springframework/data/keyvalue/repository/config/KeyValueRepositoryConfigurationExtension.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright 2014 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.repository.config; - -import java.util.Collection; -import java.util.Collections; -import java.util.Map; - -import org.springframework.beans.factory.support.BeanDefinitionBuilder; -import org.springframework.beans.factory.support.BeanDefinitionRegistry; -import org.springframework.beans.factory.support.RootBeanDefinition; -import org.springframework.core.annotation.AnnotationAttributes; -import org.springframework.core.type.AnnotationMetadata; -import org.springframework.data.keyvalue.core.mapping.context.KeyValueMappingContext; -import org.springframework.data.keyvalue.repository.KeyValueRepository; -import org.springframework.data.keyvalue.repository.query.SpelQueryCreator; -import org.springframework.data.keyvalue.repository.support.KeyValueRepositoryFactoryBean; -import org.springframework.data.repository.config.AnnotationRepositoryConfigurationSource; -import org.springframework.data.repository.config.RepositoryConfigurationExtension; -import org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport; -import org.springframework.data.repository.config.RepositoryConfigurationSource; - -/** - * {@link RepositoryConfigurationExtension} for {@link KeyValueRepository}. - * - * @author Christoph Strobl - * @since 1.10 - */ -public class KeyValueRepositoryConfigurationExtension extends RepositoryConfigurationExtensionSupport { - - private static final String MAPPING_CONTEXT_BEAN_NAME = "keyValueMappingContext"; - - /* - * (non-Javadoc) - * @see org.springframework.data.repository.config.RepositoryConfigurationExtension#getRepositoryFactoryClassName() - */ - @Override - public String getRepositoryFactoryClassName() { - return KeyValueRepositoryFactoryBean.class.getName(); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport#getModuleName() - */ - @Override - public String getModuleName() { - return "KeyValue"; - } - - /* - * (non-Javadoc) - * @see org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport#getModulePrefix() - */ - @Override - protected String getModulePrefix() { - return "keyvalue"; - } - - /* - * (non-Javadoc) - * @see org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport#getIdentifyingTypes() - */ - @Override - protected Collection> getIdentifyingTypes() { - return Collections.> singleton(KeyValueRepository.class); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport#postProcess(org.springframework.beans.factory.support.BeanDefinitionBuilder, org.springframework.data.repository.config.AnnotationRepositoryConfigurationSource) - */ - @Override - public void postProcess(BeanDefinitionBuilder builder, AnnotationRepositoryConfigurationSource config) { - - AnnotationAttributes attributes = config.getAttributes(); - - builder.addPropertyReference("keyValueOperations", attributes.getString("keyValueTemplateRef")); - builder.addPropertyValue("queryCreator", getQueryCreatorType(config)); - builder.addPropertyReference("mappingContext", MAPPING_CONTEXT_BEAN_NAME); - } - - /** - * Detects the query creator type to be used for the factory to set. Will lookup a {@link QueryCreatorType} annotation - * on the {@code @Enable}-annotation or use {@link SpelQueryCreator} if not found. - * - * @param config - * @return - */ - private static Class getQueryCreatorType(AnnotationRepositoryConfigurationSource config) { - - AnnotationMetadata metadata = config.getEnableAnnotationMetadata(); - - Map queryCreatorFoo = metadata.getAnnotationAttributes(QueryCreatorType.class.getName()); - - if (queryCreatorFoo == null) { - return SpelQueryCreator.class; - } - - AnnotationAttributes queryCreatorAttributes = new AnnotationAttributes(queryCreatorFoo); - return queryCreatorAttributes.getClass("value"); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport#registerBeansForRoot(org.springframework.beans.factory.support.BeanDefinitionRegistry, org.springframework.data.repository.config.RepositoryConfigurationSource) - */ - @Override - public void registerBeansForRoot(BeanDefinitionRegistry registry, RepositoryConfigurationSource configurationSource) { - - super.registerBeansForRoot(registry, configurationSource); - - if (!registry.containsBeanDefinition(MAPPING_CONTEXT_BEAN_NAME)) { - - RootBeanDefinition mappingContextDefinition = new RootBeanDefinition(KeyValueMappingContext.class); - mappingContextDefinition.setSource(configurationSource.getSource()); - registry.registerBeanDefinition(MAPPING_CONTEXT_BEAN_NAME, mappingContextDefinition); - } - } -} diff --git a/src/main/java/org/springframework/data/keyvalue/repository/config/QueryCreatorType.java b/src/main/java/org/springframework/data/keyvalue/repository/config/QueryCreatorType.java deleted file mode 100644 index 44b05a271..000000000 --- a/src/main/java/org/springframework/data/keyvalue/repository/config/QueryCreatorType.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2014 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.repository.config; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.springframework.data.repository.query.parser.AbstractQueryCreator; - -/** - * Annotation to customize the query creator type to be used for a specific store. - * - * @author Oliver Gierke - */ -@Documented -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.ANNOTATION_TYPE) -public @interface QueryCreatorType { - - Class> value(); -} diff --git a/src/main/java/org/springframework/data/keyvalue/repository/config/RepositoryNameSpaceHandler.java b/src/main/java/org/springframework/data/keyvalue/repository/config/RepositoryNameSpaceHandler.java deleted file mode 100644 index 6efd4a53b..000000000 --- a/src/main/java/org/springframework/data/keyvalue/repository/config/RepositoryNameSpaceHandler.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2012 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.repository.config; - -import org.springframework.beans.factory.xml.BeanDefinitionParser; -import org.springframework.beans.factory.xml.NamespaceHandler; -import org.springframework.beans.factory.xml.NamespaceHandlerSupport; -import org.springframework.data.repository.config.RepositoryBeanDefinitionParser; - -/** - * {@link NamespaceHandler} to register {@link BeanDefinitionParser}s for key-value repositories. - * - * @author Oliver Gierke - * @author Christoph Strobl - * @since 1.4 - */ -public class RepositoryNameSpaceHandler extends NamespaceHandlerSupport { - - /* - * (non-Javadoc) - * @see org.springframework.beans.factory.xml.NamespaceHandler#init() - */ - public void init() { - - KeyValueRepositoryConfigurationExtension extension = new KeyValueRepositoryConfigurationExtension(); - RepositoryBeanDefinitionParser repositoryBeanDefinitionParser = new RepositoryBeanDefinitionParser(extension); - registerBeanDefinitionParser("repositories", repositoryBeanDefinitionParser); - } -} diff --git a/src/main/java/org/springframework/data/keyvalue/repository/query/KeyValuePartTreeQuery.java b/src/main/java/org/springframework/data/keyvalue/repository/query/KeyValuePartTreeQuery.java deleted file mode 100644 index f0c55afbd..000000000 --- a/src/main/java/org/springframework/data/keyvalue/repository/query/KeyValuePartTreeQuery.java +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright 2014 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.repository.query; - -import java.lang.reflect.Constructor; -import java.util.List; - -import org.springframework.beans.BeanUtils; -import org.springframework.data.domain.PageImpl; -import org.springframework.data.domain.Pageable; -import org.springframework.data.keyvalue.core.KeyValueOperations; -import org.springframework.data.keyvalue.core.query.KeyValueQuery; -import org.springframework.data.repository.query.EvaluationContextProvider; -import org.springframework.data.repository.query.ParameterAccessor; -import org.springframework.data.repository.query.ParametersParameterAccessor; -import org.springframework.data.repository.query.QueryMethod; -import org.springframework.data.repository.query.RepositoryQuery; -import org.springframework.data.repository.query.parser.AbstractQueryCreator; -import org.springframework.data.repository.query.parser.PartTree; -import org.springframework.expression.EvaluationContext; -import org.springframework.expression.spel.standard.SpelExpression; -import org.springframework.util.ClassUtils; -import org.springframework.util.CollectionUtils; - -/** - * {@link RepositoryQuery} implementation deriving queries from {@link PartTree} using a predefined - * {@link AbstractQueryCreator}. - * - * @author Christoph Strobl - * @author Oliver Gierke - * @since 1.10 - */ -public class KeyValuePartTreeQuery implements RepositoryQuery { - - private final EvaluationContextProvider evaluationContextProvider; - private final QueryMethod queryMethod; - private final KeyValueOperations keyValueOperations; - private final Class> queryCreator; - - private KeyValueQuery query; - - public KeyValuePartTreeQuery(QueryMethod queryMethod, EvaluationContextProvider evalContextProvider, - KeyValueOperations keyValueOperations, Class> queryCreator) { - - this.queryMethod = queryMethod; - this.keyValueOperations = keyValueOperations; - this.evaluationContextProvider = evalContextProvider; - this.queryCreator = queryCreator; - } - - @Override - public QueryMethod getQueryMethod() { - return queryMethod; - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - @Override - public Object execute(Object[] parameters) { - - KeyValueQuery query = prepareQuery(parameters); - - if (queryMethod.isPageQuery() || queryMethod.isSliceQuery()) { - - Pageable page = (Pageable) parameters[queryMethod.getParameters().getPageableIndex()]; - query.setOffset(page.getOffset()); - query.setRows(page.getPageSize()); - - List result = this.keyValueOperations.find(query, queryMethod.getEntityInformation().getJavaType()); - - long count = queryMethod.isSliceQuery() ? 0 : keyValueOperations.count(query, queryMethod.getEntityInformation() - .getJavaType()); - - return new PageImpl(result, page, count); - - } else if (queryMethod.isCollectionQuery()) { - - return this.keyValueOperations.find(query, queryMethod.getEntityInformation().getJavaType()); - - } else if (queryMethod.isQueryForEntity()) { - - List result = this.keyValueOperations.find(query, queryMethod.getEntityInformation().getJavaType()); - return CollectionUtils.isEmpty(result) ? null : result.get(0); - - } - - throw new UnsupportedOperationException("Query method not supported."); - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - private KeyValueQuery prepareQuery(Object[] parameters) { - - ParametersParameterAccessor accessor = new ParametersParameterAccessor(getQueryMethod().getParameters(), parameters); - - if (this.query == null) { - this.query = createQuery(accessor); - } - - KeyValueQuery q = new KeyValueQuery(this.query.getCritieria()); - - if (accessor.getPageable() != null) { - q.setOffset(accessor.getPageable().getOffset()); - q.setRows(accessor.getPageable().getPageSize()); - } else { - q.setOffset(-1); - q.setRows(-1); - } - - if (accessor.getSort() != null) { - q.setSort(accessor.getSort()); - } else { - q.setSort(this.query.getSort()); - } - - if (q.getCritieria() instanceof SpelExpression) { - EvaluationContext context = this.evaluationContextProvider.getEvaluationContext(getQueryMethod().getParameters(), - parameters); - ((SpelExpression) q.getCritieria()).setEvaluationContext(context); - } - - return q; - } - - public KeyValueQuery createQuery(ParametersParameterAccessor accessor) { - - PartTree tree = new PartTree(getQueryMethod().getName(), getQueryMethod().getEntityInformation().getJavaType()); - - Constructor> constructor = (Constructor>) ClassUtils - .getConstructorIfAvailable(queryCreator, PartTree.class, ParameterAccessor.class); - return (KeyValueQuery) BeanUtils.instantiateClass(constructor, tree, accessor).createQuery(); - } -} diff --git a/src/main/java/org/springframework/data/keyvalue/repository/query/SpelQueryCreator.java b/src/main/java/org/springframework/data/keyvalue/repository/query/SpelQueryCreator.java deleted file mode 100644 index cf1e71469..000000000 --- a/src/main/java/org/springframework/data/keyvalue/repository/query/SpelQueryCreator.java +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright 2014 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.repository.query; - -import java.util.Iterator; - -import org.springframework.dao.InvalidDataAccessApiUsageException; -import org.springframework.data.domain.Sort; -import org.springframework.data.keyvalue.core.query.KeyValueQuery; -import org.springframework.data.repository.query.ParameterAccessor; -import org.springframework.data.repository.query.parser.AbstractQueryCreator; -import org.springframework.data.repository.query.parser.Part; -import org.springframework.data.repository.query.parser.Part.IgnoreCaseType; -import org.springframework.data.repository.query.parser.PartTree; -import org.springframework.data.repository.query.parser.PartTree.OrPart; -import org.springframework.expression.spel.standard.SpelExpression; -import org.springframework.expression.spel.standard.SpelExpressionParser; - -/** - * {@link AbstractQueryCreator} to create {@link SpelExpression} based {@link KeyValueQuery}s. - * - * @author Christoph Strobl - * @author Oliver Gierke - * @since 1.10 - */ -public class SpelQueryCreator extends AbstractQueryCreator, String> { - - private static final SpelExpressionParser PARSER = new SpelExpressionParser(); - - private final SpelExpression expression; - - /** - * Creates a new {@link SpelQueryCreator} for the given {@link PartTree} and {@link ParameterAccessor}. - * - * @param tree must not be {@literal null}. - * @param parameters must not be {@literal null}. - */ - public SpelQueryCreator(PartTree tree, ParameterAccessor parameters) { - - super(tree, parameters); - - this.expression = toPredicateExpression(tree); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.repository.query.parser.AbstractQueryCreator#create(org.springframework.data.repository.query.parser.Part, java.util.Iterator) - */ - @Override - protected String create(Part part, Iterator iterator) { - return ""; - } - - /* - * (non-Javadoc) - * @see org.springframework.data.repository.query.parser.AbstractQueryCreator#and(org.springframework.data.repository.query.parser.Part, java.lang.Object, java.util.Iterator) - */ - @Override - protected String and(Part part, String base, Iterator iterator) { - return ""; - } - - /* - * (non-Javadoc) - * @see org.springframework.data.repository.query.parser.AbstractQueryCreator#or(java.lang.Object, java.lang.Object) - */ - @Override - protected String or(String base, String criteria) { - return ""; - } - - @Override - protected KeyValueQuery complete(String criteria, Sort sort) { - - KeyValueQuery query = new KeyValueQuery(this.expression); - - if (sort != null) { - query.orderBy(sort); - } - - return query; - } - - protected SpelExpression toPredicateExpression(PartTree tree) { - - int parameterIndex = 0; - StringBuilder sb = new StringBuilder(); - - for (Iterator orPartIter = tree.iterator(); orPartIter.hasNext();) { - - int partCnt = 0; - StringBuilder partBuilder = new StringBuilder(); - OrPart orPart = orPartIter.next(); - - for (Iterator partIter = orPart.iterator(); partIter.hasNext();) { - - Part part = partIter.next(); - partBuilder.append("#it?."); - partBuilder.append(part.getProperty().toDotPath().replace(".", "?.")); - - // TODO: check if we can have caseinsensitive search - if (!part.shouldIgnoreCase().equals(IgnoreCaseType.NEVER)) { - throw new InvalidDataAccessApiUsageException("Ignore case not supported!"); - } - - switch (part.getType()) { - case TRUE: - partBuilder.append("?.equals(true)"); - break; - case FALSE: - partBuilder.append("?.equals(false)"); - break; - case SIMPLE_PROPERTY: - partBuilder.append("?.equals(").append("[").append(parameterIndex++).append("])"); - break; - case IS_NULL: - partBuilder.append(" == null"); - break; - case IS_NOT_NULL: - partBuilder.append(" != null"); - break; - case LIKE: - partBuilder.append("?.contains(").append("[").append(parameterIndex++).append("])"); - break; - case STARTING_WITH: - partBuilder.append("?.startsWith(").append("[").append(parameterIndex++).append("])"); - break; - case AFTER: - case GREATER_THAN: - partBuilder.append(">").append("[").append(parameterIndex++).append("]"); - break; - case GREATER_THAN_EQUAL: - partBuilder.append(">=").append("[").append(parameterIndex++).append("]"); - break; - case BEFORE: - case LESS_THAN: - partBuilder.append("<").append("[").append(parameterIndex++).append("]"); - break; - case LESS_THAN_EQUAL: - partBuilder.append("<=").append("[").append(parameterIndex++).append("]"); - break; - case ENDING_WITH: - partBuilder.append("?.endsWith(").append("[").append(parameterIndex++).append("])"); - break; - case BETWEEN: - - int index = partBuilder.lastIndexOf("#it?."); - - partBuilder.insert(index, "("); - partBuilder.append(">").append("[").append(parameterIndex++).append("]"); - partBuilder.append("&&"); - partBuilder.append("#it?."); - partBuilder.append(part.getProperty().toDotPath().replace(".", "?.")); - partBuilder.append("<").append("[").append(parameterIndex++).append("]"); - partBuilder.append(")"); - - break; - - case REGEX: - - partBuilder.append(" matches ").append("[").append(parameterIndex++).append("]"); - break; - case IN: - case CONTAINING: - case NOT_CONTAINING: - case NEGATING_SIMPLE_PROPERTY: - case EXISTS: - default: - throw new InvalidDataAccessApiUsageException(String.format("Found invalid part '%s' in query", - part.getType())); - } - - if (partIter.hasNext()) { - partBuilder.append("&&"); - } - - partCnt++; - } - - if (partCnt > 1) { - sb.append("(").append(partBuilder).append(")"); - } else { - sb.append(partBuilder); - } - - if (orPartIter.hasNext()) { - sb.append("||"); - } - } - - return PARSER.parseRaw(sb.toString()); - } -} diff --git a/src/main/java/org/springframework/data/keyvalue/repository/support/KeyValueQueryDslUtils.java b/src/main/java/org/springframework/data/keyvalue/repository/support/KeyValueQueryDslUtils.java deleted file mode 100644 index 9619a7c37..000000000 --- a/src/main/java/org/springframework/data/keyvalue/repository/support/KeyValueQueryDslUtils.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright 2014 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.repository.support; - -import java.util.ArrayList; -import java.util.List; - -import org.springframework.data.domain.Sort; -import org.springframework.data.domain.Sort.Order; -import org.springframework.data.mapping.PropertyPath; -import org.springframework.data.querydsl.QSort; -import org.springframework.util.Assert; - -import com.mysema.query.support.Expressions; -import com.mysema.query.types.Expression; -import com.mysema.query.types.OrderSpecifier; -import com.mysema.query.types.OrderSpecifier.NullHandling; -import com.mysema.query.types.Path; -import com.mysema.query.types.path.PathBuilder; - -/** - * @author Christoph Strobl - * @author Thomas Darimont - */ -abstract class KeyValueQueryDslUtils { - - private KeyValueQueryDslUtils() { - // prevent instantiation - } - - /** - * Transforms a plain {@link Order} into a QueryDsl specific {@link OrderSpecifier}. - * - * @param sort - * @param builder must not be {@literal null}. - * @return empty {@code OrderSpecifier[]} when sort is {@literal null}. - */ - public static OrderSpecifier[] toOrderSpecifier(Sort sort, PathBuilder builder) { - - Assert.notNull(builder, "Builder must not be 'null'."); - - if (sort == null) { - return new OrderSpecifier[0]; - } - - List> specifiers = null; - - if (sort instanceof QSort) { - specifiers = ((QSort) sort).getOrderSpecifiers(); - } else { - - specifiers = new ArrayList>(); - for (Order order : sort) { - specifiers.add(toOrderSpecifier(order, builder)); - } - } - - return specifiers.toArray(new OrderSpecifier[specifiers.size()]); - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - private static OrderSpecifier toOrderSpecifier(Order order, PathBuilder builder) { - return new OrderSpecifier(order.isAscending() ? com.mysema.query.types.Order.ASC - : com.mysema.query.types.Order.DESC, buildOrderPropertyPathFrom(order, builder), - toQueryDslNullHandling(order.getNullHandling())); - } - - /** - * Creates an {@link Expression} for the given {@link Order} property. - * - * @param order must not be {@literal null}. - * @param builder must not be {@literal null}. - * @return - */ - private static Expression buildOrderPropertyPathFrom(Order order, PathBuilder builder) { - - Assert.notNull(order, "Order must not be null!"); - Assert.notNull(builder, "Builder must not be null!"); - - PropertyPath path = PropertyPath.from(order.getProperty(), builder.getType()); - Expression sortPropertyExpression = builder; - - while (path != null) { - - if (!path.hasNext() && order.isIgnoreCase()) { - // if order is ignore-case we have to treat the last path segment as a String. - sortPropertyExpression = Expressions.stringPath((Path) sortPropertyExpression, path.getSegment()).lower(); - } else { - sortPropertyExpression = Expressions.path(path.getType(), (Path) sortPropertyExpression, path.getSegment()); - } - - path = path.next(); - } - - return sortPropertyExpression; - } - - /** - * Converts the given {@link org.springframework.data.domain.Sort.NullHandling} to the appropriate Querydsl - * {@link NullHandling}. - * - * @param nullHandling must not be {@literal null}. - * @return - */ - private static NullHandling toQueryDslNullHandling(org.springframework.data.domain.Sort.NullHandling nullHandling) { - - Assert.notNull(nullHandling, "NullHandling must not be null!"); - - switch (nullHandling) { - - case NULLS_FIRST: - return NullHandling.NullsFirst; - - case NULLS_LAST: - return NullHandling.NullsLast; - - case NATIVE: - default: - return NullHandling.Default; - } - } -} diff --git a/src/main/java/org/springframework/data/keyvalue/repository/support/KeyValueRepositoryFactory.java b/src/main/java/org/springframework/data/keyvalue/repository/support/KeyValueRepositoryFactory.java deleted file mode 100644 index efddd7b62..000000000 --- a/src/main/java/org/springframework/data/keyvalue/repository/support/KeyValueRepositoryFactory.java +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright 2014 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.repository.support; - -import static org.springframework.data.querydsl.QueryDslUtils.*; - -import java.io.Serializable; -import java.lang.reflect.Method; - -import org.springframework.data.keyvalue.core.KeyValueOperations; -import org.springframework.data.keyvalue.repository.query.KeyValuePartTreeQuery; -import org.springframework.data.keyvalue.repository.query.SpelQueryCreator; -import org.springframework.data.mapping.PersistentEntity; -import org.springframework.data.mapping.context.MappingContext; -import org.springframework.data.querydsl.QueryDslPredicateExecutor; -import org.springframework.data.repository.core.EntityInformation; -import org.springframework.data.repository.core.NamedQueries; -import org.springframework.data.repository.core.RepositoryMetadata; -import org.springframework.data.repository.core.support.PersistentEntityInformation; -import org.springframework.data.repository.core.support.RepositoryFactorySupport; -import org.springframework.data.repository.query.EvaluationContextProvider; -import org.springframework.data.repository.query.QueryLookupStrategy; -import org.springframework.data.repository.query.QueryLookupStrategy.Key; -import org.springframework.data.repository.query.QueryMethod; -import org.springframework.data.repository.query.RepositoryQuery; -import org.springframework.data.repository.query.parser.AbstractQueryCreator; -import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; - -/** - * {@link RepositoryFactorySupport} specific of handing - * {@link org.springframework.data.keyvalue.repository.KeyValueRepository}. - * - * @author Christoph Strobl - * @since 1.10 - */ -public class KeyValueRepositoryFactory extends RepositoryFactorySupport { - - private static final Class DEFAULT_QUERY_CREATOR = SpelQueryCreator.class; - - private final KeyValueOperations keyValueOperations; - private final MappingContext context; - private final Class> queryCreator; - - /** - * Creates a new {@link KeyValueRepositoryFactory} for the given {@link KeyValueOperations}. - * - * @param keyValueOperations must not be {@literal null}. - */ - public KeyValueRepositoryFactory(KeyValueOperations keyValueOperations) { - this(keyValueOperations, DEFAULT_QUERY_CREATOR); - } - - /** - * Creates a new {@link KeyValueRepositoryFactory} for the given {@link KeyValueOperations} and - * {@link AbstractQueryCreator}-type. - * - * @param keyValueOperations must not be {@literal null}. - * @param queryCreator defaulted to {@link #DEFAULT_QUERY_CREATOR} if {@literal null}. - */ - public KeyValueRepositoryFactory(KeyValueOperations keyValueOperations, - Class> queryCreator) { - - Assert.notNull(keyValueOperations, "KeyValueOperations must not be null!"); - Assert.notNull(queryCreator, "Query creator type must not be null!"); - - this.queryCreator = queryCreator; - this.keyValueOperations = keyValueOperations; - this.context = keyValueOperations.getMappingContext(); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.repository.core.support.RepositoryFactorySupport#getEntityInformation(java.lang.Class) - */ - @Override - @SuppressWarnings("unchecked") - public EntityInformation getEntityInformation(Class domainClass) { - - PersistentEntity entity = (PersistentEntity) context.getPersistentEntity(domainClass); - PersistentEntityInformation entityInformation = new PersistentEntityInformation(entity); - - return entityInformation; - } - - /* - * (non-Javadoc) - * @see org.springframework.data.repository.core.support.RepositoryFactorySupport#getTargetRepository(org.springframework.data.repository.core.RepositoryMetadata) - */ - @Override - @SuppressWarnings({ "unchecked", "rawtypes" }) - protected Object getTargetRepository(RepositoryMetadata metadata) { - - EntityInformation entityInformation = getEntityInformation(metadata.getDomainType()); - - if (ClassUtils.isAssignable(QueryDslPredicateExecutor.class, metadata.getRepositoryInterface())) { - return new QueryDslKeyValueRepository(entityInformation, keyValueOperations); - } - - return new SimpleKeyValueRepository(entityInformation, keyValueOperations); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.repository.core.support.RepositoryFactorySupport#getRepositoryBaseClass(org.springframework.data.repository.core.RepositoryMetadata) - */ - @Override - protected Class getRepositoryBaseClass(RepositoryMetadata metadata) { - return isQueryDslRepository(metadata.getRepositoryInterface()) ? QueryDslKeyValueRepository.class - : SimpleKeyValueRepository.class; - } - - /** - * Returns whether the given repository interface requires a QueryDsl specific implementation to be chosen. - * - * @param repositoryInterface must not be {@literal null}. - * @return - */ - private static boolean isQueryDslRepository(Class repositoryInterface) { - return QUERY_DSL_PRESENT && QueryDslPredicateExecutor.class.isAssignableFrom(repositoryInterface); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.repository.core.support.RepositoryFactorySupport#getQueryLookupStrategy(org.springframework.data.repository.query.QueryLookupStrategy.Key, org.springframework.data.repository.query.EvaluationContextProvider) - */ - @Override - protected QueryLookupStrategy getQueryLookupStrategy(Key key, EvaluationContextProvider evaluationContextProvider) { - return new KeyValueQueryLookupStrategy(key, evaluationContextProvider, this.keyValueOperations, this.queryCreator); - } - - /** - * @author Christoph Strobl - * @author Oliver Gierke - * @since 1.10 - */ - private static class KeyValueQueryLookupStrategy implements QueryLookupStrategy { - - private EvaluationContextProvider evaluationContextProvider; - private KeyValueOperations keyValueOperations; - - private Class> queryCreator; - - /** - * Creates a new {@link KeyValueQueryLookupStrategy} for the given {@link Key}, {@link EvaluationContextProvider}, - * {@link KeyValueOperations} and query creator type. - *

- * TODO: Key is not considered. Should it? - * - * @param key - * @param evaluationContextProvider must not be {@literal null}. - * @param keyValueOperations must not be {@literal null}. - * @param queryCreator must not be {@literal null}. - */ - public KeyValueQueryLookupStrategy(Key key, EvaluationContextProvider evaluationContextProvider, - KeyValueOperations keyValueOperations, Class> queryCreator) { - - Assert.notNull(evaluationContextProvider, "EvaluationContextProvider must not be null!"); - Assert.notNull(keyValueOperations, "KeyValueOperations must not be null!"); - Assert.notNull(queryCreator, "Query creator type must not be null!"); - - this.evaluationContextProvider = evaluationContextProvider; - this.keyValueOperations = keyValueOperations; - this.queryCreator = queryCreator; - } - - /* - * (non-Javadoc) - * @see org.springframework.data.repository.query.QueryLookupStrategy#resolveQuery(java.lang.reflect.Method, org.springframework.data.repository.core.RepositoryMetadata, org.springframework.data.repository.core.NamedQueries) - */ - public RepositoryQuery resolveQuery(Method method, RepositoryMetadata metadata, NamedQueries namedQueries) { - - QueryMethod queryMethod = new QueryMethod(method, metadata); - return new KeyValuePartTreeQuery(queryMethod, evaluationContextProvider, this.keyValueOperations, - this.queryCreator); - } - } -} diff --git a/src/main/java/org/springframework/data/keyvalue/repository/support/KeyValueRepositoryFactoryBean.java b/src/main/java/org/springframework/data/keyvalue/repository/support/KeyValueRepositoryFactoryBean.java deleted file mode 100644 index 5ead4a99b..000000000 --- a/src/main/java/org/springframework/data/keyvalue/repository/support/KeyValueRepositoryFactoryBean.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2014 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.repository.support; - -import java.io.Serializable; - -import org.springframework.data.keyvalue.core.KeyValueOperations; -import org.springframework.data.keyvalue.repository.KeyValueRepository; -import org.springframework.data.mapping.context.MappingContext; -import org.springframework.data.repository.Repository; -import org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport; -import org.springframework.data.repository.core.support.RepositoryFactorySupport; -import org.springframework.data.repository.query.parser.AbstractQueryCreator; - -/** - * {@link org.springframework.beans.factory.FactoryBean} to create {@link KeyValueRepository}. - * - * @author Christoph Strobl - * @since 1.10 - */ -public class KeyValueRepositoryFactoryBean, S, ID extends Serializable> extends - RepositoryFactoryBeanSupport { - - private KeyValueOperations operations; - private Class> queryCreator; - - public void setKeyValueOperations(KeyValueOperations operations) { - this.operations = operations; - } - - /* - * (non-Javadoc) - * @see org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport#setMappingContext(org.springframework.data.mapping.context.MappingContext) - */ - @Override - public void setMappingContext(MappingContext mappingContext) { - super.setMappingContext(mappingContext); - } - - public void setQueryCreator(Class> queryCreator) { - this.queryCreator = queryCreator; - } - - /* - * (non-Javadoc) - * @see org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport#createRepositoryFactory() - */ - @Override - protected RepositoryFactorySupport createRepositoryFactory() { - return new KeyValueRepositoryFactory(this.operations, this.queryCreator); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport#afterPropertiesSet() - */ - @Override - public void afterPropertiesSet() { - super.afterPropertiesSet(); - } -} diff --git a/src/main/java/org/springframework/data/keyvalue/repository/support/QueryDslKeyValueRepository.java b/src/main/java/org/springframework/data/keyvalue/repository/support/QueryDslKeyValueRepository.java deleted file mode 100644 index 7622eabea..000000000 --- a/src/main/java/org/springframework/data/keyvalue/repository/support/QueryDslKeyValueRepository.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright 2014 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.repository.support; - -import static org.springframework.data.keyvalue.repository.support.KeyValueQueryDslUtils.*; - -import java.io.Serializable; - -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageImpl; -import org.springframework.data.domain.Pageable; -import org.springframework.data.keyvalue.core.KeyValueOperations; -import org.springframework.data.keyvalue.repository.KeyValueRepository; -import org.springframework.data.querydsl.EntityPathResolver; -import org.springframework.data.querydsl.QueryDslPredicateExecutor; -import org.springframework.data.querydsl.SimpleEntityPathResolver; -import org.springframework.data.repository.core.EntityInformation; -import org.springframework.util.Assert; - -import com.mysema.query.collections.CollQuery; -import com.mysema.query.support.ProjectableQuery; -import com.mysema.query.types.EntityPath; -import com.mysema.query.types.OrderSpecifier; -import com.mysema.query.types.Predicate; -import com.mysema.query.types.path.PathBuilder; - -/** - * {@link KeyValueRepository} implementation capable of executing {@link Predicate}s using {@link CollQuery}. - * - * @author Christoph Strobl - * @since 1.10 - * @param - * @param - */ -public class QueryDslKeyValueRepository extends SimpleKeyValueRepository implements - QueryDslPredicateExecutor { - - private static final EntityPathResolver DEFAULT_ENTITY_PATH_RESOLVER = SimpleEntityPathResolver.INSTANCE; - - private final EntityPath path; - private final PathBuilder builder; - - /** - * Creates a new {@link QueryDslKeyValueRepository} for the given {@link EntityInformation} and - * {@link KeyValueOperations}. - * - * @param entityInformation must not be {@literal null}. - * @param operations must not be {@literal null}. - */ - public QueryDslKeyValueRepository(EntityInformation entityInformation, KeyValueOperations operations) { - this(entityInformation, operations, DEFAULT_ENTITY_PATH_RESOLVER); - } - - /** - * Creates a new {@link QueryDslKeyValueRepository} for the given {@link EntityInformation}, - * {@link KeyValueOperations} and {@link EntityPathResolver}. - * - * @param entityInformation must not be {@literal null}. - * @param operations must not be {@literal null}. - * @param resolver must not be {@literal null}. - */ - public QueryDslKeyValueRepository(EntityInformation entityInformation, KeyValueOperations operations, - EntityPathResolver resolver) { - - super(entityInformation, operations); - - Assert.notNull(resolver, "EntityPathResolver must not be null!"); - - this.path = resolver.createPath(entityInformation.getJavaType()); - this.builder = new PathBuilder(path.getType(), path.getMetadata()); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.querydsl.QueryDslPredicateExecutor#findOne(com.mysema.query.types.Predicate) - */ - @Override - public T findOne(Predicate predicate) { - return prepareQuery(predicate).uniqueResult(builder); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.querydsl.QueryDslPredicateExecutor#findAll(com.mysema.query.types.Predicate) - */ - @Override - public Iterable findAll(Predicate predicate) { - return prepareQuery(predicate).list(builder); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.querydsl.QueryDslPredicateExecutor#findAll(com.mysema.query.types.Predicate, com.mysema.query.types.OrderSpecifier[]) - */ - @Override - public Iterable findAll(Predicate predicate, OrderSpecifier... orders) { - - ProjectableQuery query = prepareQuery(predicate); - query.orderBy(orders); - - return query.list(builder); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.querydsl.QueryDslPredicateExecutor#findAll(com.mysema.query.types.Predicate, org.springframework.data.domain.Pageable) - */ - @Override - public Page findAll(Predicate predicate, Pageable pageable) { - - ProjectableQuery query = prepareQuery(predicate); - - if (pageable != null) { - - query.offset(pageable.getOffset()); - query.limit(pageable.getPageSize()); - - if (pageable.getSort() != null) { - query.orderBy(toOrderSpecifier(pageable.getSort(), builder)); - } - } - - return new PageImpl(query.list(builder), pageable, count(predicate)); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.querydsl.QueryDslPredicateExecutor#count(com.mysema.query.types.Predicate) - */ - @Override - public long count(Predicate predicate) { - return prepareQuery(predicate).count(); - } - - /** - * Creates executable query for given {@link Predicate}. - * - * @param predicate - * @return - */ - protected ProjectableQuery prepareQuery(Predicate predicate) { - - CollQuery query = new CollQuery(); - - query.from(builder, findAll()); - query.where(predicate); - - return query; - } -} diff --git a/src/main/java/org/springframework/data/keyvalue/repository/support/SimpleKeyValueRepository.java b/src/main/java/org/springframework/data/keyvalue/repository/support/SimpleKeyValueRepository.java deleted file mode 100644 index ac79a9fe4..000000000 --- a/src/main/java/org/springframework/data/keyvalue/repository/support/SimpleKeyValueRepository.java +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Copyright 2014 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.repository.support; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; - -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageImpl; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; -import org.springframework.data.keyvalue.core.KeyValueOperations; -import org.springframework.data.keyvalue.repository.KeyValueRepository; -import org.springframework.data.repository.core.EntityInformation; -import org.springframework.util.Assert; - -/** - * @author Christoph Strobl - * @author Oliver Gierke - * @since 1.10 - * @param - * @param - */ -public class SimpleKeyValueRepository implements KeyValueRepository { - - private final KeyValueOperations operations; - private final EntityInformation entityInformation; - - /** - * Creates a new {@link SimpleKeyValueRepository} for the given {@link EntityInformation} and - * {@link KeyValueOperations}. - * - * @param metadata must not be {@literal null}. - * @param operations must not be {@literal null}. - */ - public SimpleKeyValueRepository(EntityInformation metadata, KeyValueOperations operations) { - - Assert.notNull(metadata, "EntityInformation must not be null!"); - Assert.notNull(operations, "KeyValueOperations must not be null!"); - - this.entityInformation = metadata; - this.operations = operations; - } - - /* - * (non-Javadoc) - * @see org.springframework.data.repository.PagingAndSortingRepository#findAll(org.springframework.data.domain.Sort) - */ - @Override - public Iterable findAll(Sort sort) { - return operations.findAll(sort, entityInformation.getJavaType()); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.repository.PagingAndSortingRepository#findAll(org.springframework.data.domain.Pageable) - */ - @Override - public Page findAll(Pageable pageable) { - - if (pageable == null) { - List result = findAll(); - return new PageImpl(result, null, result.size()); - } - - List content = null; - - content = operations.findInRange(pageable.getOffset(), pageable.getPageSize(), pageable.getSort(), - entityInformation.getJavaType()); - - return new PageImpl(content, pageable, this.operations.count(entityInformation.getJavaType())); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.repository.CrudRepository#save(java.lang.Object) - */ - @Override - public S save(S entity) { - - Assert.notNull(entity, "Entity must not be null!"); - - if (entityInformation.isNew(entity)) { - operations.insert(entity); - } else { - operations.update(entityInformation.getId(entity), entity); - } - return entity; - } - - /* - * (non-Javadoc) - * @see org.springframework.data.repository.CrudRepository#save(java.lang.Iterable) - */ - @Override - public Iterable save(Iterable entities) { - - for (S entity : entities) { - save(entity); - } - - return entities; - } - - /* - * (non-Javadoc) - * @see org.springframework.data.repository.CrudRepository#findOne(java.io.Serializable) - */ - @Override - public T findOne(ID id) { - return operations.findById(id, entityInformation.getJavaType()); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.repository.CrudRepository#exists(java.io.Serializable) - */ - @Override - public boolean exists(ID id) { - return findOne(id) != null; - } - - /* - * (non-Javadoc) - * @see org.springframework.data.repository.CrudRepository#findAll() - */ - @Override - public List findAll() { - return operations.findAll(entityInformation.getJavaType()); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.repository.CrudRepository#findAll(java.lang.Iterable) - */ - @Override - public Iterable findAll(Iterable ids) { - - List result = new ArrayList(); - - for (ID id : ids) { - - T candidate = findOne(id); - - if (candidate != null) { - result.add(candidate); - } - } - - return result; - } - - /* - * (non-Javadoc) - * @see org.springframework.data.repository.CrudRepository#count() - */ - @Override - public long count() { - return operations.count(entityInformation.getJavaType()); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.repository.CrudRepository#delete(java.io.Serializable) - */ - @Override - public void delete(ID id) { - operations.delete(id, entityInformation.getJavaType()); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.repository.CrudRepository#delete(java.lang.Object) - */ - @Override - public void delete(T entity) { - delete(entityInformation.getId(entity)); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.repository.CrudRepository#delete(java.lang.Iterable) - */ - @Override - public void delete(Iterable entities) { - - for (T entity : entities) { - delete(entity); - } - } - - /* - * (non-Javadoc) - * @see org.springframework.data.repository.CrudRepository#deleteAll() - */ - @Override - public void deleteAll() { - operations.delete(entityInformation.getJavaType()); - } -} diff --git a/src/test/java/org/springframework/data/keyvalue/Person.java b/src/test/java/org/springframework/data/keyvalue/Person.java deleted file mode 100644 index 10ea76f90..000000000 --- a/src/test/java/org/springframework/data/keyvalue/Person.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2014 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.io.Serializable; - -import org.springframework.data.annotation.Id; -import org.springframework.util.ObjectUtils; - -import com.mysema.query.annotations.QueryEntity; - -/** - * @author Christoph Strobl - */ -@QueryEntity -public class Person implements Serializable { - - private @Id String id; - private String firstname; - private int age; - - public Person(String firstname, int age) { - super(); - this.firstname = firstname; - this.age = age; - } - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public int getAge() { - return age; - } - - public void setAge(int age) { - this.age = age; - } - - public String getFirstname() { - return firstname; - } - - public void setFirstname(String firstname) { - this.firstname = firstname; - } - - @Override - public String toString() { - return "Person [id=" + id + ", firstname=" + firstname + ", age=" + age + "]"; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + age; - result = prime * result + ObjectUtils.nullSafeHashCode(this.firstname); - result = prime * result + ObjectUtils.nullSafeHashCode(this.id); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (!(obj instanceof Person)) { - return false; - } - Person other = (Person) obj; - if (!ObjectUtils.nullSafeEquals(this.id, other.id)) { - return false; - } - if (!ObjectUtils.nullSafeEquals(this.firstname, other.firstname)) { - return false; - } - if (!ObjectUtils.nullSafeEquals(this.age, other.age)) { - return false; - } - return true; - } - -} diff --git a/src/test/java/org/springframework/data/keyvalue/core/KeySpaceUtilsUnitTests.java b/src/test/java/org/springframework/data/keyvalue/core/KeySpaceUtilsUnitTests.java deleted file mode 100644 index ccbe4eac1..000000000 --- a/src/test/java/org/springframework/data/keyvalue/core/KeySpaceUtilsUnitTests.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright 2014 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 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.Test; -import org.springframework.data.annotation.Persistent; -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}. - * - * @author Christoph Strobl - * @author Oliver Gierke - */ -public class KeySpaceUtilsUnitTests { - - /** - * @see DATACMNS-525 - */ - @Test - public void shouldResolveKeySpaceDefaultValueCorrectly() { - assertThat(getKeySpace(EntityWithDefaultKeySpace.class), is((Object) "daenerys")); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void shouldResolveKeySpaceCorrectly() { - assertThat(getKeySpace(EntityWithSetKeySpace.class), is((Object) "viserys")); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void shouldReturnNullWhenNoKeySpaceFoundOnComposedPersistentAnnotation() { - assertThat(getKeySpace(AliasedEntity.class), nullValue()); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void shouldReturnNullWhenPersistentIsFoundOnNonComposedAnnotation() { - assertThat(getKeySpace(EntityWithPersistentAnnotation.class), nullValue()); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void shouldReturnNullWhenPersistentIsNotFound() { - assertThat(getKeySpace(Foo.class), nullValue()); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void shouldResolveInheritedKeySpaceCorrectly() { - assertThat(getKeySpace(EntityWithInheritedKeySpace.class), is((Object) "viserys")); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void shouldResolveDirectKeySpaceAnnotationCorrectly() { - assertThat(getKeySpace(ClassWithDirectKeySpaceAnnotation.class), is((Object) "rhaegar")); - } - - @PersistentAnnotationWithExplicitKeySpace - static class EntityWithDefaultKeySpace { - - } - - @PersistentAnnotationWithExplicitKeySpace(firstname = "viserys") - static class EntityWithSetKeySpace { - - } - - static class EntityWithInheritedKeySpace extends EntityWithSetKeySpace { - - } - - @Persistent - @Retention(RetentionPolicy.RUNTIME) - @Target({ ElementType.TYPE }) - static @interface PersistentAnnotationWithExplicitKeySpace { - - @KeySpace - String firstname() default "daenerys"; - - String lastnamne() default "targaryen"; - } - - @Persistent - @Retention(RetentionPolicy.RUNTIME) - @Target({ ElementType.TYPE }) - static @interface ExplicitKeySpace { - - @KeySpace - String name() default ""; - } -} diff --git a/src/test/java/org/springframework/data/keyvalue/core/KeyValuePersistenceExceptionTranslatorUnitTests.java b/src/test/java/org/springframework/data/keyvalue/core/KeyValuePersistenceExceptionTranslatorUnitTests.java deleted file mode 100644 index 5d5d1a4c8..000000000 --- a/src/test/java/org/springframework/data/keyvalue/core/KeyValuePersistenceExceptionTranslatorUnitTests.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright 2014 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 static org.hamcrest.core.IsInstanceOf.*; -import static org.hamcrest.core.IsNull.*; -import static org.junit.Assert.*; - -import java.util.NoSuchElementException; - -import org.junit.Test; -import org.springframework.beans.factory.NoSuchBeanDefinitionException; -import org.springframework.dao.DataRetrievalFailureException; - -/** - * @author Christoph Strobl - */ -public class KeyValuePersistenceExceptionTranslatorUnitTests { - - KeyValuePersistenceExceptionTranslator translator = new KeyValuePersistenceExceptionTranslator(); - - /** - * @see DATACMNS-525 - */ - @Test - public void translateExeptionShouldReturnDataAccessExceptionWhenGivenOne() { - assertThat(translator.translateExceptionIfPossible(new DataRetrievalFailureException("booh")), - instanceOf(DataRetrievalFailureException.class)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void translateExeptionShouldReturnNullWhenGivenNull() { - assertThat(translator.translateExceptionIfPossible(null), nullValue()); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void translateExeptionShouldTranslateNoSuchElementExceptionToDataRetrievalFailureException() { - assertThat(translator.translateExceptionIfPossible(new NoSuchElementException("")), - instanceOf(DataRetrievalFailureException.class)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void translateExeptionShouldTranslateIndexOutOfBoundsExceptionToDataRetrievalFailureException() { - assertThat(translator.translateExceptionIfPossible(new IndexOutOfBoundsException("")), - instanceOf(DataRetrievalFailureException.class)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void translateExeptionShouldTranslateIllegalStateExceptionToDataRetrievalFailureException() { - assertThat(translator.translateExceptionIfPossible(new IllegalStateException("")), - instanceOf(DataRetrievalFailureException.class)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void translateExeptionShouldTranslateAnyJavaExceptionToUncategorizedKeyValueException() { - assertThat(translator.translateExceptionIfPossible(new UnsupportedOperationException("")), - instanceOf(UncategorizedKeyValueException.class)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void translateExeptionShouldReturnNullForNonJavaExceptions() { - assertThat(translator.translateExceptionIfPossible(new NoSuchBeanDefinitionException("")), nullValue()); - } - -} diff --git a/src/test/java/org/springframework/data/keyvalue/core/KeyValueTemplateTests.java b/src/test/java/org/springframework/data/keyvalue/core/KeyValueTemplateTests.java deleted file mode 100644 index 9428d0539..000000000 --- a/src/test/java/org/springframework/data/keyvalue/core/KeyValueTemplateTests.java +++ /dev/null @@ -1,466 +0,0 @@ -/* - * Copyright 2014 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 static org.hamcrest.collection.IsCollectionWithSize.*; -import static org.hamcrest.collection.IsEmptyCollection.*; -import static org.hamcrest.collection.IsIterableContainingInAnyOrder.*; -import static org.hamcrest.core.Is.*; -import static org.hamcrest.core.IsNull.*; -import static org.hamcrest.core.IsSame.*; -import static org.junit.Assert.*; - -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.List; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.springframework.dao.InvalidDataAccessApiUsageException; -import org.springframework.data.annotation.Id; -import org.springframework.data.annotation.Persistent; -import org.springframework.data.keyvalue.annotation.KeySpace; -import org.springframework.data.keyvalue.core.query.KeyValueQuery; -import org.springframework.data.keyvalue.map.MapKeyValueAdapter; -import org.springframework.util.ObjectUtils; - -/** - * @author Christoph Strobl - * @author Oliver Gierke - */ -public class KeyValueTemplateTests { - - static final Foo FOO_ONE = new Foo("one"); - static final Foo FOO_TWO = new Foo("two"); - static final Foo FOO_THREE = new Foo("three"); - static final Bar BAR_ONE = new Bar("one"); - static final ClassWithTypeAlias ALIASED = new ClassWithTypeAlias("super"); - static final SubclassOfAliasedType SUBCLASS_OF_ALIASED = new SubclassOfAliasedType("sub"); - static final KeyValueQuery STRING_QUERY = new KeyValueQuery("foo == 'two'"); - - KeyValueTemplate operations; - - @Before - public void setUp() throws InstantiationException, IllegalAccessException { - this.operations = new KeyValueTemplate(new MapKeyValueAdapter()); - } - - @After - public void tearDown() throws Exception { - this.operations.destroy(); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void insertShouldNotThorwErrorWhenExecutedHavingNonExistingIdAndNonNullValue() { - operations.insert("1", FOO_ONE); - } - - /** - * @see DATACMNS-525 - */ - @Test(expected = IllegalArgumentException.class) - public void insertShouldThrowExceptionForNullId() { - operations.insert(null, FOO_ONE); - } - - /** - * @see DATACMNS-525 - */ - @Test(expected = IllegalArgumentException.class) - public void insertShouldThrowExceptionForNullObject() { - operations.insert("some-id", null); - } - - /** - * @see DATACMNS-525 - */ - @Test(expected = InvalidDataAccessApiUsageException.class) - public void insertShouldThrowExecptionWhenObjectOfSameTypeAlreadyExists() { - - operations.insert("1", FOO_ONE); - operations.insert("1", FOO_TWO); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void insertShouldWorkCorrectlyWhenObjectsOfDifferentTypesWithSameIdAreInserted() { - - operations.insert("1", FOO_ONE); - operations.insert("1", BAR_ONE); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void createShouldReturnSameInstanceGenerateId() { - - ClassWithStringId source = new ClassWithStringId(); - ClassWithStringId target = operations.insert(source); - - assertThat(target, sameInstance(source)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void createShouldRespectExistingId() { - - ClassWithStringId source = new ClassWithStringId(); - source.id = "one"; - - operations.insert(source); - - assertThat(operations.findById("one", ClassWithStringId.class), is(source)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void findByIdShouldReturnObjectWithMatchingIdAndType() { - - operations.insert("1", FOO_ONE); - assertThat(operations.findById("1", Foo.class), is(FOO_ONE)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void findByIdSouldReturnNullIfNoMatchingIdFound() { - - operations.insert("1", FOO_ONE); - assertThat(operations.findById("2", Foo.class), nullValue()); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void findByIdShouldReturnNullIfNoMatchingTypeFound() { - - operations.insert("1", FOO_ONE); - assertThat(operations.findById("1", Bar.class), nullValue()); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void findShouldExecuteQueryCorrectly() { - - operations.insert("1", FOO_ONE); - operations.insert("2", FOO_TWO); - - List result = (List) operations.find(STRING_QUERY, Foo.class); - assertThat(result, hasSize(1)); - assertThat(result.get(0), is(FOO_TWO)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void readShouldReturnEmptyCollectionIfOffsetOutOfRange() { - - operations.insert("1", FOO_ONE); - operations.insert("2", FOO_TWO); - operations.insert("3", FOO_THREE); - - assertThat(operations.findInRange(5, 5, Foo.class), empty()); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void updateShouldReplaceExistingObject() { - - operations.insert("1", FOO_ONE); - operations.update("1", FOO_TWO); - assertThat(operations.findById("1", Foo.class), is(FOO_TWO)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void updateShouldRespectTypeInformation() { - - operations.insert("1", FOO_ONE); - operations.update("1", BAR_ONE); - - assertThat(operations.findById("1", Foo.class), is(FOO_ONE)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void deleteShouldRemoveObjectCorrectly() { - - operations.insert("1", FOO_ONE); - operations.delete("1", Foo.class); - assertThat(operations.findById("1", Foo.class), nullValue()); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void deleteReturnsNullWhenNotExisting() { - - operations.insert("1", FOO_ONE); - assertThat(operations.delete("2", Foo.class), nullValue()); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void deleteReturnsRemovedObject() { - - operations.insert("1", FOO_ONE); - assertThat(operations.delete("1", Foo.class), is(FOO_ONE)); - } - - /** - * @see DATACMNS-525 - */ - @Test(expected = IllegalArgumentException.class) - public void deleteThrowsExceptionWhenIdCannotBeExctracted() { - operations.delete(FOO_ONE); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void countShouldReturnZeroWhenNoElementsPresent() { - assertThat(operations.count(Foo.class), is(0L)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void insertShouldRespectTypeAlias() { - - operations.insert("1", ALIASED); - operations.insert("2", SUBCLASS_OF_ALIASED); - - assertThat(operations.findAll(ALIASED.getClass()), containsInAnyOrder(ALIASED, SUBCLASS_OF_ALIASED)); - } - - static class Foo implements Serializable { - - private static final long serialVersionUID = -8912754229220128922L; - - String foo; - - public Foo(String foo) { - this.foo = foo; - } - - public String getFoo() { - return foo; - } - - @Override - public int hashCode() { - return ObjectUtils.nullSafeHashCode(this.foo); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (!(obj instanceof Foo)) { - return false; - } - Foo other = (Foo) obj; - return ObjectUtils.nullSafeEquals(this.foo, other.foo); - } - - } - - static class Bar implements Serializable { - - private static final long serialVersionUID = 196011921826060210L; - String bar; - - public Bar(String bar) { - this.bar = bar; - } - - public String getBar() { - return bar; - } - - @Override - public int hashCode() { - return ObjectUtils.nullSafeHashCode(this.bar); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (!(obj instanceof Bar)) { - return false; - } - Bar other = (Bar) obj; - return ObjectUtils.nullSafeEquals(this.bar, other.bar); - } - - } - - static class ClassWithStringId implements Serializable { - - private static final long serialVersionUID = -7481030649267602830L; - @Id String id; - String value; - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ObjectUtils.nullSafeHashCode(this.id); - result = prime * result + ObjectUtils.nullSafeHashCode(this.value); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (!(obj instanceof ClassWithStringId)) { - return false; - } - ClassWithStringId other = (ClassWithStringId) obj; - if (!ObjectUtils.nullSafeEquals(this.id, other.id)) { - return false; - } - if (!ObjectUtils.nullSafeEquals(this.value, other.value)) { - return false; - } - return true; - } - - } - - @ExplicitKeySpace(name = "aliased") - static class ClassWithTypeAlias implements Serializable { - - private static final long serialVersionUID = -5921943364908784571L; - @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 { - - private static final long serialVersionUID = -468809596668871479L; - - public SubclassOfAliasedType(String name) { - super(name); - } - - } - - @Persistent - @Retention(RetentionPolicy.RUNTIME) - @Target({ ElementType.TYPE }) - static @interface ExplicitKeySpace { - - @KeySpace - String name() default ""; - - } -} diff --git a/src/test/java/org/springframework/data/keyvalue/core/KeyValueTemplateUnitTests.java b/src/test/java/org/springframework/data/keyvalue/core/KeyValueTemplateUnitTests.java deleted file mode 100644 index eb2deab8a..000000000 --- a/src/test/java/org/springframework/data/keyvalue/core/KeyValueTemplateUnitTests.java +++ /dev/null @@ -1,609 +0,0 @@ -/* - * Copyright 2014 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 static org.hamcrest.CoreMatchers.*; -import static org.hamcrest.collection.IsIterableContainingInAnyOrder.*; -import static org.junit.Assert.*; -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 org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; -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.core.query.KeyValueQuery; -import org.springframework.util.ObjectUtils; - -/** - * @author Christoph Strobl - */ -@RunWith(MockitoJUnitRunner.class) -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 KeyValueQuery STRING_QUERY = new KeyValueQuery("foo == 'two'"); - - private @Mock KeyValueAdapter adapterMock; - private KeyValueTemplate template; - - @Before - public void setUp() throws InstantiationException, IllegalAccessException { - this.template = new KeyValueTemplate(adapterMock); - } - - /** - * @see DATACMNS-525 - */ - @Test(expected = IllegalArgumentException.class) - public void shouldThrowExceptionWhenCreatingNewTempateWithNullAdapter() { - new KeyValueTemplate(null); - } - - /** - * @see DATACMNS-525 - */ - @Test(expected = IllegalArgumentException.class) - public void shouldThrowExceptionWhenCreatingNewTempateWithNullMappingContext() { - new KeyValueTemplate(adapterMock, null); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void insertShouldLookUpValuesBeforeInserting() { - - template.insert("1", FOO_ONE); - - verify(adapterMock, times(1)).contains("1", Foo.class.getName()); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void insertShouldInsertUseClassNameAsDefaultKeyspace() { - - template.insert("1", FOO_ONE); - - verify(adapterMock, times(1)).put("1", FOO_ONE, Foo.class.getName()); - } - - /** - * @see DATACMNS-525 - */ - @Test(expected = InvalidDataAccessApiUsageException.class) - public void insertShouldThrowExceptionWhenObectWithIdAlreadyExists() { - - when(adapterMock.contains(anyString(), anyString())).thenReturn(true); - - template.insert("1", FOO_ONE); - } - - /** - * @see DATACMNS-525 - */ - @Test(expected = IllegalArgumentException.class) - public void insertShouldThrowExceptionForNullId() { - template.insert(null, FOO_ONE); - } - - /** - * @see DATACMNS-525 - */ - @Test(expected = IllegalArgumentException.class) - public void insertShouldThrowExceptionForNullObject() { - template.insert("some-id", null); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void insertShouldGenerateId() { - - ClassWithStringId target = template.insert(new ClassWithStringId()); - - assertThat(target.id, notNullValue()); - } - - /** - * @see DATACMNS-525 - */ - @Test(expected = IllegalArgumentException.class) - public void insertShouldThrowErrorWhenIdCannotBeResolved() { - template.insert(FOO_ONE); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void insertShouldReturnSameInstanceGenerateId() { - - ClassWithStringId source = new ClassWithStringId(); - ClassWithStringId target = template.insert(source); - - assertThat(target, sameInstance(source)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void insertShouldRespectExistingId() { - - ClassWithStringId source = new ClassWithStringId(); - source.id = "one"; - - template.insert(source); - - verify(adapterMock, times(1)).put("one", source, ClassWithStringId.class.getName()); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void findByIdShouldReturnNullWhenNoElementsPresent() { - assertNull(template.findById("1", Foo.class)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void findByIdShouldReturnObjectWithMatchingIdAndType() { - - template.findById("1", Foo.class); - - verify(adapterMock, times(1)).get("1", Foo.class.getName()); - } - - /** - * @see DATACMNS-525 - */ - @Test(expected = IllegalArgumentException.class) - public void findByIdShouldThrowExceptionWhenGivenNullId() { - template.findById((Serializable) null, Foo.class); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void findAllOfShouldReturnEntireCollection() { - - template.findAll(Foo.class); - - verify(adapterMock, times(1)).getAllOf(Foo.class.getName()); - } - - /** - * @see DATACMNS-525 - */ - @Test(expected = IllegalArgumentException.class) - public void findAllOfShouldThrowExceptionWhenGivenNullType() { - template.findAll(null); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void findShouldCallFindOnAdapterToResolveMatching() { - - template.find(STRING_QUERY, Foo.class); - - verify(adapterMock, times(1)).find(STRING_QUERY, Foo.class.getName()); - } - - /** - * @see DATACMNS-525 - */ - @Test - @SuppressWarnings("rawtypes") - public void findInRangeShouldRespectOffset() { - - ArgumentCaptor captor = ArgumentCaptor.forClass(KeyValueQuery.class); - - template.findInRange(1, 5, Foo.class); - - verify(adapterMock, times(1)).find(captor.capture(), eq(Foo.class.getName())); - assertThat(captor.getValue().getOffset(), is(1)); - assertThat(captor.getValue().getRows(), is(5)); - assertThat(captor.getValue().getCritieria(), nullValue()); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void updateShouldReplaceExistingObject() { - - template.update("1", FOO_TWO); - - verify(adapterMock, times(1)).put("1", FOO_TWO, Foo.class.getName()); - } - - /** - * @see DATACMNS-525 - */ - @Test(expected = IllegalArgumentException.class) - public void updateShouldThrowExceptionWhenGivenNullId() { - template.update(null, FOO_ONE); - } - - /** - * @see DATACMNS-525 - */ - @Test(expected = IllegalArgumentException.class) - public void updateShouldThrowExceptionWhenGivenNullObject() { - template.update("1", null); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void updateShouldUseExtractedIdInformation() { - - ClassWithStringId source = new ClassWithStringId(); - source.id = "some-id"; - - template.update(source); - - verify(adapterMock, times(1)).put(source.id, source, ClassWithStringId.class.getName()); - } - - /** - * @see DATACMNS-525 - */ - @Test(expected = InvalidDataAccessApiUsageException.class) - public void updateShouldThrowErrorWhenIdInformationCannotBeExtracted() { - template.update(FOO_ONE); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void deleteShouldRemoveObjectCorrectly() { - - template.delete("1", Foo.class); - - verify(adapterMock, times(1)).delete("1", Foo.class.getName()); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void deleteRemovesObjectUsingExtractedId() { - - ClassWithStringId source = new ClassWithStringId(); - source.id = "some-id"; - - template.delete(source); - - verify(adapterMock, times(1)).delete("some-id", ClassWithStringId.class.getName()); - } - - /** - * @see DATACMNS-525 - */ - @Test(expected = IllegalArgumentException.class) - public void deleteThrowsExceptionWhenIdCannotBeExctracted() { - template.delete(FOO_ONE); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void countShouldReturnZeroWhenNoElementsPresent() { - template.count(Foo.class); - } - - /** - * @see DATACMNS-525 - */ - @Test - @SuppressWarnings({ "rawtypes", "unchecked" }) - public void countShouldReturnCollectionSize() { - - Collection foo = Arrays.asList(FOO_ONE, FOO_ONE); - when(adapterMock.getAllOf(Foo.class.getName())).thenReturn(foo); - - assertThat(template.count(Foo.class), is(2L)); - } - - /** - * @see DATACMNS-525 - */ - @Test(expected = IllegalArgumentException.class) - public void countShouldThrowErrorOnNullType() { - template.count(null); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void insertShouldRespectTypeAlias() { - - template.insert("1", ALIASED); - - verify(adapterMock, times(1)).put("1", ALIASED, "aliased"); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void insertShouldRespectTypeAliasOnSubClass() { - - template.insert("1", SUBCLASS_OF_ALIASED); - - verify(adapterMock, times(1)).put("1", SUBCLASS_OF_ALIASED, "aliased"); - } - - /** - * @see DATACMNS-525 - */ - @SuppressWarnings({ "rawtypes", "unchecked" }) - @Test - public void findAllOfShouldRespectTypeAliasAndFilterNonMatchingTypes() { - - Collection foo = Arrays.asList(ALIASED, SUBCLASS_OF_ALIASED); - when(adapterMock.getAllOf("aliased")).thenReturn(foo); - - assertThat(template.findAll(SUBCLASS_OF_ALIASED.getClass()), containsInAnyOrder(SUBCLASS_OF_ALIASED)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void insertSouldRespectTypeAliasAndFilterNonMatching() { - - template.insert("1", ALIASED); - assertThat(template.findById("1", SUBCLASS_OF_ALIASED.getClass()), nullValue()); - } - - /** - * @see DATACMNS-525 - */ - @Test(expected = IllegalArgumentException.class) - public void setttingNullPersistenceExceptionTranslatorShouldThrowException() { - template.setExceptionTranslator(null); - } - - static class Foo { - - String foo; - - public Foo(String foo) { - this.foo = foo; - } - - public String getFoo() { - return foo; - } - - @Override - public int hashCode() { - return ObjectUtils.nullSafeHashCode(this.foo); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (!(obj instanceof Foo)) { - return false; - } - Foo other = (Foo) obj; - return ObjectUtils.nullSafeEquals(this.foo, other.foo); - } - - } - - static class Bar { - - String bar; - - public Bar(String bar) { - this.bar = bar; - } - - public String getBar() { - return bar; - } - - @Override - public int hashCode() { - return ObjectUtils.nullSafeHashCode(this.bar); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (!(obj instanceof Bar)) { - return false; - } - Bar other = (Bar) obj; - return ObjectUtils.nullSafeEquals(this.bar, other.bar); - } - - } - - static class ClassWithStringId { - - @Id String id; - String value; - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ObjectUtils.nullSafeHashCode(this.id); - result = prime * result + ObjectUtils.nullSafeHashCode(this.value); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (!(obj instanceof ClassWithStringId)) { - return false; - } - ClassWithStringId other = (ClassWithStringId) obj; - if (!ObjectUtils.nullSafeEquals(this.id, other.id)) { - return false; - } - if (!ObjectUtils.nullSafeEquals(this.value, other.value)) { - return false; - } - return true; - } - - } - - @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 ""; - } -} diff --git a/src/test/java/org/springframework/data/keyvalue/core/SpelPropertyComperatorUnitTests.java b/src/test/java/org/springframework/data/keyvalue/core/SpelPropertyComperatorUnitTests.java deleted file mode 100644 index 15d12e7ae..000000000 --- a/src/test/java/org/springframework/data/keyvalue/core/SpelPropertyComperatorUnitTests.java +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Copyright 2014 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 static java.lang.Integer.*; -import static org.hamcrest.CoreMatchers.*; -import static org.hamcrest.number.OrderingComparison.*; -import static org.junit.Assert.*; - -import java.util.Comparator; - -import org.junit.Test; -import org.springframework.expression.spel.standard.SpelExpressionParser; - -/** - * Unit tests for {@link SpelPropertyComparator}. - * - * @author Christoph Strobl - * @author Oliver Gierke - */ -public class SpelPropertyComperatorUnitTests { - - private static final SpelExpressionParser PARSER = new SpelExpressionParser(); - - private static final SomeType ONE = new SomeType("one", Integer.valueOf(1), 1); - private static final SomeType TWO = new SomeType("two", Integer.valueOf(2), 2); - private static final WrapperType WRAPPER_ONE = new WrapperType("w-one", ONE); - private static final WrapperType WRAPPER_TWO = new WrapperType("w-two", TWO); - - /** - * @see DATACMNS-525 - */ - @Test - public void shouldCompareStringAscCorrectly() { - - Comparator comparator = new SpelPropertyComparator("stringProperty", PARSER); - assertThat(comparator.compare(ONE, TWO), is(ONE.getStringProperty().compareTo(TWO.getStringProperty()))); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void shouldCompareStringDescCorrectly() { - - Comparator comparator = new SpelPropertyComparator("stringProperty", PARSER).desc(); - assertThat(comparator.compare(ONE, TWO), is(TWO.getStringProperty().compareTo(ONE.getStringProperty()))); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void shouldCompareIntegerAscCorrectly() { - - Comparator comparator = new SpelPropertyComparator("integerProperty", PARSER); - assertThat(comparator.compare(ONE, TWO), is(ONE.getIntegerProperty().compareTo(TWO.getIntegerProperty()))); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void shouldCompareIntegerDescCorrectly() { - - Comparator comparator = new SpelPropertyComparator("integerProperty", PARSER).desc(); - assertThat(comparator.compare(ONE, TWO), is(TWO.getIntegerProperty().compareTo(ONE.getIntegerProperty()))); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void shouldComparePrimitiveIntegerAscCorrectly() { - - Comparator comparator = new SpelPropertyComparator("primitiveProperty", PARSER); - assertThat(comparator.compare(ONE, TWO), - is(valueOf(ONE.getPrimitiveProperty()).compareTo(valueOf(TWO.getPrimitiveProperty())))); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void shouldNotFailOnNullValues() { - - Comparator comparator = new SpelPropertyComparator("stringProperty", PARSER); - assertThat(comparator.compare(ONE, new SomeType(null, null, 2)), is(1)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void shouldComparePrimitiveIntegerDescCorrectly() { - - Comparator comparator = new SpelPropertyComparator("primitiveProperty", PARSER).desc(); - assertThat(comparator.compare(ONE, TWO), - is(valueOf(TWO.getPrimitiveProperty()).compareTo(valueOf(ONE.getPrimitiveProperty())))); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void shouldSortNullsFirstCorrectly() { - Comparator comparator = new SpelPropertyComparator("stringProperty", PARSER).nullsFirst(); - assertThat(comparator.compare(ONE, new SomeType(null, null, 2)), equalTo(1)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void shouldSortNullsLastCorrectly() { - - Comparator comparator = new SpelPropertyComparator("stringProperty", PARSER).nullsLast(); - assertThat(comparator.compare(ONE, new SomeType(null, null, 2)), equalTo(-1)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void shouldCompareNestedTypesCorrectly() { - - Comparator comparator = new SpelPropertyComparator("nestedType.stringProperty", PARSER); - assertThat(comparator.compare(WRAPPER_ONE, WRAPPER_TWO), is(WRAPPER_ONE.getNestedType().getStringProperty() - .compareTo(WRAPPER_TWO.getNestedType().getStringProperty()))); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void shouldCompareNestedTypesCorrectlyWhenOneOfThemHasNullValue() { - - SpelPropertyComparator comparator = new SpelPropertyComparator( - "nestedType.stringProperty", PARSER); - assertThat(comparator.compare(WRAPPER_ONE, new WrapperType("two", null)), is(greaterThanOrEqualTo(1))); - } - - static class WrapperType { - - private String stringPropertyWrapper; - private SomeType nestedType; - - public WrapperType(String stringPropertyWrapper, SomeType nestedType) { - this.stringPropertyWrapper = stringPropertyWrapper; - this.nestedType = nestedType; - } - - public String getStringPropertyWrapper() { - return stringPropertyWrapper; - } - - public void setStringPropertyWrapper(String stringPropertyWrapper) { - this.stringPropertyWrapper = stringPropertyWrapper; - } - - public SomeType getNestedType() { - return nestedType; - } - - public void setNestedType(SomeType nestedType) { - this.nestedType = nestedType; - } - - } - - static class SomeType { - - public SomeType() { - - } - - public SomeType(String stringProperty, Integer integerProperty, int primitiveProperty) { - this.stringProperty = stringProperty; - this.integerProperty = integerProperty; - this.primitiveProperty = primitiveProperty; - } - - String stringProperty; - Integer integerProperty; - int primitiveProperty; - - public String getStringProperty() { - return stringProperty; - } - - public void setStringProperty(String stringProperty) { - this.stringProperty = stringProperty; - } - - public Integer getIntegerProperty() { - return integerProperty; - } - - public void setIntegerProperty(Integer integerProperty) { - this.integerProperty = integerProperty; - } - - public int getPrimitiveProperty() { - return primitiveProperty; - } - - public void setPrimitiveProperty(int primitiveProperty) { - this.primitiveProperty = primitiveProperty; - } - - } - -} diff --git a/src/test/java/org/springframework/data/keyvalue/map/MapKeyValueAdapterFactoryUnitTests.java b/src/test/java/org/springframework/data/keyvalue/map/MapKeyValueAdapterFactoryUnitTests.java deleted file mode 100644 index d31c53383..000000000 --- a/src/test/java/org/springframework/data/keyvalue/map/MapKeyValueAdapterFactoryUnitTests.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright 2014 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.map; - -import static org.hamcrest.core.IsEqual.*; -import static org.hamcrest.core.IsInstanceOf.*; -import static org.junit.Assert.*; - -import java.io.Serializable; -import java.util.Collections; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentSkipListMap; - -import org.junit.Test; -import org.springframework.core.CollectionFactory; - -/** - * @author Christoph Strobl - */ -public class MapKeyValueAdapterFactoryUnitTests { - - /** - * @see DATACMNS-525 - */ - @Test - public void shouldDefaultToConcurrentHashMapWhenTypeIsNull() { - - assertThat(new MapKeyValueAdapterFactory(null).getAdapter().getKeySpaceMap("foo"), - instanceOf(ConcurrentHashMap.class)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void shouldDefaultToCollecitonUtilsDefaultForInterfaceTypes() { - - assertThat(new MapKeyValueAdapterFactory(Map.class).getAdapter().getKeySpaceMap("foo"), - instanceOf(CollectionFactory.createMap(Map.class, 0).getClass())); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void shouldUseConcreteMapTypeWhenInstantiable() { - - assertThat(new MapKeyValueAdapterFactory(ConcurrentSkipListMap.class).getAdapter().getKeySpaceMap("foo"), - instanceOf(CollectionFactory.createMap(ConcurrentSkipListMap.class, 0).getClass())); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void shouldPopulateAdapterWithValues() { - - MapKeyValueAdapterFactory factory = new MapKeyValueAdapterFactory(); - factory.setInitialValuesForKeyspace("foo", Collections.singletonMap("1", "STANIS")); - factory.setInitialValuesForKeyspace("bar", Collections.singletonMap("1", "ROBERT")); - - assertThat((String) factory.getAdapter().get("1", "foo"), equalTo("STANIS")); - assertThat((String) factory.getAdapter().get("1", "bar"), equalTo("ROBERT")); - } - - /** - * @see DATACMNS-525 - */ - @Test(expected = IllegalArgumentException.class) - public void shouldThrowExceptionWhenSettingValuesForNullKeySpace() { - new MapKeyValueAdapterFactory().setInitialValuesForKeyspace(null, Collections. emptyMap()); - } - - /** - * @see DATACMNS-525 - */ - @Test(expected = IllegalArgumentException.class) - public void shouldThrowExceptionWhenSettingNullValuesForKeySpace() { - new MapKeyValueAdapterFactory().setInitialValuesForKeyspace("foo", null); - } - -} diff --git a/src/test/java/org/springframework/data/keyvalue/map/MapKeyValueAdapterUnitTests.java b/src/test/java/org/springframework/data/keyvalue/map/MapKeyValueAdapterUnitTests.java deleted file mode 100644 index 1d1bce19f..000000000 --- a/src/test/java/org/springframework/data/keyvalue/map/MapKeyValueAdapterUnitTests.java +++ /dev/null @@ -1,222 +0,0 @@ -/* - * Copyright 2014 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.map; - -import static org.hamcrest.collection.IsIterableContainingInAnyOrder.*; -import static org.hamcrest.core.Is.*; -import static org.hamcrest.core.IsEqual.*; -import static org.hamcrest.core.IsNull.*; -import static org.junit.Assert.*; - -import org.junit.Before; -import org.junit.Test; -import org.springframework.util.ObjectUtils; - -/** - * @author Christoph Strobl - */ -public class MapKeyValueAdapterUnitTests { - - private static final String COLLECTION_1 = "collection-1"; - private static final String COLLECTION_2 = "collection-2"; - private static final String STRING_1 = new String("1"); - - private Object object1 = new SimpleObject("one"); - private Object object2 = new SimpleObject("two"); - - private MapKeyValueAdapter adapter; - - @Before - public void setUp() { - this.adapter = new MapKeyValueAdapter(); - } - - /** - * @see DATACMNS-525 - */ - @Test(expected = IllegalArgumentException.class) - public void putShouldThrowExceptionWhenAddingNullId() { - adapter.put(null, object1, COLLECTION_1); - } - - /** - * @see DATACMNS-525 - */ - @Test(expected = IllegalArgumentException.class) - public void putShouldThrowExceptionWhenCollectionIsNullValue() { - adapter.put("1", object1, null); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void putReturnsNullWhenNoObjectForIdPresent() { - assertThat(adapter.put("1", object1, COLLECTION_1), nullValue()); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void putShouldReturnPreviousObjectForIdWhenAddingNewOneWithSameIdPresent() { - - adapter.put("1", object1, COLLECTION_1); - assertThat(adapter.put("1", object2, COLLECTION_1), equalTo(object1)); - } - - /** - * @see DATACMNS-525 - */ - @Test(expected = IllegalArgumentException.class) - public void containsShouldThrowExceptionWhenIdIsNull() { - adapter.contains(null, COLLECTION_1); - } - - /** - * @see DATACMNS-525 - */ - @Test(expected = IllegalArgumentException.class) - public void containsShouldThrowExceptionWhenTypeIsNull() { - adapter.contains("", null); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void containsShouldReturnFalseWhenNoElementsPresent() { - assertThat(adapter.contains("1", COLLECTION_1), is(false)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void containShouldReturnTrueWhenElementWithIdPresent() { - - adapter.put("1", object1, COLLECTION_1); - assertThat(adapter.contains("1", COLLECTION_1), is(true)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void getShouldReturnNullWhenNoElementWithIdPresent() { - assertThat(adapter.get("1", COLLECTION_1), nullValue()); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void getShouldReturnElementWhenMatchingIdPresent() { - - adapter.put("1", object1, COLLECTION_1); - assertThat(adapter.get("1", COLLECTION_1), is(object1)); - } - - /** - * @see DATACMNS-525 - */ - @Test(expected = IllegalArgumentException.class) - public void getShouldThrowExceptionWhenIdIsNull() { - adapter.get(null, COLLECTION_1); - } - - /** - * @see DATACMNS-525 - */ - @Test(expected = IllegalArgumentException.class) - public void getShouldThrowExceptionWhenTypeIsNull() { - adapter.get("1", null); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void getAllOfShouldReturnAllValuesOfGivenCollection() { - - adapter.put("1", object1, COLLECTION_1); - adapter.put("2", object2, COLLECTION_1); - adapter.put("3", STRING_1, COLLECTION_2); - - assertThat(adapter.getAllOf(COLLECTION_1), containsInAnyOrder(object1, object2)); - } - - /** - * @see DATACMNS-525 - */ - @Test(expected = IllegalArgumentException.class) - public void getAllOfShouldThrowExceptionWhenTypeIsNull() { - adapter.getAllOf(null); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void deleteShouldReturnNullWhenGivenIdThatDoesNotExist() { - assertThat(adapter.delete("1", COLLECTION_1), nullValue()); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void deleteShouldReturnDeletedObject() { - - adapter.put("1", object1, COLLECTION_1); - assertThat(adapter.delete("1", COLLECTION_1), is(object1)); - } - - static class SimpleObject { - - protected String stringValue; - - public SimpleObject() {} - - SimpleObject(String value) { - this.stringValue = value; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * ObjectUtils.nullSafeHashCode(this.stringValue); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (!(obj instanceof SimpleObject)) { - return false; - } - SimpleObject that = (SimpleObject) obj; - return ObjectUtils.nullSafeEquals(this.stringValue, that.stringValue); - } - } - -} diff --git a/src/test/java/org/springframework/data/keyvalue/map/QueryDslMapRepositoryUnitTests.java b/src/test/java/org/springframework/data/keyvalue/map/QueryDslMapRepositoryUnitTests.java deleted file mode 100644 index 4927f33a7..000000000 --- a/src/test/java/org/springframework/data/keyvalue/map/QueryDslMapRepositoryUnitTests.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright 2014 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.map; - -import static org.hamcrest.collection.IsCollectionWithSize.*; -import static org.hamcrest.collection.IsIterableContainingInAnyOrder.*; -import static org.hamcrest.collection.IsIterableContainingInOrder.*; -import static org.hamcrest.core.Is.*; -import static org.junit.Assert.*; - -import org.junit.Test; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Sort.Direction; -import org.springframework.data.keyvalue.Person; -import org.springframework.data.keyvalue.QPerson; -import org.springframework.data.querydsl.QSort; -import org.springframework.data.querydsl.QueryDslPredicateExecutor; - -/** - * @author Christoph Strobl - */ -public class QueryDslMapRepositoryUnitTests extends SimpleKeyValueRepositoryUnitTests { - - /** - * @see DATACMNS-525 - */ - @Test - public void findOneIsExecutedCorrectly() { - - repository.save(LENNISTERS); - - Person result = getQPersonRepo().findOne(QPerson.person.firstname.eq(CERSEI.getFirstname())); - assertThat(result, is(CERSEI)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void findAllIsExecutedCorrectly() { - - repository.save(LENNISTERS); - - Iterable result = getQPersonRepo().findAll(QPerson.person.age.eq(CERSEI.getAge())); - assertThat(result, containsInAnyOrder(CERSEI, JAIME)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void findWithPaginationWorksCorrectly() { - - repository.save(LENNISTERS); - Page page1 = getQPersonRepo().findAll(QPerson.person.age.eq(CERSEI.getAge()), new PageRequest(0, 1)); - - assertThat(page1.getTotalElements(), is(2L)); - assertThat(page1.getContent(), hasSize(1)); - assertThat(page1.hasNext(), is(true)); - - Page page2 = ((QPersonRepository) repository).findAll(QPerson.person.age.eq(CERSEI.getAge()), - page1.nextPageable()); - - assertThat(page2.getTotalElements(), is(2L)); - assertThat(page2.getContent(), hasSize(1)); - assertThat(page2.hasNext(), is(false)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void findAllUsingOrderSpecifierWorksCorrectly() { - - repository.save(LENNISTERS); - - Iterable result = getQPersonRepo().findAll(QPerson.person.age.eq(CERSEI.getAge()), - QPerson.person.firstname.desc()); - - assertThat(result, contains(JAIME, CERSEI)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void findAllUsingPageableWithSortWorksCorrectly() { - - repository.save(LENNISTERS); - - Iterable result = getQPersonRepo().findAll(QPerson.person.age.eq(CERSEI.getAge()), - new PageRequest(0, 10, Direction.DESC, "firstname")); - - assertThat(result, contains(JAIME, CERSEI)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void findAllUsingPagableWithQSortWorksCorrectly() { - - repository.save(LENNISTERS); - - Iterable result = getQPersonRepo().findAll(QPerson.person.age.eq(CERSEI.getAge()), - new PageRequest(0, 10, new QSort(QPerson.person.firstname.desc()))); - - assertThat(result, contains(JAIME, CERSEI)); - } - - @Override - protected Class getRepositoryClass() { - return QPersonRepository.class; - } - - QPersonRepository getQPersonRepo() { - return ((QPersonRepository) repository); - } - - static interface QPersonRepository extends PersonRepository, QueryDslPredicateExecutor { - - } - -} diff --git a/src/test/java/org/springframework/data/keyvalue/map/SimpleKeyValueRepositoryUnitTests.java b/src/test/java/org/springframework/data/keyvalue/map/SimpleKeyValueRepositoryUnitTests.java deleted file mode 100644 index d5575727f..000000000 --- a/src/test/java/org/springframework/data/keyvalue/map/SimpleKeyValueRepositoryUnitTests.java +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright 2014 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.map; - -import static org.hamcrest.collection.IsIterableContainingInAnyOrder.*; -import static org.hamcrest.collection.IsIterableContainingInOrder.*; -import static org.hamcrest.core.Is.*; -import static org.junit.Assert.*; - -import java.util.Arrays; -import java.util.List; - -import org.hamcrest.collection.IsCollectionWithSize; -import org.hamcrest.collection.IsIterableContainingInOrder; -import org.junit.Before; -import org.junit.Test; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; -import org.springframework.data.domain.Sort.Direction; -import org.springframework.data.keyvalue.Person; -import org.springframework.data.keyvalue.core.KeyValueTemplate; -import org.springframework.data.keyvalue.repository.KeyValueRepository; -import org.springframework.data.keyvalue.repository.support.KeyValueRepositoryFactory; -import org.springframework.data.repository.CrudRepository; - -/** - * @author Christoph Strobl - */ -public class SimpleKeyValueRepositoryUnitTests { - - protected static final Person CERSEI = new Person("cersei", 19); - protected static final Person JAIME = new Person("jaime", 19); - protected static final Person TYRION = new Person("tyrion", 17); - - protected static List LENNISTERS = Arrays.asList(CERSEI, JAIME, TYRION); - - protected PersonRepository repository; - protected KeyValueTemplate template = new KeyValueTemplate(new MapKeyValueAdapter()); - - @Before - public void setup() { - this.repository = new KeyValueRepositoryFactory(template).getRepository(getRepositoryClass()); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void findBy() { - - this.repository.save(LENNISTERS); - assertThat(this.repository.findByAge(19), containsInAnyOrder(CERSEI, JAIME)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void combindedFindUsingAnd() { - - this.repository.save(LENNISTERS); - - assertThat(this.repository.findByFirstnameAndAge(JAIME.getFirstname(), 19), containsInAnyOrder(JAIME)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void findPage() { - - this.repository.save(LENNISTERS); - - Page page = this.repository.findByAge(19, new PageRequest(0, 1)); - assertThat(page.hasNext(), is(true)); - assertThat(page.getTotalElements(), is(2L)); - assertThat(page.getContent(), IsCollectionWithSize.hasSize(1)); - - Page next = this.repository.findByAge(19, page.nextPageable()); - assertThat(next.hasNext(), is(false)); - assertThat(next.getTotalElements(), is(2L)); - assertThat(next.getContent(), IsCollectionWithSize.hasSize(1)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void findByConnectingOr() { - - this.repository.save(LENNISTERS); - - assertThat(this.repository.findByAgeOrFirstname(19, TYRION.getFirstname()), - containsInAnyOrder(CERSEI, JAIME, TYRION)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void singleEntityExecution() { - - this.repository.save(LENNISTERS); - - assertThat(this.repository.findByAgeAndFirstname(TYRION.getAge(), TYRION.getFirstname()), is(TYRION)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void findAllShouldRespectSort() { - - this.repository.save(LENNISTERS); - - assertThat(this.repository.findAll(new Sort(new Sort.Order(Direction.ASC, "age"), new Sort.Order(Direction.DESC, - "firstname"))), IsIterableContainingInOrder.contains(TYRION, JAIME, CERSEI)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void derivedFinderShouldRespectSort() { - - repository.save(LENNISTERS); - - List result = repository.findByAgeGreaterThanOrderByAgeAscFirstnameDesc(2); - - assertThat(result, contains(TYRION, JAIME, CERSEI)); - } - - protected Class getRepositoryClass() { - return PersonRepository.class; - } - - public static interface PersonRepository extends CrudRepository, KeyValueRepository { - - List findByAge(int age); - - List findByFirstname(String firstname); - - List findByFirstnameAndAge(String firstname, int age); - - Page findByAge(int age, Pageable page); - - List findByAgeOrFirstname(int age, String firstname); - - Person findByAgeAndFirstname(int age, String firstname); - - List findByAgeGreaterThanOrderByAgeAscFirstnameDesc(int age); - - } - -} diff --git a/src/test/java/org/springframework/data/keyvalue/repository/SimpleKeyValueRepositoryUnitTests.java b/src/test/java/org/springframework/data/keyvalue/repository/SimpleKeyValueRepositoryUnitTests.java deleted file mode 100644 index 0c6935bb2..000000000 --- a/src/test/java/org/springframework/data/keyvalue/repository/SimpleKeyValueRepositoryUnitTests.java +++ /dev/null @@ -1,247 +0,0 @@ -/* - * Copyright 2014 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.repository; - -import static org.mockito.Matchers.*; -import static org.mockito.Mockito.*; - -import java.util.Arrays; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; -import org.springframework.data.annotation.Id; -import org.springframework.data.annotation.Persistent; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; -import org.springframework.data.keyvalue.core.KeyValueOperations; -import org.springframework.data.keyvalue.repository.support.SimpleKeyValueRepository; -import org.springframework.data.repository.core.support.ReflectionEntityInformation; - -/** - * @author Christoph Strobl - */ -@RunWith(MockitoJUnitRunner.class) -public class SimpleKeyValueRepositoryUnitTests { - - private SimpleKeyValueRepository repo; - private @Mock KeyValueOperations opsMock; - - @Before - public void setUp() { - - ReflectionEntityInformation ei = new ReflectionEntityInformation(Foo.class); - repo = new SimpleKeyValueRepository(ei, opsMock); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void saveNewWithNumericId() { - - ReflectionEntityInformation ei = new ReflectionEntityInformation( - WithNumericId.class); - SimpleKeyValueRepository temp = new SimpleKeyValueRepository(ei, - opsMock); - - WithNumericId withNumericId = new WithNumericId(); - temp.save(withNumericId); - - verify(opsMock, times(1)).insert(eq(withNumericId)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void testDoubleSave() { - - Foo foo = new Foo("one"); - - repo.save(foo); - - foo.id = "1"; - repo.save(foo); - verify(opsMock, times(1)).insert(eq(foo)); - verify(opsMock, times(1)).update(eq(foo.getId()), eq(foo)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void multipleSave() { - - Foo one = new Foo("one"); - Foo two = new Foo("one"); - - repo.save(Arrays.asList(one, two)); - verify(opsMock, times(1)).insert(eq(one)); - verify(opsMock, times(1)).insert(eq(two)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void deleteEntity() { - - Foo one = repo.save(new Foo("one")); - repo.delete(one); - - verify(opsMock, times(1)).delete(eq(one.getId()), eq(Foo.class)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void deleteById() { - - repo.delete("one"); - - verify(opsMock, times(1)).delete(eq("one"), eq(Foo.class)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void deleteAll() { - - repo.deleteAll(); - - verify(opsMock, times(1)).delete(eq(Foo.class)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void findAllIds() { - - repo.findAll(Arrays.asList("one", "two", "three")); - - verify(opsMock, times(3)).findById(anyString(), eq(Foo.class)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void findAllWithPageableShouldDelegateToOperationsCorrectlyWhenPageableDoesNotContainSort() { - - repo.findAll(new PageRequest(10, 15)); - - verify(opsMock, times(1)).findInRange(eq(150), eq(15), isNull(Sort.class), eq(Foo.class)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void findAllWithPageableShouldDelegateToOperationsCorrectlyWhenPageableContainsSort() { - - Sort sort = new Sort("for", "bar"); - repo.findAll(new PageRequest(10, 15, sort)); - - verify(opsMock, times(1)).findInRange(eq(150), eq(15), eq(sort), eq(Foo.class)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void findAllShouldFallbackToFindAllOfWhenGivenNullPageable() { - - repo.findAll((Pageable) null); - - verify(opsMock, times(1)).findAll(eq(Foo.class)); - } - - static class Foo { - - private @Id String id; - private Long longValue; - private String name; - private Bar bar; - - public Foo() { - - } - - public Foo(String name) { - this.name = name; - } - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public Long getLongValue() { - return longValue; - } - - public void setLongValue(Long longValue) { - this.longValue = longValue; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public Bar getBar() { - return bar; - } - - public void setBar(Bar bar) { - this.bar = bar; - } - - } - - static class Bar { - - private String bar; - - public String getBar() { - return bar; - } - - public void setBar(String bar) { - this.bar = bar; - } - } - - @Persistent - static class WithNumericId { - - @Id Integer id; - - } -} diff --git a/src/test/java/org/springframework/data/keyvalue/repository/config/KeyValueRepositoryRegistrarIntegrationTests.java b/src/test/java/org/springframework/data/keyvalue/repository/config/KeyValueRepositoryRegistrarIntegrationTests.java deleted file mode 100644 index 84ead9488..000000000 --- a/src/test/java/org/springframework/data/keyvalue/repository/config/KeyValueRepositoryRegistrarIntegrationTests.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright 2014 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.repository.config; - -import static org.hamcrest.core.IsNull.*; -import static org.junit.Assert.*; - -import java.util.List; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.data.annotation.Id; -import org.springframework.data.keyvalue.core.KeyValueOperations; -import org.springframework.data.keyvalue.core.KeyValueTemplate; -import org.springframework.data.keyvalue.map.MapKeyValueAdapter; -import org.springframework.data.repository.CrudRepository; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -/** - * @author Christoph Strobl - */ -@RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration -public class KeyValueRepositoryRegistrarIntegrationTests { - - @Configuration - @EnableKeyValueRepositories(considerNestedRepositories = true) - static class Config { - - @Bean - public KeyValueOperations keyValueTemplate() { - return new KeyValueTemplate(new MapKeyValueAdapter()); - } - } - - @Autowired PersonRepository repo; - - /** - * @see DATACMNS-525 - */ - @Test - public void shouldEnableKeyValueRepositoryCorrectly() { - assertThat(repo, notNullValue()); - } - - static class Person { - - @Id String id; - String firstname; - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public String getFirstname() { - return firstname; - } - - public void setFirstname(String firstname) { - this.firstname = firstname; - } - - } - - static interface PersonRepository extends CrudRepository { - - List findByFirstname(String firstname); - - } - -} diff --git a/src/test/java/org/springframework/data/keyvalue/repository/query/SpelQueryCreatorUnitTests.java b/src/test/java/org/springframework/data/keyvalue/repository/query/SpelQueryCreatorUnitTests.java deleted file mode 100644 index 20c0a6171..000000000 --- a/src/test/java/org/springframework/data/keyvalue/repository/query/SpelQueryCreatorUnitTests.java +++ /dev/null @@ -1,566 +0,0 @@ -/* - * Copyright 2014 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.repository.query; - -import static org.hamcrest.core.Is.*; -import static org.junit.Assert.*; - -import java.lang.reflect.Method; -import java.util.Date; - -import org.joda.time.format.DateTimeFormatter; -import org.joda.time.format.ISODateTimeFormat; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; -import org.springframework.dao.InvalidDataAccessApiUsageException; -import org.springframework.data.annotation.Id; -import org.springframework.data.keyvalue.core.query.KeyValueQuery; -import org.springframework.data.repository.core.RepositoryMetadata; -import org.springframework.data.repository.query.ParametersParameterAccessor; -import org.springframework.data.repository.query.QueryMethod; -import org.springframework.data.repository.query.parser.PartTree; -import org.springframework.expression.spel.standard.SpelExpression; -import org.springframework.expression.spel.support.StandardEvaluationContext; -import org.springframework.util.ObjectUtils; - -/** - * @author Christoph Strobl - */ -@RunWith(MockitoJUnitRunner.class) -public class SpelQueryCreatorUnitTests { - - static final DateTimeFormatter FORMATTER = ISODateTimeFormat.dateTimeNoMillis().withZoneUTC(); - - static final Person RICKON = new Person("rickon", 4); - static final Person BRAN = new Person("bran", 9)// - .skinChanger(true)// - .bornAt(FORMATTER.parseDateTime("2013-01-31T06:00:00Z").toDate()); - static final Person ARYA = new Person("arya", 13); - static final Person ROBB = new Person("robb", 16)// - .named("stark")// - .bornAt(FORMATTER.parseDateTime("2010-09-20T06:00:00Z").toDate()); - static final Person JON = new Person("jon", 17).named("snow"); - - @Mock RepositoryMetadata metadataMock; - - /** - * @see DATACMNS-525 - */ - @Test - public void equalsReturnsTrueWhenMatching() throws Exception { - assertThat(evaluate("findByFirstname", BRAN.firstname).against(BRAN), is(true)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void equalsReturnsFalseWhenNotMatching() throws Exception { - assertThat(evaluate("findByFirstname", BRAN.firstname).against(RICKON), is(false)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void isTrueAssertedPropertlyWhenTrue() throws Exception { - assertThat(evaluate("findBySkinChangerIsTrue").against(BRAN), is(true)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void isTrueAssertedPropertlyWhenFalse() throws Exception { - assertThat(evaluate("findBySkinChangerIsTrue").against(RICKON), is(false)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void isFalseAssertedPropertlyWhenTrue() throws Exception { - assertThat(evaluate("findBySkinChangerIsFalse").against(BRAN), is(false)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void isFalseAssertedPropertlyWhenFalse() throws Exception { - assertThat(evaluate("findBySkinChangerIsFalse").against(RICKON), is(true)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void isNullAssertedPropertlyWhenAttributeIsNull() throws Exception { - assertThat(evaluate("findByLastnameIsNull").against(BRAN), is(true)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void isNullAssertedPropertlyWhenAttributeIsNotNull() throws Exception { - assertThat(evaluate("findByLastnameIsNull").against(ROBB), is(false)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void isNotNullFalseTrueWhenAttributeIsNull() throws Exception { - assertThat(evaluate("findByLastnameIsNotNull").against(BRAN), is(false)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void isNotNullReturnsTrueAttributeIsNotNull() throws Exception { - assertThat(evaluate("findByLastnameIsNotNull").against(ROBB), is(true)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void startsWithReturnsTrueWhenMatching() throws Exception { - assertThat(evaluate("findByFirstnameStartingWith", "r").against(ROBB), is(true)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void startsWithReturnsFalseWhenNotMatching() throws Exception { - assertThat(evaluate("findByFirstnameStartingWith", "r").against(BRAN), is(false)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void likeReturnsTrueWhenMatching() throws Exception { - assertThat(evaluate("findByFirstnameLike", "ob").against(ROBB), is(true)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void likeReturnsFalseWhenNotMatching() throws Exception { - assertThat(evaluate("findByFirstnameLike", "ra").against(ROBB), is(false)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void endsWithReturnsTrueWhenMatching() throws Exception { - assertThat(evaluate("findByFirstnameEndingWith", "bb").against(ROBB), is(true)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void endsWithReturnsFalseWhenNotMatching() throws Exception { - assertThat(evaluate("findByFirstnameEndingWith", "an").against(ROBB), is(false)); - } - - /** - * @see DATACMNS-525 - */ - @Test(expected = InvalidDataAccessApiUsageException.class) - public void startsWithIgnoreCaseReturnsTrueWhenMatching() throws Exception { - assertThat(evaluate("findByFirstnameIgnoreCase", "R").against(ROBB), is(true)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void greaterThanReturnsTrueForHigherValues() throws Exception { - assertThat(evaluate("findByAgeGreaterThan", BRAN.age).against(ROBB), is(true)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void greaterThanReturnsFalseForLowerValues() throws Exception { - assertThat(evaluate("findByAgeGreaterThan", BRAN.age).against(RICKON), is(false)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void afterReturnsTrueForHigherValues() throws Exception { - assertThat(evaluate("findByBirthdayAfter", ROBB.birthday).against(BRAN), is(true)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void afterReturnsFalseForLowerValues() throws Exception { - assertThat(evaluate("findByBirthdayAfter", BRAN.birthday).against(ROBB), is(false)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void greaterThanEaualsReturnsTrueForHigherValues() throws Exception { - assertThat(evaluate("findByAgeGreaterThanEqual", BRAN.age).against(ROBB), is(true)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void greaterThanEaualsReturnsTrueForEqualValues() throws Exception { - assertThat(evaluate("findByAgeGreaterThanEqual", BRAN.age).against(BRAN), is(true)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void greaterThanEqualsReturnsFalseForLowerValues() throws Exception { - assertThat(evaluate("findByAgeGreaterThanEqual", BRAN.age).against(RICKON), is(false)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void lessThanReturnsTrueForHigherValues() throws Exception { - assertThat(evaluate("findByAgeLessThan", BRAN.age).against(ROBB), is(false)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void lessThanReturnsFalseForLowerValues() throws Exception { - assertThat(evaluate("findByAgeLessThan", BRAN.age).against(RICKON), is(true)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void beforeReturnsTrueForLowerValues() throws Exception { - assertThat(evaluate("findByBirthdayBefore", BRAN.birthday).against(ROBB), is(true)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void beforeReturnsFalseForHigherValues() throws Exception { - assertThat(evaluate("findByBirthdayBefore", ROBB.birthday).against(BRAN), is(false)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void lessThanEaualsReturnsTrueForHigherValues() throws Exception { - assertThat(evaluate("findByAgeLessThanEqual", BRAN.age).against(ROBB), is(false)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void lessThanEaualsReturnsTrueForEqualValues() throws Exception { - assertThat(evaluate("findByAgeLessThanEqual", BRAN.age).against(BRAN), is(true)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void lessThanEqualsReturnsFalseForLowerValues() throws Exception { - assertThat(evaluate("findByAgeLessThanEqual", BRAN.age).against(RICKON), is(true)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void betweenEqualsReturnsTrueForValuesInBetween() throws Exception { - assertThat(evaluate("findByAgeBetween", BRAN.age, ROBB.age).against(ARYA), is(true)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void betweenEqualsReturnsFalseForHigherValues() throws Exception { - assertThat(evaluate("findByAgeBetween", BRAN.age, ROBB.age).against(JON), is(false)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void betweenEqualsReturnsFalseForLowerValues() throws Exception { - assertThat(evaluate("findByAgeBetween", BRAN.age, ROBB.age).against(RICKON), is(false)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void connectByAndReturnsTrueWhenAllPropertiesMatching() throws Exception { - assertThat(evaluate("findByAgeGreaterThanAndLastname", BRAN.age, JON.lastname).against(JON), is(true)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void connectByAndReturnsFalseWhenOnlyFewPropertiesMatch() throws Exception { - assertThat(evaluate("findByAgeGreaterThanAndLastname", BRAN.age, JON.lastname).against(ROBB), is(false)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void connectByOrReturnsTrueWhenOnlyFewPropertiesMatch() throws Exception { - assertThat(evaluate("findByAgeGreaterThanOrLastname", BRAN.age, JON.lastname).against(ROBB), is(true)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void connectByOrReturnsTrueWhenAllPropertiesMatch() throws Exception { - assertThat(evaluate("findByAgeGreaterThanOrLastname", BRAN.age, JON.lastname).against(JON), is(true)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void regexReturnsTrueWhenMatching() throws Exception { - assertThat(evaluate("findByLastnameMatches", "^s.*w$").against(JON), is(true)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void regexReturnsFalseWhenNotMatching() throws Exception { - assertThat(evaluate("findByLastnameMatches", "^s.*w$").against(ROBB), is(false)); - } - - private Evaluation evaluate(String methodName, Object... args) throws Exception { - return new Evaluation((SpelExpression) createQueryForMethodWithArgs(methodName, args).getCritieria()); - } - - private KeyValueQuery createQueryForMethodWithArgs(String methodName, Object... args) - throws NoSuchMethodException, SecurityException { - - Class[] argTypes = new Class[args.length]; - if (!ObjectUtils.isEmpty(args)) { - - for (int i = 0; i < args.length; i++) { - argTypes[i] = args[i].getClass(); - } - } - - Method method = PersonRepository.class.getMethod(methodName, argTypes); - - PartTree partTree = new PartTree(method.getName(), method.getReturnType()); - SpelQueryCreator creator = new SpelQueryCreator(partTree, new ParametersParameterAccessor(new QueryMethod(method, - metadataMock).getParameters(), args)); - - KeyValueQuery q = creator.createQuery(); - q.getCritieria().setEvaluationContext(new StandardEvaluationContext(args)); - - return q; - } - - static interface PersonRepository { - - // Type.SIMPLE_PROPERTY - Person findByFirstname(String firstname); - - // Type.TRUE - Person findBySkinChangerIsTrue(); - - // Type.FALSE - Person findBySkinChangerIsFalse(); - - // Type.IS_NULL - Person findByLastnameIsNull(); - - // Type.IS_NOT_NULL - Person findByLastnameIsNotNull(); - - // Type.STARTING_WITH - Person findByFirstnameStartingWith(String firstanme); - - Person findByFirstnameIgnoreCase(String firstanme); - - // Type.AFTER - Person findByBirthdayAfter(Date date); - - // Type.GREATHER_THAN - Person findByAgeGreaterThan(Integer age); - - // Type.GREATER_THAN_EQUAL - Person findByAgeGreaterThanEqual(Integer age); - - // Type.BEFORE - Person findByBirthdayBefore(Date date); - - // Type.LESS_THAN - Person findByAgeLessThan(Integer age); - - // Type.LESS_THAN_EQUAL - Person findByAgeLessThanEqual(Integer age); - - // Type.BETWEEN - Person findByAgeBetween(Integer low, Integer high); - - // Type.LIKE - Person findByFirstnameLike(String firstname); - - // Type.ENDING_WITH - Person findByFirstnameEndingWith(String firstname); - - Person findByAgeGreaterThanAndLastname(Integer age, String lastname); - - Person findByAgeGreaterThanOrLastname(Integer age, String lastname); - - // Type.REGEX - Person findByLastnameMatches(String lastname); - - } - - static class Evaluation { - - SpelExpression expression; - Object candidate; - - public Evaluation(SpelExpression expresison) { - this.expression = expresison; - } - - public Boolean against(Object candidate) { - this.candidate = candidate; - return evaluate(); - } - - private boolean evaluate() { - expression.getEvaluationContext().setVariable("it", candidate); - return expression.getValue(Boolean.class); - } - - } - - static class Person { - - private @Id String id; - private String firstname, lastname; - private int age; - private boolean isSkinChanger = false; - private Date birthday; - - public Person() {} - - public Person(String firstname, int age) { - super(); - this.firstname = firstname; - this.age = age; - } - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public String getFirstname() { - return firstname; - } - - public void setFirstname(String firstname) { - this.firstname = firstname; - } - - public String getLastname() { - return lastname; - } - - public void setLastname(String lastname) { - this.lastname = lastname; - } - - public int getAge() { - return age; - } - - public void setAge(int age) { - this.age = age; - } - - public Date getBirthday() { - return birthday; - } - - public void setBirthday(Date birthday) { - this.birthday = birthday; - } - - public boolean isSkinChanger() { - return isSkinChanger; - } - - public void setSkinChanger(boolean isSkinChanger) { - this.isSkinChanger = isSkinChanger; - } - - public Person skinChanger(boolean isSkinChanger) { - this.isSkinChanger = isSkinChanger; - return this; - } - - public Person named(String lastname) { - this.lastname = lastname; - return this; - } - - public Person bornAt(Date date) { - this.birthday = date; - return this; - } - } -} diff --git a/src/test/java/org/springframework/data/keyvalue/repository/support/QueryDslUtilsUnitTests.java b/src/test/java/org/springframework/data/keyvalue/repository/support/QueryDslUtilsUnitTests.java deleted file mode 100644 index 478e4534f..000000000 --- a/src/test/java/org/springframework/data/keyvalue/repository/support/QueryDslUtilsUnitTests.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright 2014 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.repository.support; - -import static org.hamcrest.collection.IsArrayWithSize.*; -import static org.junit.Assert.*; -import static org.springframework.data.keyvalue.repository.support.KeyValueQueryDslUtils.*; - -import org.hamcrest.collection.IsArrayContainingInOrder; -import org.junit.Before; -import org.junit.Test; -import org.springframework.data.domain.Sort; -import org.springframework.data.domain.Sort.Direction; -import org.springframework.data.domain.Sort.NullHandling; -import org.springframework.data.keyvalue.Person; -import org.springframework.data.keyvalue.QPerson; -import org.springframework.data.querydsl.SimpleEntityPathResolver; - -import com.mysema.query.types.EntityPath; -import com.mysema.query.types.OrderSpecifier; -import com.mysema.query.types.path.PathBuilder; - -/** - * @author Christoph Strobl - * @author Thomas Darimont - */ -public class QueryDslUtilsUnitTests { - - private EntityPath path; - private PathBuilder builder; - - @Before - public void setUp() { - - this.path = SimpleEntityPathResolver.INSTANCE.createPath(Person.class); - this.builder = new PathBuilder(path.getType(), path.getMetadata()); - } - - /** - * @see DATACMNS-525 - */ - @Test(expected = IllegalArgumentException.class) - public void toOrderSpecifierThrowsExceptioOnNullPathBuilder() { - toOrderSpecifier(new Sort("firstname"), null); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void toOrderSpecifierReturnsEmptyArrayWhenSortIsNull() { - assertThat(toOrderSpecifier(null, builder), arrayWithSize(0)); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void toOrderSpecifierConvertsSimpleAscSortCorrectly() { - - Sort sort = new Sort(Direction.ASC, "firstname"); - - OrderSpecifier[] specifiers = toOrderSpecifier(sort, builder); - - assertThat(specifiers, IsArrayContainingInOrder.> arrayContaining(QPerson.person.firstname.asc())); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void toOrderSpecifierConvertsSimpleDescSortCorrectly() { - - Sort sort = new Sort(Direction.DESC, "firstname"); - - OrderSpecifier[] specifiers = toOrderSpecifier(sort, builder); - - assertThat(specifiers, - IsArrayContainingInOrder.> arrayContaining(QPerson.person.firstname.desc())); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void toOrderSpecifierConvertsSortCorrectlyAndRetainsArgumentOrder() { - - Sort sort = new Sort(Direction.DESC, "firstname").and(new Sort(Direction.ASC, "age")); - - OrderSpecifier[] specifiers = toOrderSpecifier(sort, builder); - - assertThat(specifiers, IsArrayContainingInOrder.> arrayContaining( - QPerson.person.firstname.desc(), QPerson.person.age.asc())); - } - - /** - * @see DATACMNS-525 - */ - @Test - public void toOrderSpecifierConvertsSortWithNullHandlingCorrectly() { - - Sort sort = new Sort(new Sort.Order(Direction.DESC, "firstname", NullHandling.NULLS_LAST)); - - OrderSpecifier[] specifiers = toOrderSpecifier(sort, builder); - - assertThat(specifiers, - IsArrayContainingInOrder.> arrayContaining(QPerson.person.firstname.desc().nullsLast())); - } -}