Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

DATAMONGO-36 - Added support for JSR-303 validation

Added event listener that uses a java.validation.Validator to trigger validation on an entity before persisting it. This validation is enabled by default if the javx.validation API is present on the classpath. Added namespace attribute 'disable-validation' to allow disabling that auto enabling behavior.
commit 5b13307e3936cf5779f1c420fb36d1dc0b6d6906 1 parent d317bcf
Maciej Walkowiak authored olivergierke committed
Showing with 851 additions and 7 deletions.
  1. +16 −0 spring-data-mongodb/pom.xml
  2. +1 −0  spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/BeanNames.java
  3. +56 −4 spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MappingMongoConverterParser.java
  4. +68 −0 ...mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/event/ValidatingMongoEventListener.java
  5. +2 −1  spring-data-mongodb/src/main/resources/META-INF/spring.schemas
  6. +479 −0 spring-data-mongodb/src/main/resources/org/springframework/data/mongodb/config/spring-mongo-1.1.xsd
  7. +2 −2 ...godb/src/test/java/org/springframework/data/mongodb/config/MappingMongoConverterParserIntegrationTests.java
  8. +68 −0 ...est/java/org/springframework/data/mongodb/config/MappingMongoConverterParserValidationIntegrationTests.java
  9. +48 −0 spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/event/User.java
  10. +61 −0 ...odb/src/test/java/org/springframework/data/mongodb/core/mapping/event/ValidatingMongoEventListenerTest.java
  11. +10 −0 spring-data-mongodb/src/test/resources/namespace/converter-default.xml
  12. +10 −0 spring-data-mongodb/src/test/resources/namespace/converter-validation-disabled.xml
  13. +10 −0 spring-data-mongodb/src/test/resources/namespace/converter-validation-enabled.xml
  14. +19 −0 .../resources/org/springframework/data/mongodb/core/mapping/event/ValidatingMongoEventListenerTest-context.xml
  15. +1 −0  spring-data-mongodb/template.mf
