Skip to content

Commit

Permalink
DATACMNS-1018 - Reinstantiated ability to customize repository factor…
Browse files Browse the repository at this point in the history
…y bean through annotation and XML namespace.

The refactoring for DATACMNS-867 has dropped support to customize the repository factory bean class on both the @Enable-annotations and the XML namespace. Reintroduced this feature, added a test case and moved the fallback into the value that's defined by the configuration extension inside DefaultRepositoryConfiguration.
  • Loading branch information
odrotbohm committed Mar 24, 2017
1 parent 6b5b658 commit 11dc67d
Show file tree
Hide file tree
Showing 13 changed files with 93 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -211,10 +211,11 @@ private Optional<String> getNullDefaultedAttribute(String attributeName) {

/*
* (non-Javadoc)
* @see org.springframework.data.repository.config.RepositoryConfigurationSource#getRepositoryFactoryBeanName()
* @see org.springframework.data.repository.config.RepositoryConfigurationSource#getRepositoryFactoryBeanClassName()
*/
public String getRepositoryFactoryBeanName() {
return attributes.getClass(REPOSITORY_FACTORY_BEAN_CLASS).getName();
@Override
public Optional<String> getRepositoryFactoryBeanClassName() {
return Optional.of(attributes.getClass(REPOSITORY_FACTORY_BEAN_CLASS).getName());
}

/*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ public class DefaultRepositoryConfiguration<T extends RepositoryConfigurationSou

private final @NonNull T configurationSource;
private final @NonNull BeanDefinition definition;
private final @NonNull RepositoryConfigurationExtension extension;

/*
* (non-Javadoc)
Expand Down Expand Up @@ -133,7 +134,18 @@ public Optional<String> getRepositoryBaseClassName() {
return configurationSource.getRepositoryBaseClassName();
}

/*
/*
* (non-Javadoc)
* @see org.springframework.data.repository.config.RepositoryConfiguration#getRepositoryFactoryBeanClassName()
*/
@Override
public String getRepositoryFactoryBeanClassName() {

return configurationSource.getRepositoryFactoryBeanClassName()
.orElseGet(() -> extension.getRepositoryFactoryBeanClassName());
}

/*
* (non-Javadoc)
* @see org.springframework.data.repository.config.RepositoryConfiguration#isLazyInit()
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@ public BeanDefinitionBuilder build(RepositoryConfiguration<?> configuration) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null!");
Assert.notNull(resourceLoader, "ResourceLoader must not be null!");

BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(extension.getRepositoryFactoryClassName());
BeanDefinitionBuilder builder = BeanDefinitionBuilder
.rootBeanDefinition(configuration.getRepositoryFactoryBeanClassName());

builder.getRawBeanDefinition().setSource(configuration.getSource());
builder.addConstructorArgValue(configuration.getRepositoryInterface());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,13 @@ public interface RepositoryConfiguration<T extends RepositoryConfigurationSource
*/
Optional<String> getRepositoryBaseClassName();

/**
* Returns the name of the repository factory bean class to be used.
*
* @return
*/
String getRepositoryFactoryBeanClassName();

/**
* Returns the source of the {@link RepositoryConfiguration}.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ public List<BeanComponentDefinition> registerRepositoriesIn(BeanDefinitionRegist

if (LOGGER.isDebugEnabled()) {
LOGGER.debug(REPOSITORY_REGISTRATION, extension.getModuleName(), beanName,
configuration.getRepositoryInterface(), extension.getRepositoryFactoryClassName());
configuration.getRepositoryInterface(), configuration.getRepositoryFactoryBeanClassName());
}

beanDefinition.setAttribute(FACTORY_BEAN_OBJECT_TYPE, configuration.getRepositoryInterface());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ <T extends RepositoryConfigurationSource> Collection<RepositoryConfiguration<T>>
*
* @return
*/
String getRepositoryFactoryClassName();
String getRepositoryFactoryBeanClassName();

/**
* Callback to register additional bean definitions for a {@literal repositories} root node. This usually includes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -232,15 +232,15 @@ public static boolean hasBean(Class<?> type, BeanDefinitionRegistry registry) {
/**
* Creates a actual {@link RepositoryConfiguration} instance for the given {@link RepositoryConfigurationSource} and
* interface name. Defaults to the {@link DefaultRepositoryConfiguration} but allows sub-classes to override this to
* customize the behaviour.
* customize the behavior.
*
* @param definition will never be {@literal null} or empty.
* @param configSource will never be {@literal null}.
* @return
*/
protected <T extends RepositoryConfigurationSource> RepositoryConfiguration<T> getRepositoryConfiguration(
BeanDefinition definition, T configSource) {
return new DefaultRepositoryConfiguration<>(configSource, definition);
return new DefaultRepositoryConfiguration<>(configSource, definition, this);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public interface RepositoryConfigurationSource {
/**
* Returns the configured postfix to be used for looking up custom implementation classes.
*
* @return the postfix to use or {@literal null} in case none is configured.
* @return the postfix to use or {@link Optional#empty()} in case none is configured.
*/
Optional<String> getRepositoryImplementationPostfix();

Expand All @@ -67,14 +67,21 @@ public interface RepositoryConfigurationSource {
Optional<String> getNamedQueryLocation();

/**
* Returns the name of the repository base class to be used or {@literal null} if the store specific defaults shall be
* applied.
* Returns the name of the repository base class to be used or {@link Optional#empty()} if the store specific defaults
* shall be applied.
*
* @return
* @since 1.11
*/
Optional<String> getRepositoryBaseClassName();

/**
* Returns the name of the repository factory bean class or {@link Optional#empty()} if not defined in the source.
*
* @return
*/
Optional<String> getRepositoryFactoryBeanClassName();

/**
* Returns the source {@link BeanDefinition}s of the repository interfaces to create repository instances for.
*
Expand All @@ -88,7 +95,7 @@ public interface RepositoryConfigurationSource {
* camel-case.
*
* @param name must not be {@literal null} or empty.
* @return the attribute with the given name or {@literal null} if not configured or empty.
* @return the attribute with the given name or {@link Optional#empty()} if not configured or empty.
* @since 1.8
*/
Optional<String> getAttribute(String name);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
import org.springframework.core.type.filter.TypeFilter;
import org.springframework.data.config.TypeFilterParser;
import org.springframework.data.config.TypeFilterParser.Type;
import org.springframework.data.repository.query.QueryLookupStrategy;
import org.springframework.data.repository.query.QueryLookupStrategy.Key;
import org.springframework.data.util.ParsingUtils;
import org.springframework.util.Assert;
Expand Down Expand Up @@ -162,6 +161,15 @@ public Optional<String> getRepositoryBaseClassName() {
return getNullDefaultedAttribute(element, REPOSITORY_BASE_CLASS_NAME);
}

/*
* (non-Javadoc)
* @see org.springframework.data.repository.config.RepositoryConfigurationSource#getRepositoryFactoryBeanClassName()
*/
@Override
public Optional<String> getRepositoryFactoryBeanClassName() {
return getNullDefaultedAttribute(element, REPOSITORY_FACTORY_BEAN_CLASS_NAME);
}

private Optional<String> getNullDefaultedAttribute(Element element, String attributeName) {

String attribute = element.getAttribute(attributeName);
Expand All @@ -175,8 +183,7 @@ private Optional<String> getNullDefaultedAttribute(Element element, String attri
@Override
public boolean shouldConsiderNestedRepositories() {

return getNullDefaultedAttribute(element, CONSIDER_NESTED_REPOSITORIES).map(Boolean::parseBoolean)
.orElse(false);
return getNullDefaultedAttribute(element, CONSIDER_NESTED_REPOSITORIES).map(Boolean::parseBoolean).orElse(false);
}

/*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
*/
package org.springframework.data.repository.core.support;

import lombok.Getter;

import java.io.Serializable;
import java.util.List;

Expand All @@ -31,6 +33,7 @@
* @author Oliver Gierke
* @author Thomas Darimont
*/
@Getter
public class DefaultRepositoryMetadata extends AbstractRepositoryMetadata {

private static final String MUST_BE_A_REPOSITORY = String.format("Given type must be assignable to %s!",
Expand All @@ -53,24 +56,6 @@ public DefaultRepositoryMetadata(Class<?> repositoryInterface) {
this.domainType = resolveDomainType(repositoryInterface);
}

/*
* (non-Javadoc)
* @see org.springframework.data.repository.core.RepositoryMetadata#getDomainType()
*/
@Override
public Class<?> getDomainType() {
return this.domainType;
}

/*
* (non-Javadoc)
* @see org.springframework.data.repository.core.RepositoryMetadata#getIdType()
*/
@Override
public Class<? extends Serializable> getIdType() {
return this.idType;
}

@SuppressWarnings("unchecked")
private Class<? extends Serializable> resolveIdType(Class<?> repositoryInterface) {

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2013 the original author or authors.
* Copyright 2012-2017 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.
Expand All @@ -16,11 +16,18 @@
package org.springframework.data.repository.config;

import static org.assertj.core.api.Assertions.*;
import static org.mockito.Mockito.*;

import lombok.EqualsAndHashCode;
import lombok.Value;

import java.util.Optional;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.data.repository.query.QueryLookupStrategy.Key;

Expand All @@ -34,11 +41,13 @@ public class DefaultRepositoryConfigurationUnitTests {

@Mock RepositoryConfigurationSource source;

BeanDefinition definition = new RootBeanDefinition("com.acme.MyRepository");
RepositoryConfigurationExtension extension = new SimplerRepositoryConfigurationExtension("factory", "module");

@Test
public void supportsBasicConfiguration() {

RepositoryConfiguration<RepositoryConfigurationSource> configuration = new DefaultRepositoryConfiguration<>(
source, new RootBeanDefinition("com.acme.MyRepository"));
RepositoryConfiguration<RepositoryConfigurationSource> configuration = getConfiguration(source);

assertThat(configuration.getConfigurationSource()).isEqualTo(source);
assertThat(configuration.getImplementationBeanName()).isEqualTo("myRepositoryImpl");
Expand All @@ -47,4 +56,28 @@ public void supportsBasicConfiguration() {
assertThat(configuration.getQueryLookupStrategyKey()).isEqualTo(Key.CREATE_IF_NOT_FOUND);
assertThat(configuration.isLazyInit()).isFalse();
}

@Test // DATACMNS-1018
public void usesExtensionFactoryBeanClassNameIfNoneDefinedInSource() {
assertThat(getConfiguration(source).getRepositoryFactoryBeanClassName()).isEqualTo("factory");
}

@Test // DATACMNS-1018
public void prefersSourcesRepositoryFactoryBeanClass() {

when(source.getRepositoryFactoryBeanClassName()).thenReturn(Optional.of("custom"));

assertThat(getConfiguration(source).getRepositoryFactoryBeanClassName()).isEqualTo("custom");
}

private DefaultRepositoryConfiguration<RepositoryConfigurationSource> getConfiguration(
RepositoryConfigurationSource source) {
return new DefaultRepositoryConfiguration<>(source, definition, extension);
}

@Value
@EqualsAndHashCode(callSuper = true)
private static class SimplerRepositoryConfigurationExtension extends RepositoryConfigurationExtensionSupport {
String repositoryFactoryBeanClassName, modulePrefix;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package org.springframework.data.repository.config;

import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*;

import java.lang.annotation.Annotation;
Expand Down Expand Up @@ -120,7 +121,7 @@ protected RepositoryConfigurationExtension getExtension() {

static class DummyConfigurationExtension extends RepositoryConfigurationExtensionSupport {

public String getRepositoryFactoryClassName() {
public String getRepositoryFactoryBeanClassName() {
return DummyRepositoryFactoryBean.class.getName();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ protected String getModulePrefix() {
}

@Override
public String getRepositoryFactoryClassName() {
public String getRepositoryFactoryBeanClassName() {
return RepositoryFactorySupport.class.getName();
}

Expand Down

0 comments on commit 11dc67d

Please sign in to comment.