From c5a99b5b5e703bfa3948def48d8f7c8b1b69f20e Mon Sep 17 00:00:00 2001 From: Martin Baumgartner Date: Tue, 26 Feb 2013 11:31:48 +0100 Subject: [PATCH] DATAMONGO-140, DATAMONGO-628 - Namespace elements for MongoTemplate and GridFsTemplate. --- .../data/mongodb/config/BeanNames.java | 13 ++- .../mongodb/config/GridFsTemplateParser.java | 78 +++++++++++++ .../mongodb/config/MongoNamespaceHandler.java | 5 +- .../mongodb/config/MongoTemplateParser.java | 86 +++++++++++++++ .../data/mongodb/config/spring-mongo-1.3.xsd | 104 ++++++++++++++++++ .../mongodb/config/MongoNamespaceTests.java | 68 +++++++++++- .../config/MongoNamespaceTests-context.xml | 13 +-- 7 files changed, 351 insertions(+), 16 deletions(-) create mode 100644 spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/GridFsTemplateParser.java create mode 100644 spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoTemplateParser.java diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/BeanNames.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/BeanNames.java index c23121d23..04d2dd16a 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/BeanNames.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/BeanNames.java @@ -1,11 +1,11 @@ /* - * Copyright (c) 2011 by the original author(s). + * Copyright 2011-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 + * 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, @@ -13,11 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.springframework.data.mongodb.config; /** - * @author Jon Brisbin + * Constants to declare bean names used by the namespace configuration. + * + * @author Jon Brisbin + * @author Oliver Gierke + * @author Martin Baumgartner */ public abstract class BeanNames { @@ -28,4 +31,6 @@ public abstract class BeanNames { static final String VALIDATING_EVENT_LISTENER = "validatingMongoEventListener"; static final String IS_NEW_STRATEGY_FACTORY = "isNewStrategyFactory"; static final String DEFAULT_CONVERTER_BEAN_NAME = "mappingConverter"; + static final String MONGO_TEMPLATE = "mongoTemplate"; + static final String GRID_FS_TEMPLATE = "gridFsTemplate"; } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/GridFsTemplateParser.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/GridFsTemplateParser.java new file mode 100644 index 000000000..9f1351e74 --- /dev/null +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/GridFsTemplateParser.java @@ -0,0 +1,78 @@ +/* + * 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.data.mongodb.config; + +import org.springframework.beans.factory.BeanDefinitionStoreException; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.support.AbstractBeanDefinition; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser; +import org.springframework.beans.factory.xml.BeanDefinitionParser; +import org.springframework.beans.factory.xml.ParserContext; +import org.springframework.data.config.BeanComponentDefinitionBuilder; +import org.springframework.data.mongodb.gridfs.GridFsTemplate; +import org.springframework.util.StringUtils; +import org.w3c.dom.Element; + +/** + * {@link BeanDefinitionParser} to parse {@code gridFsTemplate} elements into {@link BeanDefinition}s. + * + * @author Martin Baumgartner + */ +class GridFsTemplateParser extends AbstractBeanDefinitionParser { + + /* + * (non-Javadoc) + * @see org.springframework.beans.factory.xml.AbstractBeanDefinitionParser#resolveId(org.w3c.dom.Element, org.springframework.beans.factory.support.AbstractBeanDefinition, org.springframework.beans.factory.xml.ParserContext) + */ + @Override + protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext) + throws BeanDefinitionStoreException { + + String id = super.resolveId(element, definition, parserContext); + return StringUtils.hasText(id) ? id : BeanNames.GRID_FS_TEMPLATE; + } + + /* + * (non-Javadoc) + * @see org.springframework.beans.factory.xml.AbstractBeanDefinitionParser#parseInternal(org.w3c.dom.Element, org.springframework.beans.factory.xml.ParserContext) + */ + @Override + protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) { + + BeanComponentDefinitionBuilder helper = new BeanComponentDefinitionBuilder(element, parserContext); + + String converterRef = element.getAttribute("converter-ref"); + String dbFactoryRef = element.getAttribute("db-factory-ref"); + + BeanDefinitionBuilder gridFsTemplateBuilder = BeanDefinitionBuilder.genericBeanDefinition(GridFsTemplate.class); + + if (StringUtils.hasText(dbFactoryRef)) { + gridFsTemplateBuilder.addConstructorArgReference(dbFactoryRef); + } else { + gridFsTemplateBuilder.addConstructorArgReference(BeanNames.DB_FACTORY); + } + + if (StringUtils.hasText(converterRef)) { + gridFsTemplateBuilder.addConstructorArgReference(converterRef); + } else { + gridFsTemplateBuilder.addConstructorArgReference(BeanNames.DEFAULT_CONVERTER_BEAN_NAME); + } + + return (AbstractBeanDefinition) helper.getComponentIdButFallback(gridFsTemplateBuilder, BeanNames.GRID_FS_TEMPLATE) + .getBeanDefinition(); + } +} diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoNamespaceHandler.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoNamespaceHandler.java index 048536b58..3a423ec4b 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoNamespaceHandler.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoNamespaceHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2011-2012 the original author or authors. + * Copyright 2011-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. @@ -24,6 +24,7 @@ import org.springframework.data.repository.config.RepositoryConfigurationExtensi * {@link org.springframework.beans.factory.xml.NamespaceHandler} for Mongo DB configuration. * * @author Oliver Gierke + * @author Martin Baumgartner */ public class MongoNamespaceHandler extends NamespaceHandlerSupport { @@ -42,5 +43,7 @@ public class MongoNamespaceHandler extends NamespaceHandlerSupport { registerBeanDefinitionParser("db-factory", new MongoDbFactoryParser()); registerBeanDefinitionParser("jmx", new MongoJmxParser()); registerBeanDefinitionParser("auditing", new MongoAuditingBeanDefinitionParser()); + registerBeanDefinitionParser("template", new MongoTemplateParser()); + registerBeanDefinitionParser("gridFsTemplate", new GridFsTemplateParser()); } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoTemplateParser.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoTemplateParser.java new file mode 100644 index 000000000..0990fdd76 --- /dev/null +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoTemplateParser.java @@ -0,0 +1,86 @@ +/* + * Copyright 2011-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.data.mongodb.config; + +import static org.springframework.data.config.ParsingUtils.*; +import static org.springframework.data.mongodb.config.MongoParsingUtils.*; + +import org.springframework.beans.factory.BeanDefinitionStoreException; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.parsing.BeanComponentDefinition; +import org.springframework.beans.factory.support.AbstractBeanDefinition; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser; +import org.springframework.beans.factory.xml.BeanDefinitionParser; +import org.springframework.beans.factory.xml.ParserContext; +import org.springframework.data.config.BeanComponentDefinitionBuilder; +import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.util.StringUtils; +import org.w3c.dom.Element; + +/** + * {@link BeanDefinitionParser} to parse {@code template} elements into {@link BeanDefinition}s. + * + * @author Martin Baumgartner + */ +class MongoTemplateParser extends AbstractBeanDefinitionParser { + + /* + * (non-Javadoc) + * @see org.springframework.beans.factory.xml.AbstractBeanDefinitionParser#resolveId(org.w3c.dom.Element, org.springframework.beans.factory.support.AbstractBeanDefinition, org.springframework.beans.factory.xml.ParserContext) + */ + @Override + protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext) + throws BeanDefinitionStoreException { + + String id = super.resolveId(element, definition, parserContext); + return StringUtils.hasText(id) ? id : BeanNames.MONGO_TEMPLATE; + } + + /* + * (non-Javadoc) + * @see org.springframework.beans.factory.xml.AbstractBeanDefinitionParser#parseInternal(org.w3c.dom.Element, org.springframework.beans.factory.xml.ParserContext) + */ + @Override + protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) { + + BeanComponentDefinitionBuilder helper = new BeanComponentDefinitionBuilder(element, parserContext); + + String converterRef = element.getAttribute("converter-ref"); + String dbFactoryRef = element.getAttribute("db-factory-ref"); + + BeanDefinitionBuilder mongoTemplateBuilder = BeanDefinitionBuilder.genericBeanDefinition(MongoTemplate.class); + setPropertyValue(mongoTemplateBuilder, element, "write-concern", "writeConcern"); + + if (StringUtils.hasText(dbFactoryRef)) { + mongoTemplateBuilder.addConstructorArgReference(dbFactoryRef); + } else { + mongoTemplateBuilder.addConstructorArgReference(BeanNames.DB_FACTORY); + } + + if (StringUtils.hasText(converterRef)) { + mongoTemplateBuilder.addConstructorArgReference(converterRef); + } + + BeanDefinitionBuilder writeConcernPropertyEditorBuilder = getWriteConcernPropertyEditorBuilder(); + + BeanComponentDefinition component = helper.getComponent(writeConcernPropertyEditorBuilder); + parserContext.registerBeanComponent(component); + + return (AbstractBeanDefinition) helper.getComponentIdButFallback(mongoTemplateBuilder, BeanNames.MONGO_TEMPLATE) + .getBeanDefinition(); + } +} diff --git a/spring-data-mongodb/src/main/resources/org/springframework/data/mongodb/config/spring-mongo-1.3.xsd b/spring-data-mongodb/src/main/resources/org/springframework/data/mongodb/config/spring-mongo-1.3.xsd index 59019663c..9b647b62b 100644 --- a/spring-data-mongodb/src/main/resources/org/springframework/data/mongodb/config/spring-mongo-1.3.xsd +++ b/spring-data-mongodb/src/main/resources/org/springframework/data/mongodb/config/spring-mongo-1.3.xsd @@ -490,4 +490,108 @@ This controls if the driver is allowed to read from secondaries or slaves. Defa + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The reference to a DbFactory. + + + + + + + + + + + + The WriteConcern that will be the default value used when asking the MongoDbFactory for a DB object + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The reference to a DbFactory. + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/config/MongoNamespaceTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/config/MongoNamespaceTests.java index 25abc3e72..a11b641e8 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/config/MongoNamespaceTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/config/MongoNamespaceTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2010 the original author or authors. + * Copyright 2010-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. @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.springframework.data.mongodb.config; import static org.junit.Assert.*; @@ -26,12 +25,23 @@ import org.springframework.context.ApplicationContext; import org.springframework.data.authentication.UserCredentials; import org.springframework.data.mongodb.MongoDbFactory; import org.springframework.data.mongodb.core.MongoFactoryBean; +import org.springframework.data.mongodb.core.MongoOperations; +import org.springframework.data.mongodb.core.convert.MongoConverter; +import org.springframework.data.mongodb.gridfs.GridFsOperations; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import com.mongodb.Mongo; import com.mongodb.MongoOptions; +import com.mongodb.WriteConcern; +/** + * Integration tests for the MongoDB namespace. + * + * @author Mark Pollack + * @author Oliver Gierke + * @author Martin Baumgartner + */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration public class MongoNamespaceTests { @@ -58,7 +68,7 @@ public class MongoNamespaceTests { } @Test - public void testSecondMongoDbFactory() throws Exception { + public void testSecondMongoDbFactory() { assertTrue(ctx.containsBean("secondMongoDbFactory")); MongoDbFactory dbf = (MongoDbFactory) ctx.getBean("secondMongoDbFactory"); Mongo mongo = (Mongo) getField(dbf, "mongo"); @@ -68,6 +78,58 @@ public class MongoNamespaceTests { assertEquals("database", getField(dbf, "databaseName")); } + /** + * @see DATAMONGO-140 + */ + @Test + public void testMongoTemplateFactory() { + assertTrue(ctx.containsBean("mongoTemplate")); + MongoOperations operations = (MongoOperations) ctx.getBean("mongoTemplate"); + MongoDbFactory dbf = (MongoDbFactory) getField(operations, "mongoDbFactory"); + assertEquals("database", getField(dbf, "databaseName")); + MongoConverter converter = (MongoConverter) getField(operations, "mongoConverter"); + assertNotNull(converter); + } + + /** + * @see DATAMONGO-140 + */ + @Test + public void testSecondMongoTemplateFactory() { + assertTrue(ctx.containsBean("anotherMongoTemplate")); + MongoOperations operations = (MongoOperations) ctx.getBean("anotherMongoTemplate"); + MongoDbFactory dbf = (MongoDbFactory) getField(operations, "mongoDbFactory"); + assertEquals("database", getField(dbf, "databaseName")); + WriteConcern writeConcern = (WriteConcern) getField(operations, "writeConcern"); + assertEquals(WriteConcern.SAFE, writeConcern); + } + + /** + * @see DATAMONGO-628 + */ + @Test + public void testGridFsTemplateFactory() { + assertTrue(ctx.containsBean("gridFsTemplate")); + GridFsOperations operations = (GridFsOperations) ctx.getBean("gridFsTemplate"); + MongoDbFactory dbf = (MongoDbFactory) getField(operations, "dbFactory"); + assertEquals("database", getField(dbf, "databaseName")); + MongoConverter converter = (MongoConverter) getField(operations, "converter"); + assertNotNull(converter); + } + + /** + * @see DATAMONGO-628 + */ + @Test + public void testSecondGridFsTemplateFactory() { + assertTrue(ctx.containsBean("antoherGridFsTemplate")); + GridFsOperations operations = (GridFsOperations) ctx.getBean("antoherGridFsTemplate"); + MongoDbFactory dbf = (MongoDbFactory) getField(operations, "dbFactory"); + assertEquals("database", getField(dbf, "databaseName")); + MongoConverter converter = (MongoConverter) getField(operations, "converter"); + assertNotNull(converter); + } + @Test @SuppressWarnings("deprecation") public void testMongoSingletonWithPropertyPlaceHolders() throws Exception { diff --git a/spring-data-mongodb/src/test/resources/org/springframework/data/mongodb/config/MongoNamespaceTests-context.xml b/spring-data-mongodb/src/test/resources/org/springframework/data/mongodb/config/MongoNamespaceTests-context.xml index 7a855c595..9467bff01 100644 --- a/spring-data-mongodb/src/test/resources/org/springframework/data/mongodb/config/MongoNamespaceTests-context.xml +++ b/spring-data-mongodb/src/test/resources/org/springframework/data/mongodb/config/MongoNamespaceTests-context.xml @@ -51,13 +51,10 @@ - - - - + + + + + - - - -