View
16 spring-data-mongodb/pom.xml
@@ -15,6 +15,7 @@
<mongo.version>2.7.1</mongo.version>
<querydsl.version>2.3.2</querydsl.version>
<cdi.version>1.0</cdi.version>
+ <validation.version>1.0.0.GA</validation.version>
<webbeans.version>1.1.3</webbeans.version>
</properties>
@@ -130,6 +131,21 @@
<scope>test</scope>
</dependency>
+ <!-- JSR 303 Validation -->
+ <dependency>
+ <groupId>javax.validation</groupId>
+ <artifactId>validation-api</artifactId>
+ <version>${validation.version}</version>
+ <optional>true</optional>
+ </dependency>
+
+ <dependency>
+ <groupId>org.hibernate</groupId>
+ <artifactId>hibernate-validator</artifactId>
+ <version>4.2.0.Final</version>
+ <scope>test</scope>
+ </dependency>
+
</dependencies>
<build>
View
1  spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/BeanNames.java
@@ -25,4 +25,5 @@
static final String INDEX_HELPER = "indexCreationHelper";
static final String MONGO = "mongo";
static final String DB_FACTORY = "mongoDbFactory";
+ static final String VALIDATING_EVENT_LISTENER = "validatingMongoEventListener";
}
View
60 ...db/src/main/java/org/springframework/data/mongodb/config/MappingMongoConverterParser.java
@@ -1,11 +1,11 @@
/*
- * Copyright (c) 2011 by the original author(s).
+ * Copyright 2011-2012 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,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.springframework.data.mongodb.config.BeanNames.*;
@@ -30,12 +29,14 @@
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.config.RuntimeBeanReference;
+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.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.beans.factory.support.ManagedList;
import org.springframework.beans.factory.support.ManagedSet;
+import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
@@ -52,18 +53,25 @@
import org.springframework.data.mongodb.core.index.MongoPersistentEntityIndexCreator;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
+import org.springframework.data.mongodb.core.mapping.event.ValidatingMongoEventListener;
import org.springframework.util.Assert;
+import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
import org.springframework.util.xml.DomUtils;
import org.w3c.dom.Element;
/**
- * @author Jon Brisbin <jbrisbin@vmware.com>
+ * Bean definition parser for the {@code mapping-converter} element.
+ *
+ * @author Jon Brisbin
* @author Oliver Gierke
+ * @author Maciej Walkowiak
*/
public class MappingMongoConverterParser extends AbstractBeanDefinitionParser {
private static final String BASE_PACKAGE = "base-package";
+ private static final boolean jsr303Present = ClassUtils.isPresent("javax.validation.Validator",
+ MappingMongoConverterParser.class.getClassLoader());
@Override
protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext)
@@ -107,9 +115,53 @@ protected AbstractBeanDefinition parseInternal(Element element, ParserContext pa
registry.registerBeanDefinition(INDEX_HELPER, indexHelperBuilder.getBeanDefinition());
}
+ BeanDefinition validatingMongoEventListener = potentiallyCreateValidatingMongoEventListener(element, parserContext);
+
+ if (validatingMongoEventListener != null) {
+ registry.registerBeanDefinition(VALIDATING_EVENT_LISTENER, validatingMongoEventListener);
+ }
+
return converterBuilder.getBeanDefinition();
}
+ private BeanDefinition potentiallyCreateValidatingMongoEventListener(Element element, ParserContext parserContext) {
+
+ String disableValidation = element.getAttribute("disable-validation");
+ boolean validationDisabled = StringUtils.hasText(disableValidation) && Boolean.valueOf(disableValidation);
+
+ if (!validationDisabled) {
+
+ BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition();
+ RuntimeBeanReference validator = getValidator(builder, parserContext);
+
+ if (validator != null) {
+
+ builder.getRawBeanDefinition().setBeanClass(ValidatingMongoEventListener.class);
+ builder.addConstructorArgValue(validator);
+
+ return builder.getBeanDefinition();
+ }
+ }
+
+ return null;
+ }
+
+ private RuntimeBeanReference getValidator(Object source, ParserContext parserContext) {
+
+ if (!jsr303Present) {
+ return null;
+ }
+
+ RootBeanDefinition validatorDef = new RootBeanDefinition(
+ "org.springframework.validation.beanvalidation.LocalValidatorFactoryBean");
+ validatorDef.setSource(source);
+ validatorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
+ String validatorName = parserContext.getReaderContext().registerWithGeneratedName(validatorDef);
+ parserContext.registerComponent(new BeanComponentDefinition(validatorDef, validatorName));
+
+ return new RuntimeBeanReference(validatorName);
+ }
+
private String potentiallyCreateMappingContext(Element element, ParserContext parserContext,
BeanDefinition conversionsDefinition) {
View
68 ...ava/org/springframework/data/mongodb/core/mapping/event/ValidatingMongoEventListener.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2012 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.core.mapping.event;
+
+import java.util.Set;
+
+import javax.validation.ConstraintViolationException;
+import javax.validation.Validator;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.util.Assert;
+
+import com.mongodb.DBObject;
+
+/**
+ * javax.validation dependant entities validator. When it is registered as Spring component its automatically invoked
+ * before entities are saved in database.
+ *
+ * @author Maciej Walkowiak
+ */
+public class ValidatingMongoEventListener extends AbstractMongoEventListener<Object> {
+
+ private static final Logger LOG = LoggerFactory.getLogger(ValidatingMongoEventListener.class);
+
+ private final Validator validator;
+
+ /**
+ * Creates a new {@link ValidatingMongoEventListener} using the given {@link Validator}.
+ *
+ * @param validator must not be {@literal null}.
+ */
+ public ValidatingMongoEventListener(Validator validator) {
+ Assert.notNull(validator);
+ this.validator = validator;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.data.mongodb.core.mapping.event.AbstractMongoEventListener#onBeforeSave(java.lang.Object, com.mongodb.DBObject)
+ */
+ @Override
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ public void onBeforeSave(Object source, DBObject dbo) {
+
+ LOG.debug("Validating object: {}", source);
+ Set violations = validator.validate(source);
+
+ if (!violations.isEmpty()) {
+
+ LOG.info("During object: {} validation violations found: {}", source, violations);
+ throw new ConstraintViolationException(violations);
+ }
+ }
+}
View
3  spring-data-mongodb/src/main/resources/META-INF/spring.schemas
@@ -1,2 +1,3 @@
+http\://www.springframework.org/schema/data/mongo/spring-mongo-1.1.xsd=org/springframework/data/mongodb/config/spring-mongo-1.1.xsd
http\://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd=org/springframework/data/mongodb/config/spring-mongo-1.0.xsd
-http\://www.springframework.org/schema/data/mongo/spring-mongo.xsd=org/springframework/data/mongodb/config/spring-mongo-1.0.xsd
+http\://www.springframework.org/schema/data/mongo/spring-mongo.xsd=org/springframework/data/mongodb/config/spring-mongo-1.1.xsd
View
479 ...a-mongodb/src/main/resources/org/springframework/data/mongodb/config/spring-mongo-1.1.xsd
@@ -0,0 +1,479 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<xsd:schema xmlns="http://www.springframework.org/schema/data/mongo"
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:beans="http://www.springframework.org/schema/beans"
+ xmlns:tool="http://www.springframework.org/schema/tool"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xmlns:repository="http://www.springframework.org/schema/data/repository"
+ targetNamespace="http://www.springframework.org/schema/data/mongo"
+ elementFormDefault="qualified" attributeFormDefault="unqualified">
+
+ <xsd:import namespace="http://www.springframework.org/schema/beans" />
+ <xsd:import namespace="http://www.springframework.org/schema/tool" />
+ <xsd:import namespace="http://www.springframework.org/schema/context"
+ schemaLocation="http://www.springframework.org/schema/context/spring-context.xsd" />
+ <xsd:import namespace="http://www.springframework.org/schema/data/repository"
+ schemaLocation="http://www.springframework.org/schema/data/repository/spring-repository.xsd" />
+
+ <xsd:element name="mongo" type="mongoType">
+ <xsd:annotation>
+ <xsd:documentation source="org.springframework.data.mongodb.core.core.MongoFactoryBean"><![CDATA[
+Defines a Mongo instance used for accessing MongoDB'.
+ ]]></xsd:documentation>
+ <xsd:appinfo>
+ <tool:annotation>
+ <tool:exports type="com.mongodb.Mongo"/>
+ </tool:annotation>
+ </xsd:appinfo>
+ </xsd:annotation>
+ </xsd:element>
+
+ <xsd:element name="db-factory">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+Defines a MongoDbFactory for connecting to a specific database
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ <xsd:complexType>
+ <xsd:attribute name="id" type="xsd:ID" use="optional">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+The name of the mongo definition (by default "mongoDbFactory").]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="mongo-ref" type="mongoRef" use="optional">
+ <xsd:annotation>
+ <xsd:documentation>
+ The reference to a Mongo. Will default to 'mongo'.
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="dbname" type="xsd:string" use="optional">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+The name of the database to connect to. Default is 'db'.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="port" type="xsd:string" use="optional">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+The port to connect to MongoDB server. Default is 27017
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="host" type="xsd:string" use="optional">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+The host to connect to a MongoDB server. Default is localhost
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="username" type="xsd:string" use="optional">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+The username to use when connecting to a MongoDB server.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="password" type="xsd:string" use="optional">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+The password to use when connecting to a MongoDB server.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="uri" type="xsd:string" use="optional">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+The Mongo URI string.]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="write-concern">
+ <xsd:annotation>
+ <xsd:documentation>
+ The WriteConcern that will be the default value used when asking the MongoDbFactory for a DB object
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:simpleType>
+ <xsd:union memberTypes="writeConcernEnumeration xsd:string"/>
+ </xsd:simpleType>
+ </xsd:attribute>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:complexType name="mongo-repository">
+ <xsd:complexContent>
+ <xsd:extension base="repository:repository">
+ <xsd:attributeGroup ref="mongo-repository-attributes"/>
+ <xsd:attributeGroup ref="repository:repository-attributes"/>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ <xsd:attributeGroup name="mongo-repository-attributes">
+ <xsd:attribute name="mongo-template-ref" type="mongoTemplateRef" default="mongoTemplate">
+ <xsd:annotation>
+ <xsd:documentation>
+ The reference to a MongoTemplate. Will default to 'mongoTemplate'.
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="create-query-indexes" type="xsd:boolean" default="false">
+ <xsd:annotation>
+ <xsd:documentation>
+ Enables creation of indexes for queries that get derived from the method name
+ and thus reference domain class properties. Defaults to false.
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ </xsd:attributeGroup>
+
+ <xsd:element name="repositories">
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="repository:repositories">
+ <xsd:sequence>
+ <xsd:element name="repository" minOccurs="0" maxOccurs="unbounded" type="mongo-repository"/>
+ </xsd:sequence>
+ <xsd:attributeGroup ref="mongo-repository-attributes"/>
+ <xsd:attributeGroup ref="repository:repository-attributes"/>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="mapping-converter">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[Defines a MongoConverter for getting rich mapping functionality.]]></xsd:documentation>
+ <xsd:appinfo>
+ <tool:exports type="org.springframework.data.mongodb.core.convert.MappingMongoConverter" />
+ </xsd:appinfo>
+ </xsd:annotation>
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="custom-converters" minOccurs="0">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ Top-level element that contains one or more custom converters to be used for mapping
+ domain objects to and from Mongo's DBObject]]>
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="converter" type="customConverterType" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ <xsd:attribute name="base-package" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:sequence>
+ <xsd:attribute name="id" type="xsd:ID" use="optional">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+The name of the MappingMongoConverter instance (by default "mappingConverter").]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="base-package" type="xsd:string" use="optional">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+The base package in which to scan for entities annotated with @Document
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="db-factory-ref" type="xsd:string" use="optional">
+ <xsd:annotation>
+ <xsd:documentation>
+ The reference to a DbFactory.
+ </xsd:documentation>
+ <xsd:appinfo>
+ <tool:annotation kind="ref">
+ <tool:assignable-to type="org.springframework.data.mongodb.MongoDbFactory" />
+ </tool:annotation>
+ </xsd:appinfo>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="mongo-ref" type="mongoRef" use="optional">
+ <xsd:annotation>
+ <xsd:documentation>
+ The reference to a Mongo. Will default to 'mongo'.
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="mapping-context-ref" type="mappingContextRef" use="optional">
+ <xsd:annotation>
+ <xsd:documentation source="org.springframework.data.mapping.model.MappingContext">
+ The reference to a MappingContext. Will default to 'mappingContext'.
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="mongo-template-ref" type="mongoTemplateRef" use="optional">
+ <xsd:annotation>
+ <xsd:documentation source="org.springframework.data.mongodb.core.core.MongoTemplate">
+ The reference to a MongoTemplate. Will default to 'mongoTemplate'.
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="disable-validation" use="optional">
+ <xsd:annotation>
+ <xsd:documentation source="org.springframework.data.mongodb.core.mapping.event.ValidatingMongoEventListener">
+ Disables JSR-303 validation on MongoDB documents before they are saved. By default it is set to false.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:simpleType>
+ <xsd:union memberTypes="xsd:boolean xsd:string"/>
+ </xsd:simpleType>
+ </xsd:attribute>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="jmx">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+Defines a JMX Model MBeans for monitoring a MongoDB server'.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ <xsd:complexType>
+ <xsd:attribute name="mongo-ref" type="mongoRef" use="optional">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+The name of the Mongo object that determines what server to monitor. (by default "mongo").]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:simpleType name="mappingContextRef">
+ <xsd:annotation>
+ <xsd:appinfo>
+ <tool:annotation kind="ref">
+ <tool:assignable-to type="org.springframework.data.mapping.model.MappingContext"/>
+ </tool:annotation>
+ </xsd:appinfo>
+ </xsd:annotation>
+ <xsd:union memberTypes="xsd:string"/>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="mongoTemplateRef">
+ <xsd:annotation>
+ <xsd:appinfo>
+ <tool:annotation kind="ref">
+ <tool:assignable-to type="org.springframework.data.mongodb.core.core.MongoTemplate"/>
+ </tool:annotation>
+ </xsd:appinfo>
+ </xsd:annotation>
+ <xsd:union memberTypes="xsd:string"/>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="mongoRef">
+ <xsd:annotation>
+ <xsd:appinfo>
+ <tool:annotation kind="ref">
+ <tool:assignable-to type="org.springframework.data.mongodb.core.core.MongoFactoryBean"/>
+ </tool:annotation>
+ </xsd:appinfo>
+ </xsd:annotation>
+ <xsd:union memberTypes="xsd:string"/>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="writeConcernEnumeration">
+ <xsd:restriction base="xsd:token">
+ <xsd:enumeration value="NONE" />
+ <xsd:enumeration value="NORMAL" />
+ <xsd:enumeration value="SAFE" />
+ <xsd:enumeration value="FSYNC_SAFE" />
+ <xsd:enumeration value="REPLICAS_SAFE" />
+ <xsd:enumeration value="JOURNAL_SAFE" />
+ <xsd:enumeration value="MAJORITY" />
+ </xsd:restriction>
+ </xsd:simpleType>
+ <!-- MLP
+ <xsd:attributeGroup name="writeConcern">
+ <xsd:attribute name="write-concern">
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="NONE" />
+ <xsd:enumeration value="NORMAL" />
+ <xsd:enumeration value="SAFE" />
+ <xsd:enumeration value="FSYNC_SAFE" />
+ <xsd:enumeration value="REPLICA_SAFE" />
+ <xsd:enumeration value="JOURNAL_SAFE" />
+ <xsd:enumeration value="MAJORITY" />
+ </xsd:restriction>
+ </xsd:simpleType>
+ </xsd:attribute>
+ </xsd:attributeGroup>
+ -->
+ <xsd:complexType name="mongoType">
+ <xsd:sequence minOccurs="0" maxOccurs="1">
+ <xsd:element name="options" type="optionsType">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+The Mongo driver options
+ ]]></xsd:documentation>
+ <xsd:appinfo>
+ <tool:annotation>
+ <tool:exports type="com.mongodb.MongoOptions"/>
+ </tool:annotation>
+ </xsd:appinfo>
+ </xsd:annotation>
+ </xsd:element>
+ </xsd:sequence>
+ <xsd:attribute name="write-concern">
+ <xsd:annotation>
+ <xsd:documentation>
+ The WriteConcern that will be the default value used when asking the MongoDbFactory for a DB object
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:simpleType>
+ <xsd:union memberTypes="writeConcernEnumeration xsd:string"/>
+ </xsd:simpleType>
+ </xsd:attribute>
+ <!-- MLP
+ <xsd:attributeGroup ref="writeConcern" />
+ -->
+ <xsd:attribute name="id" type="xsd:ID" use="optional">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+The name of the mongo definition (by default "mongo").]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="port" type="xsd:string" use="optional">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+The port to connect to MongoDB server. Default is 27017
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="host" type="xsd:string" use="optional">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+The host to connect to a MongoDB server. Default is localhost
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="replica-set" type="xsd:string" use="optional">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+The comma delimited list of host:port entries to use for replica set/pairs.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ </xsd:complexType>
+
+ <xsd:complexType name="optionsType">
+ <xsd:attribute name="connections-per-host" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+The number of connections allowed per host. Will block if run out. Default is 10. System property MONGO.POOLSIZE can override
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="threads-allowed-to-block-for-connection-multiplier" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+The multiplier for connectionsPerHost for # of threads that can block. Default is 5.
+If connectionsPerHost is 10, and threadsAllowedToBlockForConnectionMultiplier is 5,
+then 50 threads can block more than that and an exception will be thrown.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="max-wait-time" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+The max wait time of a blocking thread for a connection. Default is 12000 ms (2 minutes)
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="connect-timeout" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+The connect timeout in milliseconds. 0 is default and infinite.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="socket-timeout" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+The socket timeout. 0 is default and infinite.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="socket-keep-alive" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+The keep alive flag, controls whether or not to have socket keep alive timeout. Defaults to false.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="auto-connect-retry" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+This controls whether or not on a connect, the system retries automatically. Default is false.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="max-auto-connect-retry-time" type="xsd:long">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+The maximum amount of time in millisecons to spend retrying to open connection to the same server. Default is 0, which means to use the default 15s if autoConnectRetry is on.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="write-number" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+This specifies the number of servers to wait for on the write operation, and exception raising behavior. The 'w' option to the getlasterror command. Defaults to 0.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="write-timeout" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+This controls timeout for write operations in milliseconds. The 'wtimeout' option to the getlasterror command. Defaults to 0 (indefinite). Greater than zero is number of milliseconds to wait.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="write-fsync" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+This controls whether or not to fsync. The 'fsync' option to the getlasterror command. Defaults to false.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="slave-ok" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+This controls if the driver is allowed to read from secondaries or slaves. Defaults to false.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ </xsd:complexType>
+
+ <xsd:group name="beanElementGroup">
+ <xsd:choice>
+ <xsd:element ref="beans:bean"/>
+ <xsd:element ref="beans:ref"/>
+ </xsd:choice>
+ </xsd:group>
+
+ <xsd:complexType name="customConverterType">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ Element defining a custom converterr.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ <xsd:group ref="beanElementGroup" minOccurs="0" maxOccurs="1"/>
+ <xsd:attribute name="ref" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation>
+ A reference to a custom converter.
+ </xsd:documentation>
+ <xsd:appinfo>
+ <tool:annotation kind="ref"/>
+ </xsd:appinfo>
+ </xsd:annotation>
+ </xsd:attribute>
+ </xsd:complexType>
+
+</xsd:schema>
View
4 .../org/springframework/data/mongodb/config/MappingMongoConverterParserIntegrationTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2011 the original author or authors.
+ * Copyright 2011-2012 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.
@@ -37,7 +37,7 @@
import com.mongodb.DBObject;
/**
- * Integration tests for {@link MongoParser}.
+ * Integration tests for {@link MappingMongoConverterParser}.
*
* @author Oliver Gierke
*/
View
68 ...gframework/data/mongodb/config/MappingMongoConverterParserValidationIntegrationTests.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2012 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.hamcrest.Matchers.*;
+import static org.junit.Assert.*;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.springframework.beans.factory.NoSuchBeanDefinitionException;
+import org.springframework.beans.factory.support.BeanDefinitionReader;
+import org.springframework.beans.factory.support.DefaultListableBeanFactory;
+import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
+import org.springframework.core.io.ClassPathResource;
+
+/**
+ * Integration test for creation of instance of
+ * {@link org.springframework.data.mongodb.core.mapping.event.ValidatingMongoEventListener} by defining
+ * {@code <mongo:mapping-converter />} in context XML.
+ *
+ * @see DATAMONGO-36
+ * @author Maciej Walkowiak
+ */
+public class MappingMongoConverterParserValidationIntegrationTests {
+
+ DefaultListableBeanFactory factory;
+ BeanDefinitionReader reader;
+
+ @Before
+ public void setUp() {
+ factory = new DefaultListableBeanFactory();
+ reader = new XmlBeanDefinitionReader(factory);
+ }
+
+ @Test
+ public void validatingEventListenerCreatedWithDefaultConfig() {
+
+ reader.loadBeanDefinitions(new ClassPathResource("namespace/converter-default.xml"));
+ assertThat(factory.getBean(BeanNames.VALIDATING_EVENT_LISTENER), is(not(nullValue())));
+ }
+
+ @Test
+ public void validatingEventListenerCreatedWhenValidationEnabled() {
+
+ reader.loadBeanDefinitions(new ClassPathResource("namespace/converter-validation-enabled.xml"));
+ assertThat(factory.getBean(BeanNames.VALIDATING_EVENT_LISTENER), is(not(nullValue())));
+ }
+
+ @Test(expected = NoSuchBeanDefinitionException.class)
+ public void validatingEventListenersIsNotCreatedWhenDisabled() {
+
+ reader.loadBeanDefinitions(new ClassPathResource("namespace/converter-validation-disabled.xml"));
+ factory.getBean(BeanNames.VALIDATING_EVENT_LISTENER);
+ }
+}
View
48 ...-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/event/User.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2012 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.core.mapping.event;
+
+import javax.validation.constraints.Min;
+import javax.validation.constraints.Size;
+
+/**
+ * Class used to test JSR-303 validation
+ * {@link org.springframework.data.mongodb.core.mapping.event.ValidatingMongoEventListener}
+ *
+ * @see DATAMONGO-36
+ * @author Maciej Walkowiak
+ */
+public class User {
+
+ @Size(min = 10)
+ private String name;
+
+ @Min(18)
+ private Integer age;
+
+ public User(String name, Integer age) {
+ this.name = name;
+ this.age = age;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public Integer getAge() {
+ return age;
+ }
+}
View
61 ...org/springframework/data/mongodb/core/mapping/event/ValidatingMongoEventListenerTest.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2012 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.core.mapping.event;
+
+import static org.hamcrest.core.IsEqual.*;
+import static org.junit.Assert.*;
+
+import javax.validation.ConstraintViolationException;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+/**
+ * Integration test for {@link ValidatingMongoEventListener}.
+ *
+ * @see DATAMONGO-36
+ * @author Maciej Walkowiak
+ * @author Oliver Gierke
+ */
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration
+public class ValidatingMongoEventListenerTest {
+
+ @Autowired
+ MongoTemplate mongoTemplate;
+
+ @Test
+ public void shouldThrowConstraintViolationException() {
+
+ User user = new User("john", 17);
+
+ try {
+ mongoTemplate.save(user);
+ fail();
+ } catch (ConstraintViolationException e) {
+ assertThat(e.getConstraintViolations().size(), equalTo(2));
+ }
+ }
+
+ @Test
+ public void shouldNotThrowAnyExceptions() {
+ mongoTemplate.save(new User("john smith", 18));
+ }
+}
View
10 spring-data-mongodb/src/test/resources/namespace/converter-default.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:mongo="http://www.springframework.org/schema/data/mongo"
+ xsi:schemaLocation="http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo.xsd
+ http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
+
+ <mongo:mapping-converter />
+
+</beans>
View
10 spring-data-mongodb/src/test/resources/namespace/converter-validation-disabled.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:mongo="http://www.springframework.org/schema/data/mongo"
+ xsi:schemaLocation="http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo.xsd
+ http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
+
+ <mongo:mapping-converter disable-validation="true" />
+
+</beans>
View
10 spring-data-mongodb/src/test/resources/namespace/converter-validation-enabled.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:mongo="http://www.springframework.org/schema/data/mongo"
+ xsi:schemaLocation="http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo.xsd
+ http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
+
+ <mongo:mapping-converter disable-validation="false" />
+
+</beans>
View
19 ...ingframework/data/mongodb/core/mapping/event/ValidatingMongoEventListenerTest-context.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:mongo="http://www.springframework.org/schema/data/mongo"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xsi:schemaLocation="http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo.xsd
+ http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
+
+ <mongo:db-factory />
+
+ <mongo:mapping-converter base-package="org.springframework.data.mongodb.core" />
+
+ <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
+ <constructor-arg name="mongoDbFactory" ref="mongoDbFactory" />
+ <constructor-arg name="mongoConverter" ref="mappingConverter" />
+ </bean>
+
+</beans>
View
1  spring-data-mongodb/template.mf
@@ -12,6 +12,7 @@ Import-Template:
javax.annotation.processing.*;version="0",
javax.enterprise.*;version="${cdi.version:[=.=.=,+1.0.0)}";resolution:=optional,
javax.tools.*;version="0",
+ javax.validation.*;version="${validation.version:[=.=.=.=,+1.0.0)}";resolution:=optional,
org.aopalliance.*;version="[1.0.0, 2.0.0)";resolution:=optional,
org.apache.commons.collections15.*;version="[4.0.0,5.0.0)";resolution:=optional,
org.bson.*;version="0",
Please sign in to comment.
Something went wrong with that request. Please try again.