Browse Source

DATAMONGO-1470 - AbstractMongoConfiguration now supports multiple base packages for @Document scanning.

Introduced AbstractMongoConfiguration.getMappingBasePackages() to return multiple ones over the previously existing ….getMappingBasePackage(). The former is now used by the code triggering the scanning using what the latter returns by default.
pull/382/head
Oliver Gierke 10 years ago
parent
commit
29a6688e8c
  1. 57
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/AbstractMongoConfiguration.java
  2. 26
      spring-data-mongodb/src/test/java/example/first/First.java
  3. 26
      spring-data-mongodb/src/test/java/example/second/Second.java
  4. 51
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/config/AbstractMongoConfigurationUnitTests.java

57
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/AbstractMongoConfiguration.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2011-2015 the original author or authors.
* Copyright 2011-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.
@ -15,6 +15,7 @@ @@ -15,6 +15,7 @@
*/
package org.springframework.data.mongodb.config;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
@ -118,17 +119,33 @@ public abstract class AbstractMongoConfiguration { @@ -118,17 +119,33 @@ public abstract class AbstractMongoConfiguration {
* Return the base package to scan for mapped {@link Document}s. Will return the package name of the configuration
* class' (the concrete class, not this one here) by default. So if you have a {@code com.acme.AppConfig} extending
* {@link AbstractMongoConfiguration} the base package will be considered {@code com.acme} unless the method is
* overriden to implement alternate behaviour.
* overridden to implement alternate behavior.
*
* @return the base package to scan for mapped {@link Document} classes or {@literal null} to not enable scanning for
* entities.
* @deprecated use {@link #getMappingBasePackages()} instead.
*/
@Deprecated
protected String getMappingBasePackage() {
Package mappingBasePackage = getClass().getPackage();
return mappingBasePackage == null ? null : mappingBasePackage.getName();
}
/**
* Returns the base packages to scan for MongoDB mapped entities at startup. Will return the package name of the
* configuration class' (the concrete class, not this one here) by default. So if you have a
* {@code com.acme.AppConfig} extending {@link AbstractMongoConfiguration} the base package will be considered
* {@code com.acme} unless the method is overridden to implement alternate behavior.
*
* @return the base packages to scan for mapped {@link Document} classes or an empty collection to not enable scanning
* for entities.
* @since 1.10
*/
protected Collection<String> getMappingBasePackages() {
return Collections.singleton(getMappingBasePackage());
}
/**
* Return {@link UserCredentials} to be used when connecting to the MongoDB instance or {@literal null} if none shall
* be used.
@ -204,26 +221,52 @@ public abstract class AbstractMongoConfiguration { @@ -204,26 +221,52 @@ public abstract class AbstractMongoConfiguration {
}
/**
* Scans the mapping base package for classes annotated with {@link Document}.
* Scans the mapping base package for classes annotated with {@link Document}. By default, it scans for entities in
* all packages returned by {@link #getMappingBasePackages()}.
*
* @see #getMappingBasePackage()
* @see #getMappingBasePackages()
* @return
* @throws ClassNotFoundException
*/
protected Set<Class<?>> getInitialEntitySet() throws ClassNotFoundException {
String basePackage = getMappingBasePackage();
Set<Class<?>> initialEntitySet = new HashSet<Class<?>>();
for (String basePackage : getMappingBasePackages()) {
initialEntitySet.addAll(scanForEntities(basePackage));
}
return initialEntitySet;
}
/**
* Scans the given base package for entities, i.e. MongoDB specific types annotated with {@link Document} and
* {@link Persistent}.
*
* @param basePackage must not be {@literal null}.
* @return
* @throws ClassNotFoundException
* @since 1.10
*/
protected Set<Class<?>> scanForEntities(String basePackage) throws ClassNotFoundException {
if (!StringUtils.hasText(basePackage)) {
return Collections.emptySet();
}
Set<Class<?>> initialEntitySet = new HashSet<Class<?>>();
if (StringUtils.hasText(basePackage)) {
ClassPathScanningCandidateComponentProvider componentProvider = new ClassPathScanningCandidateComponentProvider(
false);
componentProvider.addIncludeFilter(new AnnotationTypeFilter(Document.class));
componentProvider.addIncludeFilter(new AnnotationTypeFilter(Persistent.class));
for (BeanDefinition candidate : componentProvider.findCandidateComponents(basePackage)) {
initialEntitySet.add(ClassUtils.forName(candidate.getBeanClassName(),
AbstractMongoConfiguration.class.getClassLoader()));
initialEntitySet
.add(ClassUtils.forName(candidate.getBeanClassName(), AbstractMongoConfiguration.class.getClassLoader()));
}
}

26
spring-data-mongodb/src/test/java/example/first/First.java

@ -0,0 +1,26 @@ @@ -0,0 +1,26 @@
/*
* 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 example.first;
import org.springframework.data.mongodb.core.mapping.Document;
/**
* @author Oliver Gierke
*/
@Document
public class First {
}

26
spring-data-mongodb/src/test/java/example/second/Second.java

@ -0,0 +1,26 @@ @@ -0,0 +1,26 @@
/*
* 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 example.second;
import org.springframework.data.mongodb.core.mapping.Document;
/**
* @author Oliver Gierke
*/
@Document
public class Second {
}

51
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/config/AbstractMongoConfigurationUnitTests.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2012-2013 the original author or authors.
* Copyright 2012-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.
@ -18,6 +18,13 @@ package org.springframework.data.mongodb.config; @@ -18,6 +18,13 @@ package org.springframework.data.mongodb.config;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import example.first.First;
import example.second.Second;
import java.util.Arrays;
import java.util.Collection;
import java.util.Set;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
@ -144,6 +151,20 @@ public class AbstractMongoConfigurationUnitTests { @@ -144,6 +151,20 @@ public class AbstractMongoConfigurationUnitTests {
assertThat(new SampleMongoConfiguration().getAuthenticationDatabaseName(), is(nullValue()));
}
/**
* @see DATAMONGO-1470
*/
@Test
@SuppressWarnings("unchecked")
public void allowsMultipleEntityBasePackages() throws ClassNotFoundException {
ConfigurationWithMultipleBasePackages config = new ConfigurationWithMultipleBasePackages();
Set<Class<?>> entities = config.getInitialEntitySet();
assertThat(entities, hasSize(2));
assertThat(entities, hasItems(First.class, Second.class));
}
private static void assertScanningDisabled(final String value) throws ClassNotFoundException {
AbstractMongoConfiguration configuration = new SampleMongoConfiguration() {
@ -173,9 +194,11 @@ public class AbstractMongoConfigurationUnitTests { @@ -173,9 +194,11 @@ public class AbstractMongoConfigurationUnitTests {
@Bean
@Override
public MappingMongoConverter mappingMongoConverter() throws Exception {
MappingMongoConverter mmc = super.mappingMongoConverter();
mmc.setTypeMapper(typeMapper());
return mmc;
MappingMongoConverter converter = super.mappingMongoConverter();
converter.setTypeMapper(typeMapper());
return converter;
}
@Bean
@ -184,8 +207,24 @@ public class AbstractMongoConfigurationUnitTests { @@ -184,8 +207,24 @@ public class AbstractMongoConfigurationUnitTests {
}
}
@Document
static class Entity {
static class ConfigurationWithMultipleBasePackages extends AbstractMongoConfiguration {
@Override
protected String getDatabaseName() {
return "test";
}
@Override
public Mongo mongo() throws Exception {
return new MongoClient();
}
@Override
protected Collection<String> getMappingBasePackages() {
return Arrays.asList("example.first", "example.second");
}
}
@Document
static class Entity {}
}

Loading…
Cancel
Save