From 191894a16affe86dbc49c2ad44e625b17d5f2399 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Wed, 11 Sep 2013 07:48:59 -0700 Subject: [PATCH] Add Mongo auto configuration Spring Data Mongo is the only dependency so it doesn't really need a new starter. Added a sample though. --- spring-boot-autoconfigure/pom.xml | 5 + ...tRepositoryConfigurationSourceSupport.java | 125 ++++++++++++++++ ...JpaRepositoriesAutoConfigureRegistrar.java | 89 ++---------- .../MongoRepositoriesAutoConfiguration.java | 133 ++++++++++++++++++ ...ngoRepositoriesAutoConfigureRegistrar.java | 49 +++++++ .../main/resources/META-INF/spring.factories | 1 + ...JpaRepositoriesAutoConfigurationTests.java | 4 +- .../data/JpaWebAutoConfigurationTests.java | 4 +- ...ngoRepositoriesAutoConfigurationTests.java | 75 ++++++++++ .../data/{test => jpa}/City.java | 2 +- .../data/{test => jpa}/CityRepository.java | 2 +- .../boot/autoconfigure/data/mongo/City.java | 76 ++++++++++ .../data/mongo/CityRepository.java | 32 +++++ spring-boot-samples/pom.xml | 1 + .../spring-boot-sample-data-mongo/pom.xml | 34 +++++ .../boot/sample/data/mongo/Customer.java | 29 ++++ .../sample/data/mongo/CustomerRepository.java | 12 ++ .../data/mongo/SampleMongoApplication.java | 67 +++++++++ .../mongo/SampleMongoApplicationTests.java | 42 ++++++ .../springframework/boot/ansi/AnsiOutput.java | 9 +- 20 files changed, 702 insertions(+), 89 deletions(-) create mode 100644 spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/AbstractRepositoryConfigurationSourceSupport.java create mode 100644 spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/MongoRepositoriesAutoConfiguration.java create mode 100644 spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/MongoRepositoriesAutoConfigureRegistrar.java create mode 100644 spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/MongoRepositoriesAutoConfigurationTests.java rename spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/{test => jpa}/City.java (96%) rename spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/{test => jpa}/CityRepository.java (94%) create mode 100644 spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/City.java create mode 100644 spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/CityRepository.java create mode 100644 spring-boot-samples/spring-boot-sample-data-mongo/pom.xml create mode 100644 spring-boot-samples/spring-boot-sample-data-mongo/src/main/java/org/springframework/boot/sample/data/mongo/Customer.java create mode 100644 spring-boot-samples/spring-boot-sample-data-mongo/src/main/java/org/springframework/boot/sample/data/mongo/CustomerRepository.java create mode 100644 spring-boot-samples/spring-boot-sample-data-mongo/src/main/java/org/springframework/boot/sample/data/mongo/SampleMongoApplication.java create mode 100644 spring-boot-samples/spring-boot-sample-data-mongo/src/test/java/org/springframework/boot/sample/data/mongo/SampleMongoApplicationTests.java diff --git a/spring-boot-autoconfigure/pom.xml b/spring-boot-autoconfigure/pom.xml index f4e3fc4631..0d09b51cc7 100644 --- a/spring-boot-autoconfigure/pom.xml +++ b/spring-boot-autoconfigure/pom.xml @@ -91,6 +91,11 @@ spring-data-jpa true + + org.springframework.data + spring-data-mongodb + true + org.springframework.security spring-security-acl diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/AbstractRepositoryConfigurationSourceSupport.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/AbstractRepositoryConfigurationSourceSupport.java new file mode 100644 index 0000000000..1181977d37 --- /dev/null +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/AbstractRepositoryConfigurationSourceSupport.java @@ -0,0 +1,125 @@ +/* + * Copyright 2012-2013 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.boot.autoconfigure.data; + +import java.lang.annotation.Annotation; +import java.util.Collection; +import java.util.List; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.BeanClassLoaderAware; +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.BeanFactoryAware; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.support.BeanDefinitionRegistry; +import org.springframework.boot.autoconfigure.AutoConfigurationUtils; +import org.springframework.context.annotation.ImportBeanDefinitionRegistrar; +import org.springframework.core.io.DefaultResourceLoader; +import org.springframework.core.io.ResourceLoader; +import org.springframework.core.type.AnnotationMetadata; +import org.springframework.core.type.StandardAnnotationMetadata; +import org.springframework.data.repository.config.AnnotationRepositoryConfigurationSource; +import org.springframework.data.repository.config.RepositoryBeanDefinitionBuilder; +import org.springframework.data.repository.config.RepositoryBeanNameGenerator; +import org.springframework.data.repository.config.RepositoryConfiguration; +import org.springframework.data.repository.config.RepositoryConfigurationExtension; + +/** + * @author Dave Syer + */ +public abstract class AbstractRepositoryConfigurationSourceSupport implements + BeanFactoryAware, ImportBeanDefinitionRegistrar, BeanClassLoaderAware { + + private ClassLoader beanClassLoader; + + private static Log logger = LogFactory + .getLog(AbstractRepositoryConfigurationSourceSupport.class); + + private BeanFactory beanFactory; + + @Override + public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, + final BeanDefinitionRegistry registry) { + + final ResourceLoader resourceLoader = new DefaultResourceLoader(); + final AnnotationRepositoryConfigurationSource configurationSource = getConfigurationSource(); + final RepositoryConfigurationExtension extension = getRepositoryConfigurationExtension(); + extension.registerBeansForRoot(registry, configurationSource); + + final RepositoryBeanNameGenerator generator = new RepositoryBeanNameGenerator(); + generator.setBeanClassLoader(this.beanClassLoader); + + Collection> repositoryConfigurations = extension + .getRepositoryConfigurations(configurationSource, resourceLoader); + + for (final RepositoryConfiguration repositoryConfiguration : repositoryConfigurations) { + RepositoryBeanDefinitionBuilder builder = new RepositoryBeanDefinitionBuilder( + repositoryConfiguration, extension); + BeanDefinitionBuilder definitionBuilder = builder.build(registry, + resourceLoader); + extension.postProcess(definitionBuilder, configurationSource); + + String beanName = generator.generateBeanName( + definitionBuilder.getBeanDefinition(), registry); + registry.registerBeanDefinition(beanName, + definitionBuilder.getBeanDefinition()); + } + } + + @Override + public void setBeanClassLoader(ClassLoader classLoader) { + this.beanClassLoader = classLoader; + } + + protected abstract RepositoryConfigurationExtension getRepositoryConfigurationExtension(); + + protected abstract AnnotationRepositoryConfigurationSource getConfigurationSource(); + + protected AnnotationRepositoryConfigurationSource getConfigurationSource( + Class annotated, Class annotation) { + StandardAnnotationMetadata metadata = new StandardAnnotationMetadata(annotated, + true); + AnnotationRepositoryConfigurationSource configurationSource = new AnnotationRepositoryConfigurationSource( + metadata, annotation) { + + @Override + public java.lang.Iterable getBasePackages() { + return AbstractRepositoryConfigurationSourceSupport.this + .getBasePackages(); + }; + }; + return configurationSource; + } + + protected Iterable getBasePackages() { + List basePackages = AutoConfigurationUtils + .getBasePackages(this.beanFactory); + if (basePackages.isEmpty()) { + logger.warn("Unable to find repository base packages. If you need Repositories please define " + + "a @ComponentScan annotation or else disable *RepositoriesAutoConfiguration"); + } + return basePackages; + } + + @Override + public void setBeanFactory(BeanFactory beanFactory) throws BeansException { + this.beanFactory = beanFactory; + } + +} diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/JpaRepositoriesAutoConfigureRegistrar.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/JpaRepositoriesAutoConfigureRegistrar.java index 9c33472e7f..6ed9c1da50 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/JpaRepositoriesAutoConfigureRegistrar.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/JpaRepositoriesAutoConfigureRegistrar.java @@ -16,104 +16,31 @@ package org.springframework.boot.autoconfigure.data; -import java.util.Collection; -import java.util.List; - -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.BeanClassLoaderAware; -import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.BeanFactoryAware; -import org.springframework.beans.factory.support.BeanDefinitionBuilder; -import org.springframework.beans.factory.support.BeanDefinitionRegistry; -import org.springframework.boot.autoconfigure.AutoConfigurationUtils; import org.springframework.context.annotation.ImportBeanDefinitionRegistrar; -import org.springframework.core.io.DefaultResourceLoader; -import org.springframework.core.io.ResourceLoader; -import org.springframework.core.type.AnnotationMetadata; -import org.springframework.core.type.StandardAnnotationMetadata; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.data.jpa.repository.config.JpaRepositoryConfigExtension; import org.springframework.data.repository.config.AnnotationRepositoryConfigurationSource; -import org.springframework.data.repository.config.RepositoryBeanDefinitionBuilder; -import org.springframework.data.repository.config.RepositoryBeanNameGenerator; -import org.springframework.data.repository.config.RepositoryConfiguration; import org.springframework.data.repository.config.RepositoryConfigurationExtension; -import org.springframework.util.Assert; /** * {@link ImportBeanDefinitionRegistrar} used to auto-configure Spring Data JPA * Repositories. * * @author Phillip Webb + * @author Dave Syer */ -class JpaRepositoriesAutoConfigureRegistrar implements ImportBeanDefinitionRegistrar, - BeanFactoryAware, BeanClassLoaderAware { - - private BeanFactory beanFactory; - - private ClassLoader beanClassLoader; +class JpaRepositoriesAutoConfigureRegistrar extends + AbstractRepositoryConfigurationSourceSupport { @Override - public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, - final BeanDefinitionRegistry registry) { - - final ResourceLoader resourceLoader = new DefaultResourceLoader(); - final AnnotationRepositoryConfigurationSource configurationSource = getConfigurationSource(); - final RepositoryConfigurationExtension extension = new JpaRepositoryConfigExtension(); - extension.registerBeansForRoot(registry, configurationSource); - - final RepositoryBeanNameGenerator generator = new RepositoryBeanNameGenerator(); - generator.setBeanClassLoader(this.beanClassLoader); - - Collection> repositoryConfigurations = extension - .getRepositoryConfigurations(configurationSource, resourceLoader); - - for (final RepositoryConfiguration repositoryConfiguration : repositoryConfigurations) { - RepositoryBeanDefinitionBuilder builder = new RepositoryBeanDefinitionBuilder( - repositoryConfiguration, extension); - BeanDefinitionBuilder definitionBuilder = builder.build(registry, - resourceLoader); - extension.postProcess(definitionBuilder, configurationSource); - - String beanName = generator.generateBeanName( - definitionBuilder.getBeanDefinition(), registry); - registry.registerBeanDefinition(beanName, - definitionBuilder.getBeanDefinition()); - } - } - - private AnnotationRepositoryConfigurationSource getConfigurationSource() { - StandardAnnotationMetadata metadata = new StandardAnnotationMetadata( - EnableJpaRepositoriesConfiguration.class, true); - AnnotationRepositoryConfigurationSource configurationSource = new AnnotationRepositoryConfigurationSource( - metadata, EnableJpaRepositories.class) { - - @Override - public java.lang.Iterable getBasePackages() { - return JpaRepositoriesAutoConfigureRegistrar.this.getBasePackages(); - }; - }; - return configurationSource; - } - - protected Iterable getBasePackages() { - List basePackages = AutoConfigurationUtils - .getBasePackages(this.beanFactory); - Assert.notEmpty( - basePackages, - "Unable to find JPA repository base packages, please define " - + "a @ComponentScan annotation or disable JpaRepositoriesAutoConfigure"); - return basePackages; + protected AnnotationRepositoryConfigurationSource getConfigurationSource() { + return getConfigurationSource(EnableJpaRepositoriesConfiguration.class, + EnableJpaRepositories.class); } @Override - public void setBeanFactory(BeanFactory beanFactory) throws BeansException { - this.beanFactory = beanFactory; - } - - @Override - public void setBeanClassLoader(ClassLoader classLoader) { - this.beanClassLoader = classLoader; + protected RepositoryConfigurationExtension getRepositoryConfigurationExtension() { + return new JpaRepositoryConfigExtension(); } @EnableJpaRepositories diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/MongoRepositoriesAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/MongoRepositoriesAutoConfiguration.java new file mode 100644 index 0000000000..6978513750 --- /dev/null +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/MongoRepositoriesAutoConfiguration.java @@ -0,0 +1,133 @@ +/* + * Copyright 2012-2013 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.boot.autoconfigure.data; + +import java.net.UnknownHostException; + +import javax.annotation.PreDestroy; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.data.mongodb.repository.MongoRepository; +import org.springframework.data.mongodb.repository.config.EnableMongoRepositories; + +import com.mongodb.DBPort; +import com.mongodb.Mongo; +import com.mongodb.MongoURI; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for Spring Data's Mongo + * Repositories. + * + * @author Dave Syer + * @see EnableMongoRepositories + */ +@Configuration +@ConditionalOnClass({ Mongo.class, MongoRepository.class }) +public class MongoRepositoriesAutoConfiguration { + + @Import(MongoRepositoriesAutoConfigureRegistrar.class) + @Configuration + @EnableConfigurationProperties(MongoProperties.class) + protected static class MongoRepositoriesConfiguration { + + @Autowired + private MongoProperties config; + + @PreDestroy + public void close() throws UnknownHostException { + mongo().close(); + } + + @Bean + @ConditionalOnMissingBean(Mongo.class) + Mongo mongo() throws UnknownHostException { + return this.config.mongo(); + } + + @Bean + @ConditionalOnMissingBean(MongoTemplate.class) + MongoTemplate mongoTemplate(Mongo mongo) throws UnknownHostException { + return new MongoTemplate(mongo, this.config.database()); + } + + } + + @ConfigurationProperties(name = "spring.data.mongo") + public static class MongoProperties { + + private String host; + + private int port = DBPort.PORT; + + private String uri = "mongodb://localhost/test"; + + private String database; + + public String getHost() { + return this.host; + } + + public String database() { + return this.database == null ? new MongoURI(this.uri).getDatabase() + : this.database; + } + + public Mongo mongo() throws UnknownHostException { + return this.host != null ? new Mongo(this.host, this.port) : new Mongo( + new MongoURI(this.uri)); + } + + public void setHost(String host) { + this.host = host; + } + + public String getDatabase() { + return this.database; + } + + public void setDatabase(String database) { + this.database = database; + } + + public String getUri() { + return this.uri; + } + + public void setUri(String uri) { + this.uri = uri; + } + + public int getPort() { + return this.port; + } + + public void setPort(int port) { + this.port = port; + } + + } + +} diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/MongoRepositoriesAutoConfigureRegistrar.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/MongoRepositoriesAutoConfigureRegistrar.java new file mode 100644 index 0000000000..0edd0d186a --- /dev/null +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/MongoRepositoriesAutoConfigureRegistrar.java @@ -0,0 +1,49 @@ +/* + * Copyright 2012-2013 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.boot.autoconfigure.data; + +import org.springframework.context.annotation.ImportBeanDefinitionRegistrar; +import org.springframework.data.mongodb.repository.config.EnableMongoRepositories; +import org.springframework.data.mongodb.repository.config.MongoRepositoryConfigurationExtension; +import org.springframework.data.repository.config.AnnotationRepositoryConfigurationSource; +import org.springframework.data.repository.config.RepositoryConfigurationExtension; + +/** + * {@link ImportBeanDefinitionRegistrar} used to auto-configure Spring Data Mongo + * Repositories. + * + * @author Dave Syer + */ +class MongoRepositoriesAutoConfigureRegistrar extends + AbstractRepositoryConfigurationSourceSupport { + + @Override + protected AnnotationRepositoryConfigurationSource getConfigurationSource() { + return getConfigurationSource(EnableMongoRepositoriesConfiguration.class, + EnableMongoRepositories.class); + } + + @Override + protected RepositoryConfigurationExtension getRepositoryConfigurationExtension() { + return new MongoRepositoryConfigurationExtension(); + } + + @EnableMongoRepositories + private static class EnableMongoRepositoriesConfiguration { + } + +} diff --git a/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories b/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories index 106c3316a5..7123ea0f52 100644 --- a/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories +++ b/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories @@ -5,6 +5,7 @@ org.springframework.boot.autoconfigure.MessageSourceAutoConfiguration,\ org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration,\ org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\ org.springframework.boot.autoconfigure.data.JpaRepositoriesAutoConfiguration,\ +org.springframework.boot.autoconfigure.data.MongoRepositoriesAutoConfiguration,\ org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\ org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,\ org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\ diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/JpaRepositoriesAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/JpaRepositoriesAutoConfigurationTests.java index bf8ce57c49..5bd24ce40b 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/JpaRepositoriesAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/JpaRepositoriesAutoConfigurationTests.java @@ -21,8 +21,8 @@ import javax.persistence.EntityManagerFactory; import org.junit.Test; import org.springframework.boot.autoconfigure.ComponentScanDetectorConfiguration; import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.autoconfigure.data.test.City; -import org.springframework.boot.autoconfigure.data.test.CityRepository; +import org.springframework.boot.autoconfigure.data.jpa.City; +import org.springframework.boot.autoconfigure.data.jpa.CityRepository; import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration; import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; import org.springframework.context.annotation.AnnotationConfigApplicationContext; diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/JpaWebAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/JpaWebAutoConfigurationTests.java index d81b3917ad..ca517094d4 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/JpaWebAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/JpaWebAutoConfigurationTests.java @@ -20,8 +20,8 @@ import org.junit.Ignore; import org.junit.Test; import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration; import org.springframework.boot.autoconfigure.data.JpaRepositoriesAutoConfiguration; -import org.springframework.boot.autoconfigure.data.test.City; -import org.springframework.boot.autoconfigure.data.test.CityRepository; +import org.springframework.boot.autoconfigure.data.jpa.City; +import org.springframework.boot.autoconfigure.data.jpa.CityRepository; import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration; import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; import org.springframework.context.annotation.ComponentScan; diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/MongoRepositoriesAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/MongoRepositoriesAutoConfigurationTests.java new file mode 100644 index 0000000000..5e45b97cfd --- /dev/null +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/MongoRepositoriesAutoConfigurationTests.java @@ -0,0 +1,75 @@ +/* + * Copyright 2012-2013 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.boot.autoconfigure.data; + +import org.junit.Test; +import org.springframework.boot.autoconfigure.ComponentScanDetectorConfiguration; +import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration; +import org.springframework.boot.autoconfigure.data.mongo.City; +import org.springframework.boot.autoconfigure.data.mongo.CityRepository; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +import com.mongodb.Mongo; + +import static org.junit.Assert.assertNotNull; + +/** + * Tests for {@link MongoRepositoriesAutoConfiguration}. + * + * @author Dave Syer + */ +public class MongoRepositoriesAutoConfigurationTests { + + private AnnotationConfigApplicationContext context; + + @Test + public void testDefaultRepositoryConfiguration() throws Exception { + this.context = new AnnotationConfigApplicationContext(); + this.context.register(TestConfiguration.class, + ComponentScanDetectorConfiguration.class, + MongoRepositoriesAutoConfiguration.class, + PropertyPlaceholderAutoConfiguration.class); + this.context.refresh(); + assertNotNull(this.context.getBean(CityRepository.class)); + assertNotNull(this.context.getBean(Mongo.class)); + } + + @Test + public void testNoRepositoryConfiguration() throws Exception { + this.context = new AnnotationConfigApplicationContext(); + this.context.register(EmptyConfiguration.class, + ComponentScanDetectorConfiguration.class, + MongoRepositoriesAutoConfiguration.class, + PropertyPlaceholderAutoConfiguration.class); + this.context.refresh(); + assertNotNull(this.context.getBean(Mongo.class)); + } + + @Configuration + @ComponentScan(basePackageClasses = City.class) + protected static class TestConfiguration { + + } + + @Configuration + protected static class EmptyConfiguration { + + } + +} diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/test/City.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/jpa/City.java similarity index 96% rename from spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/test/City.java rename to spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/jpa/City.java index 4c8a983265..39ffcc044a 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/test/City.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/jpa/City.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.test; +package org.springframework.boot.autoconfigure.data.jpa; import java.io.Serializable; diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/test/CityRepository.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/jpa/CityRepository.java similarity index 94% rename from spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/test/CityRepository.java rename to spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/jpa/CityRepository.java index bc931f0491..68c67c73bd 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/test/CityRepository.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/jpa/CityRepository.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.test; +package org.springframework.boot.autoconfigure.data.jpa; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/City.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/City.java new file mode 100644 index 0000000000..00ced41abb --- /dev/null +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/City.java @@ -0,0 +1,76 @@ +/* + * Copyright 2012-2013 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.boot.autoconfigure.data.mongo; + +import java.io.Serializable; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; + +@Entity +public class City implements Serializable { + + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue + private Long id; + + @Column(nullable = false) + private String name; + + @Column(nullable = false) + private String state; + + @Column(nullable = false) + private String country; + + @Column(nullable = false) + private String map; + + protected City() { + } + + public City(String name, String country) { + super(); + this.name = name; + this.country = country; + } + + public String getName() { + return this.name; + } + + public String getState() { + return this.state; + } + + public String getCountry() { + return this.country; + } + + public String getMap() { + return this.map; + } + + @Override + public String toString() { + return getName() + "," + getState() + "," + getCountry(); + } +} diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/CityRepository.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/CityRepository.java new file mode 100644 index 0000000000..19048564ef --- /dev/null +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/CityRepository.java @@ -0,0 +1,32 @@ +/* + * Copyright 2012-2013 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.boot.autoconfigure.data.mongo; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.repository.Repository; + +public interface CityRepository extends Repository { + + Page findAll(Pageable pageable); + + Page findByNameLikeAndCountryLikeAllIgnoringCase(String name, String country, + Pageable pageable); + + City findByNameAndCountryAllIgnoringCase(String name, String country); + +} diff --git a/spring-boot-samples/pom.xml b/spring-boot-samples/pom.xml index f837e75404..9e7c13d329 100644 --- a/spring-boot-samples/pom.xml +++ b/spring-boot-samples/pom.xml @@ -19,6 +19,7 @@ spring-boot-sample-aop spring-boot-sample-batch spring-boot-sample-data-jpa + spring-boot-sample-data-mongo spring-boot-sample-integration spring-boot-sample-jetty spring-boot-sample-profile diff --git a/spring-boot-samples/spring-boot-sample-data-mongo/pom.xml b/spring-boot-samples/spring-boot-sample-data-mongo/pom.xml new file mode 100644 index 0000000000..a6ed8521f4 --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-data-mongo/pom.xml @@ -0,0 +1,34 @@ + + + 4.0.0 + + + org.springframework.boot + spring-boot-samples + 0.5.0.BUILD-SNAPSHOT + + spring-boot-sample-data-mongo + jar + + ${basedir}/../.. + + + + org.springframework.boot + spring-boot-starter + + + org.springframework.data + spring-data-mongodb + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + diff --git a/spring-boot-samples/spring-boot-sample-data-mongo/src/main/java/org/springframework/boot/sample/data/mongo/Customer.java b/spring-boot-samples/spring-boot-sample-data-mongo/src/main/java/org/springframework/boot/sample/data/mongo/Customer.java new file mode 100644 index 0000000000..f7e2cfe80e --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-data-mongo/src/main/java/org/springframework/boot/sample/data/mongo/Customer.java @@ -0,0 +1,29 @@ +package org.springframework.boot.sample.data.mongo; + +import org.springframework.data.annotation.Id; + + +public class Customer { + + @Id + private String id; + + private String firstName; + private String lastName; + + public Customer() {} + + public Customer(String firstName, String lastName) { + this.firstName = firstName; + this.lastName = lastName; + } + + @Override + public String toString() { + return String.format( + "Customer[id=%s, firstName='%s', lastName='%s']", + id, firstName, lastName); + } + +} + diff --git a/spring-boot-samples/spring-boot-sample-data-mongo/src/main/java/org/springframework/boot/sample/data/mongo/CustomerRepository.java b/spring-boot-samples/spring-boot-sample-data-mongo/src/main/java/org/springframework/boot/sample/data/mongo/CustomerRepository.java new file mode 100644 index 0000000000..2a6b2dfba3 --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-data-mongo/src/main/java/org/springframework/boot/sample/data/mongo/CustomerRepository.java @@ -0,0 +1,12 @@ +package org.springframework.boot.sample.data.mongo; + +import java.util.List; + +import org.springframework.data.mongodb.repository.MongoRepository; + +public interface CustomerRepository extends MongoRepository { + + public Customer findByFirstName(String firstName); + public List findByLastName(String lastName); + +} diff --git a/spring-boot-samples/spring-boot-sample-data-mongo/src/main/java/org/springframework/boot/sample/data/mongo/SampleMongoApplication.java b/spring-boot-samples/spring-boot-sample-data-mongo/src/main/java/org/springframework/boot/sample/data/mongo/SampleMongoApplication.java new file mode 100644 index 0000000000..59c8e8f0e8 --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-data-mongo/src/main/java/org/springframework/boot/sample/data/mongo/SampleMongoApplication.java @@ -0,0 +1,67 @@ +/* + * Copyright 2013 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.boot.sample.data.mongo; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +@Configuration +@EnableAutoConfiguration +@ComponentScan +public class SampleMongoApplication implements CommandLineRunner { + + @Autowired + private CustomerRepository repository; + + @Override + public void run(String... args) throws Exception { + + repository.deleteAll(); + + // save a couple of customers + repository.save(new Customer("Alice", "Smith")); + repository.save(new Customer("Bob", "Smith")); + + // fetch all customers + System.out.println("Customers found with findAll():"); + System.out.println("-------------------------------"); + for (Customer customer : repository.findAll()) { + System.out.println(customer); + } + System.out.println(); + + // fetch an individual customer + System.out.println("Customer found with findByFirstName('Alice'):"); + System.out.println("--------------------------------"); + System.out.println(repository.findByFirstName("Alice")); + + System.out.println("Customers found with findByLastName('Smith'):"); + System.out.println("--------------------------------"); + for (Customer customer : repository.findByLastName("Smith")) { + System.out.println(customer); + } + + } + + public static void main(String[] args) throws Exception { + SpringApplication.run(SampleMongoApplication.class, args); + } +} diff --git a/spring-boot-samples/spring-boot-sample-data-mongo/src/test/java/org/springframework/boot/sample/data/mongo/SampleMongoApplicationTests.java b/spring-boot-samples/spring-boot-sample-data-mongo/src/test/java/org/springframework/boot/sample/data/mongo/SampleMongoApplicationTests.java new file mode 100644 index 0000000000..d962084e42 --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-data-mongo/src/test/java/org/springframework/boot/sample/data/mongo/SampleMongoApplicationTests.java @@ -0,0 +1,42 @@ +/* + * Copyright 2012-2013 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.boot.sample.data.mongo; + +import static org.junit.Assert.assertTrue; + +import org.junit.Rule; +import org.junit.Test; +import org.springframework.boot.OutputCapture; + +/** + * Tests for {@link SampleMongoApplication}. + * + * @author Dave Syer + */ +public class SampleMongoApplicationTests { + + @Rule + public OutputCapture outputCapture = new OutputCapture(); + + @Test + public void testDefaultSettings() throws Exception { + SampleMongoApplication.main(new String[0]); + String output = this.outputCapture.toString(); + assertTrue("Wrong output: " + output, output.contains("firstName='Alice', lastName='Smith'")); + } + +} diff --git a/spring-boot/src/main/java/org/springframework/boot/ansi/AnsiOutput.java b/spring-boot/src/main/java/org/springframework/boot/ansi/AnsiOutput.java index bb5d3b8299..5d14dd8c2c 100644 --- a/spring-boot/src/main/java/org/springframework/boot/ansi/AnsiOutput.java +++ b/spring-boot/src/main/java/org/springframework/boot/ansi/AnsiOutput.java @@ -110,10 +110,15 @@ public abstract class AnsiOutput { } private static boolean detectIfEnabled() { - if (System.console() == null) { + try { + if (System.console() == null) { + return false; + } + return !(OPERATING_SYSTEM_NAME.indexOf("win") >= 0); + } + catch (Throwable e) { return false; } - return !(OPERATING_SYSTEM_NAME.indexOf("win") >= 0); } public static enum Enabled {