diff --git a/src/main/java/org/springframework/data/ldap/repository/config/EnableLdapRepositories.java b/src/main/java/org/springframework/data/ldap/repository/config/EnableLdapRepositories.java index 603f256..9de2f62 100644 --- a/src/main/java/org/springframework/data/ldap/repository/config/EnableLdapRepositories.java +++ b/src/main/java/org/springframework/data/ldap/repository/config/EnableLdapRepositories.java @@ -24,15 +24,16 @@ import java.lang.annotation.Target; import org.springframework.context.annotation.ComponentScan.Filter; import org.springframework.context.annotation.Import; -import org.springframework.data.repository.query.QueryLookupStrategy.Key; import org.springframework.data.ldap.repository.support.LdapRepositoryFactoryBean; +import org.springframework.data.repository.config.DefaultRepositoryBaseClass; +import org.springframework.data.repository.query.QueryLookupStrategy.Key; /** * Annotation to activate Ldap 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 Mattias Hellborg Arthursson - * @since 2.0 + * @author Mark Paluch */ @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @@ -43,7 +44,8 @@ public @interface EnableLdapRepositories { /** * Alias for the {@link #basePackages()} attribute. Allows for more concise annotation declarations e.g.: - * {@code @EnableLdapRepositories("org.my.pkg")} instead of {@code @EnableLdapRepositories(basePackages="org.my.pkg")}. + * {@code @EnableLdapRepositories("org.my.pkg")} instead of + * {@code @EnableLdapRepositories(basePackages="org.my.pkg")}. */ String[] value() default {}; @@ -78,7 +80,7 @@ public @interface EnableLdapRepositories { * * @return */ - String repositoryImplementationPostfix() default ""; + String repositoryImplementationPostfix() default "Impl"; /** * Configures the location of where to find the Spring Data named queries properties file. Will default to @@ -89,7 +91,8 @@ public @interface EnableLdapRepositories { String namedQueriesLocation() default ""; /** - * Returns the key of the {@link org.springframework.data.repository.query.QueryLookupStrategy} to be used for lookup queries for query methods. Defaults to + * Returns the key of the {@link org.springframework.data.repository.query.QueryLookupStrategy} to be used for lookup + * queries for query methods. Defaults to * {@link org.springframework.data.repository.query.QueryLookupStrategy.Key#CREATE_IF_NOT_FOUND}. * * @return @@ -97,17 +100,31 @@ public @interface EnableLdapRepositories { Key queryLookupStrategy() default Key.CREATE_IF_NOT_FOUND; /** - * Returns the {@link org.springframework.beans.factory.FactoryBean} class to be used for each repository instance. Defaults to - * {@link org.springframework.data.ldap.repository.support.LdapRepositoryFactoryBean}. + * Returns the {@link org.springframework.beans.factory.FactoryBean} class to be used for each repository instance. + * Defaults to {@link org.springframework.data.ldap.repository.support.LdapRepositoryFactoryBean}. * * @return */ Class repositoryFactoryBeanClass() default LdapRepositoryFactoryBean.class; /** - * Configures the name of the {@link org.springframework.ldap.core.LdapTemplate} bean to be used with the repositories detected. + * Configure the repository base class to be used to create repository proxies for this particular configuration. + * + * @return + */ + Class repositoryBaseClass() default DefaultRepositoryBaseClass.class; + + /** + * Configures the name of the {@link org.springframework.ldap.core.LdapTemplate} bean to be used with the repositories + * detected. * * @return */ String ldapTemplateRef() default "ldapTemplate"; + + /** + * 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/ldap/repository/support/LdapRepositoryFactory.java b/src/main/java/org/springframework/data/ldap/repository/support/LdapRepositoryFactory.java index c100e8e..7d345bf 100644 --- a/src/main/java/org/springframework/data/ldap/repository/support/LdapRepositoryFactory.java +++ b/src/main/java/org/springframework/data/ldap/repository/support/LdapRepositoryFactory.java @@ -20,6 +20,9 @@ import static org.springframework.data.querydsl.QueryDslUtils.*; import java.io.Serializable; import java.lang.reflect.Method; +import org.springframework.data.ldap.repository.query.AnnotatedLdapRepositoryQuery; +import org.springframework.data.ldap.repository.query.LdapQueryMethod; +import org.springframework.data.ldap.repository.query.PartTreeLdapRepositoryQuery; import org.springframework.data.projection.ProjectionFactory; import org.springframework.data.querydsl.QueryDslPredicateExecutor; import org.springframework.data.repository.core.EntityInformation; @@ -32,17 +35,13 @@ import org.springframework.data.repository.query.QueryLookupStrategy; import org.springframework.data.repository.query.QueryLookupStrategy.Key; import org.springframework.data.repository.query.RepositoryQuery; import org.springframework.ldap.core.LdapOperations; -import org.springframework.data.ldap.repository.query.AnnotatedLdapRepositoryQuery; -import org.springframework.data.ldap.repository.query.LdapQueryMethod; -import org.springframework.data.ldap.repository.query.PartTreeLdapRepositoryQuery; -import org.springframework.data.ldap.repository.support.SimpleLdapRepository; /** * Factory to create {@link org.springframework.data.ldap.repository.LdapRepository} instances. * * @author Mattias Hellborg Arthursson * @author Eddu Melendez - * @since 2.0 + * @author Mark Paluch */ public class LdapRepositoryFactory extends RepositoryFactorySupport { @@ -57,33 +56,28 @@ public class LdapRepositoryFactory extends RepositoryFactorySupport { return null; } - @SuppressWarnings({ "unchecked", "rawtypes" }) - protected Object getTargetRepository(RepositoryMetadata metadata) { - - if (!isQueryDslRepository(metadata.getRepositoryInterface())) { - return new org.springframework.data.ldap.repository.support.SimpleLdapRepository(ldapOperations, - ldapOperations.getObjectDirectoryMapper(), metadata.getDomainType()); - } - - return new QueryDslLdapRepository(ldapOperations, ldapOperations.getObjectDirectoryMapper(), - metadata.getDomainType()); - } - - protected Object getTargetRepository(RepositoryInformation metadata) { - return getTargetRepository((RepositoryMetadata) metadata); + /* + * (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()) ? QueryDslLdapRepository.class + : SimpleLdapRepository.class; } private static boolean isQueryDslRepository(Class repositoryInterface) { return QUERY_DSL_PRESENT && QueryDslPredicateExecutor.class.isAssignableFrom(repositoryInterface); } + /* + * (non-Javadoc) + * @see org.springframework.data.repository.core.support.RepositoryFactorySupport#getTargetRepository(org.springframework.data.repository.core.RepositoryInformation) + */ @Override - protected Class getRepositoryBaseClass(RepositoryMetadata metadata) { - if (!isQueryDslRepository(metadata.getRepositoryInterface())) { - return SimpleLdapRepository.class; - } else { - return QueryDslLdapRepository.class; - } + protected Object getTargetRepository(RepositoryInformation information) { + return getTargetRepositoryViaReflection(information, ldapOperations, ldapOperations.getObjectDirectoryMapper(), + information.getDomainType()); } @Override @@ -101,6 +95,7 @@ public class LdapRepositoryFactory extends RepositoryFactorySupport { @Override public RepositoryQuery resolveQuery(Method method, RepositoryMetadata metadata, ProjectionFactory factory, NamedQueries namedQueries) { + LdapQueryMethod queryMethod = new LdapQueryMethod(method, metadata, factory); Class domainType = metadata.getDomainType(); diff --git a/src/test/java/org/springframework/data/ldap/repository/config/CustomRepositoryBaseClassTests.java b/src/test/java/org/springframework/data/ldap/repository/config/CustomRepositoryBaseClassTests.java new file mode 100644 index 0000000..f4d6f25 --- /dev/null +++ b/src/test/java/org/springframework/data/ldap/repository/config/CustomRepositoryBaseClassTests.java @@ -0,0 +1,77 @@ +/* + * Copyright 2016 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.ldap.repository.config; + +import static org.assertj.core.api.Assertions.*; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.ImportResource; +import org.springframework.data.ldap.config.DummyEntity; +import org.springframework.data.ldap.repository.LdapRepository; +import org.springframework.data.ldap.repository.support.SimpleLdapRepository; +import org.springframework.data.repository.NoRepositoryBean; +import org.springframework.ldap.core.LdapOperations; +import org.springframework.ldap.odm.core.ObjectDirectoryMapper; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringRunner; + +/** + * Unit tests for {@link EnableLdapRepositories#repositoryBaseClass()}. + * + * @author Mark Paluch + */ +@RunWith(SpringRunner.class) +@ContextConfiguration(classes = CustomRepositoryBaseClassTests.Config.class) +public class CustomRepositoryBaseClassTests { + + @Autowired ApplicationContext applicationContext; + + @Test // DATALDAP-2 + public void shouldImplementCustomizedRepository() { + + CustomizedDummyRepository repository = applicationContext.getBean(CustomizedDummyRepository.class); + assertThat(repository.returnOne()).isEqualTo(1); + } + + @Configuration + @ImportResource("classpath:/infrastructure.xml") + @EnableLdapRepositories(considerNestedRepositories = true, repositoryBaseClass = CustomizedLdapRepositoryImpl.class) + static class Config {} + + interface CustomizedDummyRepository extends CustomizedLdapRepository {} + + @NoRepositoryBean + interface CustomizedLdapRepository extends LdapRepository { + + int returnOne(); + } + + static class CustomizedLdapRepositoryImpl extends SimpleLdapRepository implements CustomizedLdapRepository { + + public CustomizedLdapRepositoryImpl(LdapOperations ldapOperations, ObjectDirectoryMapper odm, Class clazz) { + super(ldapOperations, odm, clazz); + } + + @Override + public int returnOne() { + return 1; + } + } +}