From bc88cb48ace8b6e26076d617e121d0717f9d4fc0 Mon Sep 17 00:00:00 2001 From: Oliver Gierke Date: Fri, 5 Dec 2014 19:14:06 +0100 Subject: [PATCH] DATAKV-87 - Polished implementation of configurability of Map type on @EnableMapRepositories. Removed the MapKeyValueAdapterFactory in favor of using instantiating MapKeyValueAdapters directly. Reverted additional hook in KeyValueRepositoryConfigurationExtension as we now rather use inner bean definitions. Original pull request: #2. --- ...ValueRepositoryConfigurationExtension.java | 18 +-- .../data/map/MapKeyValueAdapter.java | 59 ++++++--- .../data/map/MapKeyValueAdapterFactory.java | 121 ------------------ .../config/EnableMapRepositories.java | 6 +- .../MapRepositoryConfigurationExtension.java | 50 ++------ .../MapKeyValueAdapterFactoryUnitTests.java | 96 -------------- ...onfigurationExtensionIntegrationTests.java | 59 +++------ 7 files changed, 77 insertions(+), 332 deletions(-) delete mode 100644 src/main/java/org/springframework/data/map/MapKeyValueAdapterFactory.java delete mode 100644 src/test/java/org/springframework/data/map/MapKeyValueAdapterFactoryUnitTests.java 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 index 1085adc..30b148c 100644 --- a/src/main/java/org/springframework/data/keyvalue/repository/config/KeyValueRepositoryConfigurationExtension.java +++ b/src/main/java/org/springframework/data/keyvalue/repository/config/KeyValueRepositoryConfigurationExtension.java @@ -19,12 +19,12 @@ import java.util.Collection; import java.util.Collections; import java.util.Map; +import org.springframework.beans.factory.support.AbstractBeanDefinition; 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.KeyValueAdapter; import org.springframework.data.keyvalue.core.mapping.context.KeyValueMappingContext; import org.springframework.data.keyvalue.repository.KeyValueRepository; import org.springframework.data.keyvalue.repository.query.SpelQueryCreator; @@ -136,8 +136,7 @@ public abstract class KeyValueRepositoryConfigurationExtension extends Repositor if (getDefaultKeyValueTemplateRef().equals(keyValueTemplateName) && !registry.containsBeanDefinition(keyValueTemplateName)) { - registerTemplateInfrastructure(registry, configurationSource); - RootBeanDefinition beanDefinition = getDefaultKeyValueTemplateBeanDefinition(configurationSource); + AbstractBeanDefinition beanDefinition = getDefaultKeyValueTemplateBeanDefinition(configurationSource); if (beanDefinition != null) { registerIfNotAlreadyRegistered(beanDefinition, registry, keyValueTemplateName, configurationSource.getSource()); @@ -145,23 +144,12 @@ public abstract class KeyValueRepositoryConfigurationExtension extends Repositor } } - /** - * Register infrastructure components such as {@link KeyValueAdapter} required for default template. - * - * @param registry - * @param configurationSource - */ - protected void registerTemplateInfrastructure(BeanDefinitionRegistry registry, - RepositoryConfigurationSource configurationSource) { - // nothing to register by default - } - /** * Get the default {@link RootBeanDefinition} for {@link org.springframework.data.keyvalue.core.KeyValueTemplate}. * * @return {@literal null} to explicitly not register a template. */ - protected RootBeanDefinition getDefaultKeyValueTemplateBeanDefinition( + protected AbstractBeanDefinition getDefaultKeyValueTemplateBeanDefinition( RepositoryConfigurationSource configurationSource) { return null; } diff --git a/src/main/java/org/springframework/data/map/MapKeyValueAdapter.java b/src/main/java/org/springframework/data/map/MapKeyValueAdapter.java index 3a6173a..392a1c0 100644 --- a/src/main/java/org/springframework/data/map/MapKeyValueAdapter.java +++ b/src/main/java/org/springframework/data/map/MapKeyValueAdapter.java @@ -34,30 +34,51 @@ import org.springframework.util.ClassUtils; */ public class MapKeyValueAdapter extends AbstractKeyValueAdapter { - private final Map> data; - @SuppressWarnings("rawtypes")// - private final Class mapType; + private final Class keySpaceMapType; + private final Map> store; /** - * Create new instance of {@link MapKeyValueAdapter} using {@link ConcurrentHashMap}. + * Create new {@link MapKeyValueAdapter} using {@link ConcurrentHashMap} as backing store type. */ public MapKeyValueAdapter() { - this(new ConcurrentHashMap>()); + this(ConcurrentHashMap.class); + } + + /** + * Creates a new {@link MapKeyValueAdapter} using the given {@link Map} as backing store. + * + * @param mapType must not be {@literal null}. + */ + @SuppressWarnings("rawtypes") + public MapKeyValueAdapter(Class mapType) { + this(CollectionFactory.> createMap(mapType, 100), mapType); } /** * Create new instance of {@link MapKeyValueAdapter} using given dataStore for persistence. * - * @param dataStore must not be {@literal null}. + * @param store must not be {@literal null}. */ @SuppressWarnings({ "rawtypes", "unchecked" }) - public MapKeyValueAdapter(Map> dataStore) { + public MapKeyValueAdapter(Map> store) { + this(store, (Class) ClassUtils.getUserClass(store)); + } - Assert.notNull(dataStore, "Cannot initilalize adapter with 'null' datastore."); + /** + * Creates a new {@link MapKeyValueAdapter} with the given store and type to be used when creating key spaces. + * + * @param store must not be {@literal null}. + * @param keySpaceMapType must not be {@literal null}. + */ + @SuppressWarnings("rawtypes") + private MapKeyValueAdapter(Map> store, Class keySpaceMapType) { - this.data = dataStore; - this.mapType = (Class) ClassUtils.getUserClass(dataStore); + Assert.notNull(store, "Store must not be null."); + Assert.notNull(keySpaceMapType, "Map type to be used for key spaces must not be null!"); + + this.store = store; + this.keySpaceMapType = keySpaceMapType; } /* @@ -67,8 +88,8 @@ public class MapKeyValueAdapter extends AbstractKeyValueAdapter { @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."); + Assert.notNull(id, "Cannot add item with null id."); + Assert.notNull(keyspace, "Cannot add item for null collection."); return getKeySpaceMap(keyspace).put(id, item); } @@ -89,7 +110,7 @@ public class MapKeyValueAdapter extends AbstractKeyValueAdapter { @Override public Object get(Serializable id, Serializable keyspace) { - Assert.notNull(id, "Cannot get item with 'null' id."); + Assert.notNull(id, "Cannot get item with null id."); return getKeySpaceMap(keyspace).get(id); } @@ -100,7 +121,7 @@ public class MapKeyValueAdapter extends AbstractKeyValueAdapter { @Override public Object delete(Serializable id, Serializable keyspace) { - Assert.notNull(id, "Cannot delete item with 'null' id."); + Assert.notNull(id, "Cannot delete item with null id."); return getKeySpaceMap(keyspace).remove(id); } @@ -128,7 +149,7 @@ public class MapKeyValueAdapter extends AbstractKeyValueAdapter { */ @Override public void clear() { - data.clear(); + store.clear(); } /* @@ -148,19 +169,19 @@ public class MapKeyValueAdapter extends AbstractKeyValueAdapter { */ protected Map getKeySpaceMap(Serializable keyspace) { - Assert.notNull(keyspace, "Collection must not be 'null' for lookup."); + Assert.notNull(keyspace, "Collection must not be null for lookup."); - Map map = data.get(keyspace); + Map map = store.get(keyspace); if (map != null) { return map; } addMapForKeySpace(keyspace); - return data.get(keyspace); + return store.get(keyspace); } private void addMapForKeySpace(Serializable keyspace) { - data.put(keyspace, CollectionFactory. createMap(mapType, 1000)); + store.put(keyspace, CollectionFactory. createMap(keySpaceMapType, 1000)); } } diff --git a/src/main/java/org/springframework/data/map/MapKeyValueAdapterFactory.java b/src/main/java/org/springframework/data/map/MapKeyValueAdapterFactory.java deleted file mode 100644 index d7e5b38..0000000 --- a/src/main/java/org/springframework/data/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.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/map/repository/config/EnableMapRepositories.java b/src/main/java/org/springframework/data/map/repository/config/EnableMapRepositories.java index 44357fb..f633efa 100644 --- a/src/main/java/org/springframework/data/map/repository/config/EnableMapRepositories.java +++ b/src/main/java/org/springframework/data/map/repository/config/EnableMapRepositories.java @@ -25,9 +25,11 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import org.springframework.beans.factory.FactoryBean; +import org.springframework.context.ApplicationContext; 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.core.KeyValueTemplate; import org.springframework.data.keyvalue.repository.config.QueryCreatorType; import org.springframework.data.keyvalue.repository.query.SpelQueryCreator; import org.springframework.data.keyvalue.repository.support.KeyValueRepositoryFactoryBean; @@ -126,7 +128,9 @@ public @interface EnableMapRepositories { /** * Configures the {@link Map} structure used for data storage. Defaults to {@link ConcurrentHashMap}. Will be ignored - * in favor of existing {@link KeyValueOperations} definition. + * in case an explicit bean for the {@link KeyValueTemplate} is available in the {@link ApplicationContext}. + * + * @see #keyValueTemplateRef() */ @SuppressWarnings("rawtypes") Class mapType() default ConcurrentHashMap.class; diff --git a/src/main/java/org/springframework/data/map/repository/config/MapRepositoryConfigurationExtension.java b/src/main/java/org/springframework/data/map/repository/config/MapRepositoryConfigurationExtension.java index 7d6a500..0b1d55f 100644 --- a/src/main/java/org/springframework/data/map/repository/config/MapRepositoryConfigurationExtension.java +++ b/src/main/java/org/springframework/data/map/repository/config/MapRepositoryConfigurationExtension.java @@ -17,17 +17,14 @@ package org.springframework.data.map.repository.config; import java.util.Map; -import org.springframework.beans.factory.config.AutowireCapableBeanFactory; import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.beans.factory.config.ConstructorArgumentValues; -import org.springframework.beans.factory.support.BeanDefinitionRegistry; -import org.springframework.beans.factory.support.GenericBeanDefinition; -import org.springframework.beans.factory.support.RootBeanDefinition; +import org.springframework.beans.factory.support.AbstractBeanDefinition; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.core.type.AnnotationMetadata; +import org.springframework.data.config.ParsingUtils; import org.springframework.data.keyvalue.core.KeyValueTemplate; import org.springframework.data.keyvalue.repository.config.KeyValueRepositoryConfigurationExtension; import org.springframework.data.map.MapKeyValueAdapter; -import org.springframework.data.map.MapKeyValueAdapterFactory; import org.springframework.data.repository.config.RepositoryConfigurationSource; /** @@ -67,43 +64,24 @@ public class MapRepositoryConfigurationExtension extends KeyValueRepositoryConfi * @see org.springframework.data.keyvalue.repository.config.KeyValueRepositoryConfigurationExtension#getDefaultKeyValueTemplateBeanDefinition() */ @Override - protected RootBeanDefinition getDefaultKeyValueTemplateBeanDefinition( + protected AbstractBeanDefinition getDefaultKeyValueTemplateBeanDefinition( RepositoryConfigurationSource configurationSource) { - ConstructorArgumentValues constructorArgumentValues = new ConstructorArgumentValues(); + BeanDefinitionBuilder adapterBuilder = BeanDefinitionBuilder.rootBeanDefinition(MapKeyValueAdapter.class); + adapterBuilder.addConstructorArgValue(getMapTypeToUse(configurationSource)); - GenericBeanDefinition referencingMapKeyValueAdapterBeanDefintion = new GenericBeanDefinition(); - referencingMapKeyValueAdapterBeanDefintion.setBeanClass(MapKeyValueAdapter.class); - referencingMapKeyValueAdapterBeanDefintion.setAutowireMode(AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE); + BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(KeyValueTemplate.class); + builder + .addConstructorArgValue(ParsingUtils.getSourceBeanDefinition(adapterBuilder, configurationSource.getSource())); + builder.setRole(BeanDefinition.ROLE_SUPPORT); - constructorArgumentValues.addGenericArgumentValue(referencingMapKeyValueAdapterBeanDefintion); - - RootBeanDefinition keyValueTemplateDefinition = new RootBeanDefinition(KeyValueTemplate.class); - keyValueTemplateDefinition.setConstructorArgumentValues(constructorArgumentValues); - keyValueTemplateDefinition.setRole(BeanDefinition.ROLE_APPLICATION); - - return keyValueTemplateDefinition; + return ParsingUtils.getSourceBeanDefinition(builder, configurationSource.getSource()); } - @Override @SuppressWarnings({ "unchecked", "rawtypes" }) - protected void registerTemplateInfrastructure(BeanDefinitionRegistry registry, - RepositoryConfigurationSource configurationSource) { + private static Class getMapTypeToUse(RepositoryConfigurationSource source) { - Class type = (Class) ((AnnotationMetadata) configurationSource.getSource()) - .getAnnotationAttributes(EnableMapRepositories.class.getName()).get("mapType"); - - ConstructorArgumentValues mapAdapterFactoryArgs = new ConstructorArgumentValues(); - mapAdapterFactoryArgs.addGenericArgumentValue(type); - RootBeanDefinition mapAdapterFactory = new RootBeanDefinition(MapKeyValueAdapterFactory.class, - mapAdapterFactoryArgs, null); - - registry.registerBeanDefinition("mapKeyValueAdapterFactory", mapAdapterFactory); - - RootBeanDefinition mapKeyValueAdapter = new RootBeanDefinition(MapKeyValueAdapter.class); - mapKeyValueAdapter.setFactoryBeanName("mapKeyValueAdapterFactory"); - mapKeyValueAdapter.setFactoryMethodName("getAdapter"); - - registry.registerBeanDefinition("mapKeyValueAdapter", mapAdapterFactory); + return (Class) ((AnnotationMetadata) source.getSource()).getAnnotationAttributes( + EnableMapRepositories.class.getName()).get("mapType"); } } diff --git a/src/test/java/org/springframework/data/map/MapKeyValueAdapterFactoryUnitTests.java b/src/test/java/org/springframework/data/map/MapKeyValueAdapterFactoryUnitTests.java deleted file mode 100644 index 60e74fe..0000000 --- a/src/test/java/org/springframework/data/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.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/map/repository/config/MapRepositoriesConfigurationExtensionIntegrationTests.java b/src/test/java/org/springframework/data/map/repository/config/MapRepositoriesConfigurationExtensionIntegrationTests.java index 139a9c6..f479449 100644 --- a/src/test/java/org/springframework/data/map/repository/config/MapRepositoriesConfigurationExtensionIntegrationTests.java +++ b/src/test/java/org/springframework/data/map/repository/config/MapRepositoriesConfigurationExtensionIntegrationTests.java @@ -23,13 +23,14 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentSkipListMap; import org.junit.Test; -import org.mockito.Mockito; +import org.springframework.context.ApplicationContext; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.data.keyvalue.core.KeyValueAdapter; import org.springframework.data.keyvalue.core.KeyValueTemplate; +import org.springframework.data.map.MapKeyValueAdapter; +import org.springframework.test.util.ReflectionTestUtils; /** * Integration tests for {@link MapRepositoryConfigurationExtension}. @@ -70,56 +71,27 @@ public class MapRepositoriesConfigurationExtensionIntegrationTests { * @see DATAKV-87 */ @Test - public void registeresMapKeyValueAdapterFactoryWithDefaultMapTypeWhenIsNotCostomized() { - - ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(Config.class); - - assertThat(context.getBeanFactory().getBeanDefinition("mapKeyValueAdapterFactory").getConstructorArgumentValues() - .getGenericArgumentValue(Class.class).getValue().equals(ConcurrentHashMap.class), is(true)); - - context.close(); + public void considersMapTypeConfiguredOnAnnotation() { + assertKeyValueTemplateWithAdapterFor(ConcurrentSkipListMap.class, new AnnotationConfigApplicationContext( + ConfigWithCustomizedMapType.class)); } /** * @see DATAKV-87 */ @Test - public void registeresMapKeyValueAdapterFactoryWithGivenMapTypeWhenIsCostomized() { - - ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(ConfigWithCustomizedMapType.class); - - assertThat(context.getBeanFactory().getBeanDefinition("mapKeyValueAdapterFactory").getConstructorArgumentValues() - .getGenericArgumentValue(Class.class).getValue().equals(ConcurrentSkipListMap.class), is(true)); - - context.close(); + public void doesNotConsiderMapConfiguredIfTemplateIsPresent() { + assertKeyValueTemplateWithAdapterFor(ConcurrentHashMap.class, new AnnotationConfigApplicationContext( + ConfigWithCustomizedMapTypeAndExplicitDefinitionOfKeyValueTemplate.class)); } - /** - * @see DATAKV-87 - */ - @Test - public void doesNotRegisterMapKeyValueAdapterFactoryWhenKeyValueTemplateIsCustomized() { + private static void assertKeyValueTemplateWithAdapterFor(Class mapType, ApplicationContext context) { - ConfigurableApplicationContext context = new AnnotationConfigApplicationContext( - ConfigWithCustomizedMapTypeAndExplicitDefinitionOfKeyValueTemplate.class); + KeyValueTemplate template = context.getBean(KeyValueTemplate.class); + Object adapter = ReflectionTestUtils.getField(template, "adapter"); - assertThat(Arrays.asList(context.getBeanDefinitionNames()), not(hasItem("mapKeyValueAdapterFactory"))); - - context.close(); - } - - /** - * @see DATAKV-87 - */ - @Test - public void doesNotRegisterMapKeyValueAdapterFactoryWhenTemplateReferenceIsCustomized() { - - ConfigurableApplicationContext context = new AnnotationConfigApplicationContext( - ConfigWithCustomTemplateReference.class); - - assertThat(Arrays.asList(context.getBeanDefinitionNames()), not(hasItem("mapKeyValueAdapterFactory"))); - - context.close(); + assertThat(adapter, is(instanceOf(MapKeyValueAdapter.class))); + assertThat(ReflectionTestUtils.getField(adapter, "store"), is(instanceOf(mapType))); } @Configuration @@ -140,8 +112,7 @@ public class MapRepositoriesConfigurationExtensionIntegrationTests { @Bean public KeyValueTemplate mapKeyValueTemplate() { - return new KeyValueTemplate(Mockito.mock(KeyValueAdapter.class)); + return new KeyValueTemplate(new MapKeyValueAdapter()); } } - }