Author: hardy.ferentschik
Date: 2009-04-22 06:59:38 -0400 (Wed, 22 Apr 2009)
New Revision: 16395
Added:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ConstraintTree.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/MetaConstraint.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/metadata/
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/xml/
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/xml/AnnotationIgnores.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/xml/ValidationBootstrapParameters.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/xml/ValidationXmlParser.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/xml/XmlMappingParser.java
Removed:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/AnnotationIgnores.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ConstraintTree.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/MetaConstraint.java
Modified:
validator/trunk/hibernate-validator-archetype/src/main/java/org/hibernate/validator/quickstart/Car.java
validator/trunk/hibernate-validator-archetype/src/test/java/org/hibernate/validator/quickstart/CarTest.java
validator/trunk/hibernate-validator-tck-runner/src/main/java/org/hibernate/validation/test/StandaloneContainersImpl.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/HibernateValidationProvider.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/BeanMetaDataCache.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/BeanMetaDataImpl.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ConfigurationImpl.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/DefaultValidationProviderResolver.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ExecutionContext.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/MessageInterpolatorContext.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorFactoryImpl.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorImpl.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/xml/Optional.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/xml/TestGroup.java
Log:
HV-142
Extracted the xml parsing code
Modified:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/HibernateValidationProvider.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/HibernateValidationProvider.java 2009-04-22
09:02:56 UTC (rev 16394)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/HibernateValidationProvider.java 2009-04-22
10:59:38 UTC (rev 16395)
@@ -24,8 +24,8 @@
import javax.validation.spi.ConfigurationState;
import javax.validation.spi.ValidationProvider;
+import org.hibernate.validation.engine.ConfigurationImpl;
import org.hibernate.validation.engine.HibernateValidatorConfiguration;
-import org.hibernate.validation.engine.ConfigurationImpl;
import org.hibernate.validation.engine.ValidatorFactoryImpl;
/**
Deleted:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/AnnotationIgnores.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/AnnotationIgnores.java 2009-04-22
09:02:56 UTC (rev 16394)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/AnnotationIgnores.java 2009-04-22
10:59:38 UTC (rev 16395)
@@ -1,119 +0,0 @@
-// $Id:$
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2008, Red Hat Middleware LLC, and individual contributors
-* by the @authors tag. See the copyright.txt in the distribution for a
-* full listing of individual contributors.
-*
-* 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.hibernate.validation.engine;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Member;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.slf4j.Logger;
-
-import org.hibernate.validation.util.LoggerFactory;
-
-/**
- * This class instantiated during the parsing of the XML configuration data and keeps
- * track of the annotations which should be ignored.
- *
- * @author Hardy Ferentschik
- */
-public class AnnotationIgnores {
-
- private static final Logger log = LoggerFactory.make();
-
- /**
- * Keeps track whether the 'ignore-annotations' flag is set on bean level in the
xml configuration. If 'ignore-annotations'
- * is not specified <code>false</code> is the default.
- */
- private final Map<Class<?>, Boolean> ignoreAnnotationDefaults = new
HashMap<Class<?>, Boolean>();
-
- /**
- * Keeps track of explicitly excluded members (fields and properties) for a given class.
If a member appears in
- * the list mapped to a given class 'ignore-annotations' was explicitly set to
<code>true</code> in the configuration
- * for this class.
- */
- private final Map<Class<?>, List<Member>> ignoreAnnotationOnMember =
new HashMap<Class<?>, List<Member>>();
-
- private final List<Class<?>> ignoreAnnotationOnClass = new
ArrayList<Class<?>>();
-
- public void setDefaultIgnoreAnnotation(Class<?> clazz, Boolean b) {
- if ( b == null ) {
- ignoreAnnotationDefaults.put( clazz, Boolean.FALSE );
- }
- else {
- ignoreAnnotationDefaults.put( clazz, b );
- }
- }
-
- public boolean getDefaultIgnoreAnnotation(Class<?> clazz) {
- return ignoreAnnotationDefaults.containsKey( clazz ) &&
ignoreAnnotationDefaults.get( clazz );
- }
-
- public void setIgnoreAnnotationsOnMember(Member member) {
- Class<?> beanClass = member.getDeclaringClass();
- if ( ignoreAnnotationOnMember.get( beanClass ) == null ) {
- List<Member> tmpList = new ArrayList<Member>();
- tmpList.add( member );
- ignoreAnnotationOnMember.put( beanClass, tmpList );
- }
- else {
- ignoreAnnotationOnMember.get( beanClass ).add( member );
- }
- }
-
- public boolean isIgnoreAnnotations(Member member) {
- boolean ignoreAnnotation;
- Class<?> clazz = member.getDeclaringClass();
- List<Member> ignoreAnnotationForMembers = ignoreAnnotationOnMember.get( clazz );
- if ( ignoreAnnotationForMembers == null || !ignoreAnnotationForMembers.contains( member
) ) {
- ignoreAnnotation = getDefaultIgnoreAnnotation( clazz );
- }
- else {
- ignoreAnnotation = ignoreAnnotationForMembers.contains( member );
- }
- if ( ignoreAnnotation ) {
- logMessage( member, clazz );
- }
- return ignoreAnnotation;
- }
-
- private void logMessage(Member member, Class<?> clazz) {
- String type;
- if ( member instanceof Field ) {
- type = "Field";
- }
- else {
- type = "Property";
- }
- log.debug( type + " level annotations are getting ignored for " +
clazz.getName() + "." + member.getName() );
- }
-
- public void setIgnoreAnnotationsOnClass(Class<?> clazz) {
- ignoreAnnotationOnClass.add( clazz );
- }
-
- public boolean isIgnoreAnnotations(Class<?> clazz) {
- boolean ignoreAnnotation = ignoreAnnotationOnClass.contains( clazz ) ||
getDefaultIgnoreAnnotation( clazz );
- if ( log.isDebugEnabled() && ignoreAnnotation ) {
- log.debug( "Class level annotation are getting ignored for " +
clazz.getName() );
- }
- return ignoreAnnotation;
- }
-}
Property changes on:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/BeanMetaDataCache.java
___________________________________________________________________
Name: svn:keywords
+ Id
Modified:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/BeanMetaDataImpl.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/BeanMetaDataImpl.java 2009-04-22
09:02:56 UTC (rev 16394)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/BeanMetaDataImpl.java 2009-04-22
10:59:38 UTC (rev 16395)
@@ -39,6 +39,7 @@
import org.slf4j.Logger;
+import org.hibernate.validation.engine.xml.AnnotationIgnores;
import org.hibernate.validation.util.LoggerFactory;
import org.hibernate.validation.util.ReflectionHelper;
Modified:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ConfigurationImpl.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ConfigurationImpl.java 2009-04-22
09:02:56 UTC (rev 16394)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ConfigurationImpl.java 2009-04-22
10:59:38 UTC (rev 16395)
@@ -18,13 +18,9 @@
package org.hibernate.validation.engine;
import java.io.InputStream;
-import java.net.URL;
-import java.util.HashMap;
-import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import javax.validation.Configuration;
import javax.validation.ConstraintValidatorFactory;
import javax.validation.MessageInterpolator;
import javax.validation.TraversableResolver;
@@ -34,23 +30,14 @@
import javax.validation.spi.BootstrapState;
import javax.validation.spi.ConfigurationState;
import javax.validation.spi.ValidationProvider;
-import javax.xml.bind.JAXBContext;
-import javax.xml.bind.JAXBElement;
-import javax.xml.bind.JAXBException;
-import javax.xml.bind.Unmarshaller;
-import javax.xml.transform.stream.StreamSource;
-import javax.xml.validation.Schema;
-import javax.xml.validation.SchemaFactory;
import org.slf4j.Logger;
-import org.xml.sax.SAXException;
import org.hibernate.validation.engine.resolver.DefaultTraversableResolver;
+import org.hibernate.validation.engine.xml.ValidationBootstrapParameters;
+import org.hibernate.validation.engine.xml.ValidationXmlParser;
import org.hibernate.validation.util.LoggerFactory;
-import org.hibernate.validation.util.ReflectionHelper;
import org.hibernate.validation.util.Version;
-import org.hibernate.validation.xml.PropertyType;
-import org.hibernate.validation.xml.ValidationConfigType;
/**
* Hibernate specific <code>Configuration</code> implementation.
@@ -65,15 +52,13 @@
}
private static final Logger log = LoggerFactory.make();
- private static final String VALIDATION_XML_FILE = "META-INF/validation.xml";
- private static final String VALIDATION_CONFIGURATION_XSD =
"META-INF/validation-configuration-1.0.xsd";
private final MessageInterpolator defaultMessageInterpolator = new
ResourceBundleMessageInterpolator();
private final TraversableResolver defaultTraversableResolver = new
DefaultTraversableResolver();
private final ConstraintValidatorFactory defaultValidatorFactory = new
ConstraintValidatorFactoryImpl();
private final ValidationProviderResolver providerResolver;
- private ParameterHolder parameterHolder;
+ private ValidationBootstrapParameters validationBootstrapParameters;
private boolean ignoreXmlConfiguration = false;
public ConfigurationImpl(BootstrapState state) {
@@ -83,7 +68,7 @@
else {
this.providerResolver = state.getValidationProviderResolver();
}
- parameterHolder = new ParameterHolder();
+ validationBootstrapParameters = new ValidationBootstrapParameters();
}
public ConfigurationImpl(ValidationProvider provider) {
@@ -91,8 +76,8 @@
throw new ValidationException( "Assertion error: inconsistent ConfigurationImpl
construction" );
}
this.providerResolver = null;
- parameterHolder = new ParameterHolder();
- parameterHolder.provider = provider;
+ validationBootstrapParameters = new ValidationBootstrapParameters();
+ validationBootstrapParameters.provider = provider;
}
public HibernateValidatorConfiguration ignoreXmlConfiguration() {
@@ -101,28 +86,28 @@
}
public ConfigurationImpl messageInterpolator(MessageInterpolator interpolator) {
- this.parameterHolder.messageInterpolator = interpolator;
+ this.validationBootstrapParameters.messageInterpolator = interpolator;
return this;
}
public ConfigurationImpl traversableResolver(TraversableResolver resolver) {
- this.parameterHolder.traversableResolver = resolver;
+ this.validationBootstrapParameters.traversableResolver = resolver;
return this;
}
public ConfigurationImpl constraintValidatorFactory(ConstraintValidatorFactory
constraintValidatorFactory) {
- this.parameterHolder.constraintValidatorFactory = constraintValidatorFactory;
+ this.validationBootstrapParameters.constraintValidatorFactory =
constraintValidatorFactory;
return this;
}
public HibernateValidatorConfiguration addMapping(InputStream stream) {
- parameterHolder.mappings.add( stream );
+ validationBootstrapParameters.mappings.add( stream );
return this;
}
public HibernateValidatorConfiguration addProperty(String name, String value) {
if ( value != null ) {
- parameterHolder.configProperties.put( name, value );
+ validationBootstrapParameters.configProperties.put( name, value );
}
return this;
}
@@ -131,18 +116,18 @@
parseValidationXml();
ValidatorFactory factory = null;
if ( isSpecificProvider() ) {
- factory = parameterHolder.provider.buildValidatorFactory( this );
+ factory = validationBootstrapParameters.provider.buildValidatorFactory( this );
}
else {
- if ( parameterHolder.providerClass != null ) {
+ if ( validationBootstrapParameters.providerClass != null ) {
for ( ValidationProvider provider : providerResolver.getValidationProviders() ) {
- if ( provider.isSuitable( parameterHolder.providerClass ) ) {
+ if ( provider.isSuitable( validationBootstrapParameters.providerClass ) ) {
factory = provider.buildValidatorFactory( this );
break;
}
}
if ( factory == null ) {
- throw new ValidationException( "Unable to find provider: " +
parameterHolder.providerClass );
+ throw new ValidationException( "Unable to find provider: " +
validationBootstrapParameters.providerClass );
}
}
else {
@@ -153,7 +138,7 @@
}
// reset the param holder
- parameterHolder = new ParameterHolder();
+ validationBootstrapParameters = new ValidationBootstrapParameters();
return factory;
}
@@ -162,23 +147,23 @@
}
public MessageInterpolator getMessageInterpolator() {
- return parameterHolder.messageInterpolator;
+ return validationBootstrapParameters.messageInterpolator;
}
public Set<InputStream> getMappingStreams() {
- return parameterHolder.mappings;
+ return validationBootstrapParameters.mappings;
}
public ConstraintValidatorFactory getConstraintValidatorFactory() {
- return parameterHolder.constraintValidatorFactory;
+ return validationBootstrapParameters.constraintValidatorFactory;
}
public TraversableResolver getTraversableResolver() {
- return parameterHolder.traversableResolver;
+ return validationBootstrapParameters.traversableResolver;
}
public Map<String, String> getProperties() {
- return parameterHolder.configProperties;
+ return validationBootstrapParameters.configProperties;
}
public MessageInterpolator getDefaultMessageInterpolator() {
@@ -186,7 +171,7 @@
}
private boolean isSpecificProvider() {
- return parameterHolder.provider != null;
+ return validationBootstrapParameters.provider != null;
}
/**
@@ -198,244 +183,46 @@
return;
}
- ValidationConfigType config = getValidationConfig();
- ParameterHolder xmlParameters = new ParameterHolder();
- if ( config != null ) {
- // collect the paramters from the xml file
- setProviderClassFromXml( config, xmlParameters );
- setMessageInterpolatorFromXml( config, xmlParameters );
- setTraversableResolverFromXml( config, xmlParameters );
- setConstraintFactoryFromXml( config, xmlParameters );
- setMappingStreamsFromXml( config, xmlParameters );
- setPropertiesFromXml( config, xmlParameters );
- }
+ ValidationBootstrapParameters xmlParameters = new
ValidationXmlParser().parseValidationXml();
applyXmlSettings( xmlParameters );
}
- private void applyXmlSettings(ParameterHolder xmlParameters) {
- parameterHolder.providerClass = xmlParameters.providerClass;
+ private void applyXmlSettings(ValidationBootstrapParameters xmlParameters) {
+ validationBootstrapParameters.providerClass = xmlParameters.providerClass;
- if ( parameterHolder.messageInterpolator == null ) {
+ if ( validationBootstrapParameters.messageInterpolator == null ) {
if ( xmlParameters.messageInterpolator != null ) {
- parameterHolder.messageInterpolator = xmlParameters.messageInterpolator;
+ validationBootstrapParameters.messageInterpolator =
xmlParameters.messageInterpolator;
}
else {
- parameterHolder.messageInterpolator = defaultMessageInterpolator;
+ validationBootstrapParameters.messageInterpolator = defaultMessageInterpolator;
}
}
- if ( parameterHolder.traversableResolver == null ) {
+ if ( validationBootstrapParameters.traversableResolver == null ) {
if ( xmlParameters.traversableResolver != null ) {
- parameterHolder.traversableResolver = xmlParameters.traversableResolver;
+ validationBootstrapParameters.traversableResolver =
xmlParameters.traversableResolver;
}
else {
- parameterHolder.traversableResolver = defaultTraversableResolver;
+ validationBootstrapParameters.traversableResolver = defaultTraversableResolver;
}
}
- if ( parameterHolder.constraintValidatorFactory == null ) {
+ if ( validationBootstrapParameters.constraintValidatorFactory == null ) {
if ( xmlParameters.constraintValidatorFactory != null ) {
- parameterHolder.constraintValidatorFactory =
xmlParameters.constraintValidatorFactory;
+ validationBootstrapParameters.constraintValidatorFactory =
xmlParameters.constraintValidatorFactory;
}
else {
- parameterHolder.constraintValidatorFactory = defaultValidatorFactory;
+ validationBootstrapParameters.constraintValidatorFactory = defaultValidatorFactory;
}
}
- parameterHolder.mappings.addAll( xmlParameters.mappings );
+ validationBootstrapParameters.mappings.addAll( xmlParameters.mappings );
for ( Map.Entry<String, String> entry : xmlParameters.configProperties.entrySet()
) {
- if ( parameterHolder.configProperties.get( entry.getKey() ) == null ) {
- parameterHolder.configProperties.put( entry.getKey(), entry.getValue() );
+ if ( validationBootstrapParameters.configProperties.get( entry.getKey() ) == null ) {
+ validationBootstrapParameters.configProperties.put( entry.getKey(), entry.getValue()
);
}
}
}
-
- private void setConstraintFactoryFromXml(ValidationConfigType config, ParameterHolder
xmlParameters) {
- String constraintFactoryClass = config.getConstraintValidatorFactory();
- if ( constraintFactoryClass != null ) {
- try {
- @SuppressWarnings("unchecked")
- Class<ConstraintValidatorFactory> clazz = (
Class<ConstraintValidatorFactory> ) ReflectionHelper.classForName(
- constraintFactoryClass, this.getClass()
- );
- xmlParameters.constraintValidatorFactory = clazz.newInstance();
- log.info( "Using {} as constraint factory.", constraintFactoryClass );
- }
- catch ( ClassNotFoundException e ) {
- throw new ValidationException(
- "Unable to instantiate constraint factory class " +
constraintFactoryClass + ".", e
- );
- }
- catch ( InstantiationException e ) {
- throw new ValidationException(
- "Unable to instantiate constraint factory class " +
constraintFactoryClass + ".", e
- );
- }
- catch ( IllegalAccessException e ) {
- throw new ValidationException(
- "Unable to instantiate constraint factory class " +
constraintFactoryClass + ".", e
- );
- }
- }
- }
-
- private void setPropertiesFromXml(ValidationConfigType config, ParameterHolder
xmlParameters) {
- for ( PropertyType property : config.getProperty() ) {
- if ( log.isDebugEnabled() ) {
- log.debug(
- "Found property '{}' with value '{}' in
validation.xml.",
- property.getName(),
- property.getValue()
- );
- }
- xmlParameters.configProperties.put( property.getName(), property.getValue() );
- }
- }
-
- private void setMappingStreamsFromXml(ValidationConfigType config, ParameterHolder
xmlParameters) {
- for ( String mappingFileName : config.getConstraintMapping() ) {
- if ( log.isDebugEnabled() ) {
- log.debug(
- "Trying to open input stream for {}.", mappingFileName
- );
- InputStream in = getInputStreamForPath( mappingFileName );
- if ( in == null ) {
- throw new ValidationException( "Unable to open input stream for mapping file
" + mappingFileName + "." );
- }
- xmlParameters.mappings.add( in );
- }
- }
- }
-
- private void setMessageInterpolatorFromXml(ValidationConfigType config, ParameterHolder
xmlParameters) {
- String messageInterpolatorClass = config.getMessageInterpolator();
- if ( messageInterpolatorClass != null ) {
- try {
- @SuppressWarnings("unchecked")
- Class<MessageInterpolator> clazz = ( Class<MessageInterpolator> )
ReflectionHelper.classForName(
- messageInterpolatorClass, this.getClass()
- );
- xmlParameters.messageInterpolator = clazz.newInstance();
- log.info( "Using {} as message interpolator.", messageInterpolatorClass );
- }
- catch ( ClassNotFoundException e ) {
- throw new ValidationException(
- "Unable to instantiate message interpolator class " +
messageInterpolatorClass + ".", e
- );
- }
- catch ( InstantiationException e ) {
- throw new ValidationException(
- "Unable to instantiate message interpolator class " +
messageInterpolatorClass + ".", e
- );
- }
- catch ( IllegalAccessException e ) {
- throw new ValidationException(
- "Unable to instantiate message interpolator class " +
messageInterpolatorClass + ".", e
- );
- }
- }
- }
-
- private void setTraversableResolverFromXml(ValidationConfigType config, ParameterHolder
xmlParameters) {
- String traversableResolverClass = config.getTraversableResolver();
- if ( traversableResolverClass != null ) {
- try {
- @SuppressWarnings("unchecked")
- Class<TraversableResolver> clazz = ( Class<TraversableResolver> )
ReflectionHelper.classForName(
- traversableResolverClass, this.getClass()
- );
- xmlParameters.traversableResolver = clazz.newInstance();
- log.info( "Using {} as traversable resolver.", traversableResolverClass );
- }
- catch ( ClassNotFoundException e ) {
- throw new ValidationException(
- "Unable to instantiate traversable resolver class " +
traversableResolverClass + ".", e
- );
- }
- catch ( InstantiationException e ) {
- throw new ValidationException(
- "Unable to instantiate traversable resolver class " +
traversableResolverClass + ".", e
- );
- }
- catch ( IllegalAccessException e ) {
- throw new ValidationException(
- "Unable to instantiate traversable resolver class " +
traversableResolverClass + ".", e
- );
- }
- }
- }
-
- @SuppressWarnings("unchecked")
- private void setProviderClassFromXml(ValidationConfigType config, ParameterHolder
xmlParamters) {
- String providerClassName = config.getDefaultProvider();
- if ( providerClassName != null ) {
- try {
- xmlParamters.providerClass = ( Class<? extends Configuration<?>> )
ReflectionHelper.classForName(
- providerClassName, this.getClass()
- );
- log.info( "Using {} as validation provider.", providerClassName );
- }
- catch ( Exception e ) {
- throw new ValidationException( "Unable to instantiate validation provider class
" + providerClassName + "." );
- }
- }
- }
-
- private ValidationConfigType getValidationConfig() {
- InputStream inputStream = getInputStreamForPath( VALIDATION_XML_FILE );
- if ( inputStream == null ) {
- log.info( "No {} found. Using annotation based configuration only!",
VALIDATION_XML_FILE );
- return null;
- }
-
- log.info( "{} found.", VALIDATION_XML_FILE );
-
- ValidationConfigType validationConfig = null;
- Schema schema = getValidationConfigurationSchema();
- try {
- JAXBContext jc = JAXBContext.newInstance( ValidationConfigType.class );
- Unmarshaller unmarshaller = jc.createUnmarshaller();
- unmarshaller.setSchema( schema );
- StreamSource stream = new StreamSource( inputStream );
- JAXBElement<ValidationConfigType> root = unmarshaller.unmarshal( stream,
ValidationConfigType.class );
- validationConfig = root.getValue();
- }
- catch ( JAXBException e ) {
- log.error( "Error parsing validation.xml: {}", e.getMessage() );
- }
- return validationConfig;
- }
-
- private InputStream getInputStreamForPath(String path) {
- InputStream inputStream = this.getClass().getResourceAsStream( path );
- // try absolute path
- if ( inputStream == null && !path.startsWith( "/" ) ) {
- inputStream = this.getClass().getResourceAsStream( "/" + path );
- }
- return inputStream;
- }
-
- private Schema getValidationConfigurationSchema() {
- URL schemaUrl = this.getClass().getClassLoader().getResource(
VALIDATION_CONFIGURATION_XSD );
- SchemaFactory sf = SchemaFactory.newInstance(
javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI );
- Schema schema = null;
- try {
- schema = sf.newSchema( schemaUrl );
- }
- catch ( SAXException e ) {
- log.warn( "Unable to create schema for {}: {}",
VALIDATION_CONFIGURATION_XSD, e.getMessage() );
- }
- return schema;
- }
-
- private static class ParameterHolder {
- ConstraintValidatorFactory constraintValidatorFactory;
- MessageInterpolator messageInterpolator;
- TraversableResolver traversableResolver;
- ValidationProvider provider;
- Class<? extends Configuration<?>> providerClass = null;
- final Map<String, String> configProperties = new HashMap<String,
String>();
- final Set<InputStream> mappings = new HashSet<InputStream>();
- }
}
Deleted:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ConstraintTree.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ConstraintTree.java 2009-04-22
09:02:56 UTC (rev 16394)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ConstraintTree.java 2009-04-22
10:59:38 UTC (rev 16395)
@@ -1,252 +0,0 @@
-// $Id$
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2008, Red Hat Middleware LLC, and individual contributors
-* by the @authors tag. See the copyright.txt in the distribution for a
-* full listing of individual contributors.
-*
-* 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.hibernate.validation.engine;
-
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Array;
-import java.lang.reflect.Type;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import javax.validation.ConstraintDescriptor;
-import javax.validation.ConstraintValidator;
-import javax.validation.ConstraintValidatorFactory;
-import javax.validation.UnexpectedTypeException;
-import javax.validation.ValidationException;
-import javax.validation.ConstraintViolation;
-
-import com.googlecode.jtype.TypeUtils;
-import org.slf4j.Logger;
-
-import org.hibernate.validation.util.LoggerFactory;
-import org.hibernate.validation.util.ValidatorTypeHelper;
-
-/**
- * Due to constraint conposition a single constraint annotation can lead to a whole
constraint tree beeing validated.
- * This class encapsulates such a tree.
- *
- * @author Hardy Ferentschik
- */
-public class ConstraintTree<A extends Annotation> {
-
- private static final Logger log = LoggerFactory.make();
-
- private final ConstraintTree<?> parent;
- private final List<ConstraintTree<?>> children;
- private final ConstraintDescriptor<A> descriptor;
-
- public ConstraintTree(ConstraintDescriptor<A> descriptor) {
- this( descriptor, null );
- }
-
- private ConstraintTree(ConstraintDescriptor<A> descriptor, ConstraintTree<?>
parent) {
- this.parent = parent;
- this.descriptor = descriptor;
- final Set<ConstraintDescriptor<?>> composingConstraints =
descriptor.getComposingConstraints();
- children = new ArrayList<ConstraintTree<?>>( composingConstraints.size()
);
-
- for ( ConstraintDescriptor<?> composingDescriptor : composingConstraints ) {
- ConstraintTree<?> treeNode = createConstraintTree( composingDescriptor );
- children.add( treeNode );
- }
- }
-
- private <U extends Annotation> ConstraintTree<U>
createConstraintTree(ConstraintDescriptor<U> composingDescriptor) {
- return new ConstraintTree<U>( composingDescriptor, this );
- }
-
- public boolean isRoot() {
- return parent == null;
- }
-
- public ConstraintTree getParent() {
- return parent;
- }
-
- public List<ConstraintTree<?>> getChildren() {
- return children;
- }
-
- public boolean hasChildren() {
- return children.size() > 0;
- }
-
- public ConstraintDescriptor<A> getDescriptor() {
- return descriptor;
- }
-
- /**
- * Validates the specified value.
- *
- * @param value The value to validate
- * @param type The type of the value determined from the type the annotation was placed
on.
- * @param executionContext The current execution context.
- * @param constraintViolations List of constraint violation into which to accumulate all
constraint violation as we traverse
- * this <code>ConstraintTree </code>.
- * @param <T> Type of the root bean for the current validation.
- * @param <V> Type of the value to be validated.
- */
- public <T, V> void validateConstraints(V value, Type type,
ExecutionContext<T> executionContext, List<ConstraintViolation<T>>
constraintViolations) {
- for ( ConstraintTree<?> tree : getChildren() ) {
- tree.validateConstraints( value, type, executionContext, constraintViolations );
- }
-
- if ( log.isTraceEnabled() ) {
- log.trace( "Validating value {} against constraint defined by {}", value,
descriptor );
- }
- ConstraintValidator<A, V> validator = getInitalizedValidator(
- value, type, executionContext.getConstraintValidatorFactory()
- );
- ConstraintValidatorContextImpl constraintValidatorContext = new
ConstraintValidatorContextImpl(
- executionContext.peekParentPath(), executionContext.peekProperty(), descriptor
- );
- if ( !validator.isValid( value, constraintValidatorContext ) ) {
- constraintViolations.addAll( executionContext.createConstraintViolations( value,
constraintValidatorContext ) );
- }
- if ( reportAsSingleViolation() && constraintViolations.size() > 0 ) {
- constraintViolations.clear();
- final String message = ( String ) getParent().getDescriptor().getAttributes().get(
"message" );
- final String property = executionContext.peekPropertyPath();
- ConstraintValidatorContextImpl.ErrorMessage error = constraintValidatorContext.new
ErrorMessage( message, property );
- constraintViolations.add( executionContext.createConstraintViolation( value, error,
descriptor ) );
- }
- }
-
- private boolean reportAsSingleViolation() {
- return getParent() != null
- && getParent().getDescriptor().isReportAsSingleViolation();
- }
-
- /**
- * @param value The value to be validated.
- * @param type The type of the value to be validated (the type of the member/class the
constraint was placed on).
- * @param constraintFactory constraint factory used to instantiate the constraint
validator.
- *
- * @return A initalized constraint validator matching the type of the value to be
validated.
- */
- private <V> ConstraintValidator<A, V> getInitalizedValidator(V value, Type
type, ConstraintValidatorFactory constraintFactory) {
- Class<? extends ConstraintValidator<?, ?>> validatorClass =
findMatchingValidatorClass( value, type );
-
- @SuppressWarnings("unchecked")
- ConstraintValidator<A, V> constraintValidator = ( ConstraintValidator<A, V>
) constraintFactory.getInstance(
- validatorClass
- );
- initializeConstraint( descriptor, constraintValidator );
- return constraintValidator;
- }
-
- /**
- * Runs the validator resolution algorithm.
- *
- * @param value The value to be validated.
- * @param type The type of the value to be validated (the type of the member/class the
constraint was placed on).
- *
- * @return The class of a matching validator.
- */
- private Class<? extends ConstraintValidator<?, ?>>
findMatchingValidatorClass(Object value, Type type) {
- Map<Type, Class<? extends ConstraintValidator<?, ?>>> validatorsTypes
=
- ValidatorTypeHelper.getValidatorsTypes( descriptor.getConstraintValidatorClasses()
);
-
- List<Type> suitableTypes = new ArrayList<Type>();
- findSuitableValidatorTypes( type, validatorsTypes, suitableTypes );
- // TODO - do we really have to take the actual value into consideration here as well?
Or is it enough to
- // work with the type the constraint was placed on?
- if ( value != null ) {
- findSuitableValidatorTypes( determineValueClass( value ), validatorsTypes,
suitableTypes );
- }
-
- resolveAssignableTypes( suitableTypes );
- verifyResolveWasUnique( type, suitableTypes );
-
- return validatorsTypes.get( suitableTypes.get( 0 ) );
- }
-
- private Class determineValueClass(Object value) {
- Class valueClass = value.getClass();
- if ( valueClass.isArray() ) {
- valueClass = Array.class;
- }
- return valueClass;
- }
-
- private void verifyResolveWasUnique(Type valueClass, List<Type> assignableClasses)
{
- if ( assignableClasses.size() == 0 ) {
- throw new UnexpectedTypeException( "No validator could be found for type: "
+ valueClass );
- }
- else if ( assignableClasses.size() > 1 ) {
- StringBuilder builder = new StringBuilder();
- builder.append( "There are multiple validators which could validate the type
" );
- builder.append( valueClass );
- builder.append( ". The validator classes are: " );
- for ( Type clazz : assignableClasses ) {
- builder.append( clazz );
- builder.append( ", " );
- }
- builder.delete( builder.length() - 2, builder.length() );
- throw new UnexpectedTypeException( builder.toString() );
- }
- }
-
- private void findSuitableValidatorTypes(Type type, Map<Type, Class<? extends
ConstraintValidator<?, ?>>> validatorsTypes, List<Type> suitableTypes)
{
- for ( Type validatorType : validatorsTypes.keySet() ) {
- if ( TypeUtils.isAssignable( validatorType, type ) && !suitableTypes.contains(
validatorType ) ) {
- suitableTypes.add( validatorType );
- }
- }
- }
-
- /**
- * Tries to reduce all assignable classes down to a single class.
- *
- * @param assignableTypes The set of all classes which are assignable to the class of
the value to be validated and
- * which are handled by at least one of the validators for the specified constraint.
- */
- private void resolveAssignableTypes(List<Type> assignableTypes) {
- if ( assignableTypes.size() == 0 || assignableTypes.size() == 1 ) {
- return;
- }
-
- List<Type> typesToRemove = new ArrayList<Type>();
- do {
- typesToRemove.clear();
- Type type = assignableTypes.get( 0 );
- for ( int i = 1; i < assignableTypes.size(); i++ ) {
- if ( TypeUtils.isAssignable( type, assignableTypes.get( i ) ) ) {
- typesToRemove.add( type );
- }
- else if ( TypeUtils.isAssignable( assignableTypes.get( i ), type ) ) {
- typesToRemove.add( assignableTypes.get( i ) );
- }
- }
- assignableTypes.removeAll( typesToRemove );
- } while ( typesToRemove.size() > 0 );
- }
-
- private <V> void initializeConstraint
- (ConstraintDescriptor<A>
- descriptor, ConstraintValidator<A, V>
- constraintValidator) {
- try {
- constraintValidator.initialize( descriptor.getAnnotation() );
- }
- catch ( RuntimeException e ) {
- throw new ValidationException( "Unable to intialize " +
constraintValidator.getClass().getName(), e );
- }
- }
-}
Added:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ConstraintTree.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ConstraintTree.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ConstraintTree.java 2009-04-22
10:59:38 UTC (rev 16395)
@@ -0,0 +1,252 @@
+// $Id$
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, and individual contributors
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* 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.hibernate.validation.engine;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Array;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.validation.ConstraintDescriptor;
+import javax.validation.ConstraintValidator;
+import javax.validation.ConstraintValidatorFactory;
+import javax.validation.ConstraintViolation;
+import javax.validation.UnexpectedTypeException;
+import javax.validation.ValidationException;
+
+import com.googlecode.jtype.TypeUtils;
+import org.slf4j.Logger;
+
+import org.hibernate.validation.util.LoggerFactory;
+import org.hibernate.validation.util.ValidatorTypeHelper;
+
+/**
+ * Due to constraint conposition a single constraint annotation can lead to a whole
constraint tree beeing validated.
+ * This class encapsulates such a tree.
+ *
+ * @author Hardy Ferentschik
+ */
+public class ConstraintTree<A extends Annotation> {
+
+ private static final Logger log = LoggerFactory.make();
+
+ private final ConstraintTree<?> parent;
+ private final List<ConstraintTree<?>> children;
+ private final ConstraintDescriptor<A> descriptor;
+
+ public ConstraintTree(ConstraintDescriptor<A> descriptor) {
+ this( descriptor, null );
+ }
+
+ private ConstraintTree(ConstraintDescriptor<A> descriptor, ConstraintTree<?>
parent) {
+ this.parent = parent;
+ this.descriptor = descriptor;
+ final Set<ConstraintDescriptor<?>> composingConstraints =
descriptor.getComposingConstraints();
+ children = new ArrayList<ConstraintTree<?>>( composingConstraints.size()
);
+
+ for ( ConstraintDescriptor<?> composingDescriptor : composingConstraints ) {
+ ConstraintTree<?> treeNode = createConstraintTree( composingDescriptor );
+ children.add( treeNode );
+ }
+ }
+
+ private <U extends Annotation> ConstraintTree<U>
createConstraintTree(ConstraintDescriptor<U> composingDescriptor) {
+ return new ConstraintTree<U>( composingDescriptor, this );
+ }
+
+ public boolean isRoot() {
+ return parent == null;
+ }
+
+ public ConstraintTree getParent() {
+ return parent;
+ }
+
+ public List<ConstraintTree<?>> getChildren() {
+ return children;
+ }
+
+ public boolean hasChildren() {
+ return children.size() > 0;
+ }
+
+ public ConstraintDescriptor<A> getDescriptor() {
+ return descriptor;
+ }
+
+ /**
+ * Validates the specified value.
+ *
+ * @param value The value to validate
+ * @param type The type of the value determined from the type the annotation was placed
on.
+ * @param executionContext The current execution context.
+ * @param constraintViolations List of constraint violation into which to accumulate all
constraint violation as we traverse
+ * this <code>ConstraintTree </code>.
+ * @param <T> Type of the root bean for the current validation.
+ * @param <V> Type of the value to be validated.
+ */
+ public <T, V> void validateConstraints(V value, Type type,
ExecutionContext<T> executionContext, List<ConstraintViolation<T>>
constraintViolations) {
+ for ( ConstraintTree<?> tree : getChildren() ) {
+ tree.validateConstraints( value, type, executionContext, constraintViolations );
+ }
+
+ if ( log.isTraceEnabled() ) {
+ log.trace( "Validating value {} against constraint defined by {}", value,
descriptor );
+ }
+ ConstraintValidator<A, V> validator = getInitalizedValidator(
+ value, type, executionContext.getConstraintValidatorFactory()
+ );
+ ConstraintValidatorContextImpl constraintValidatorContext = new
ConstraintValidatorContextImpl(
+ executionContext.peekParentPath(), executionContext.peekProperty(), descriptor
+ );
+ if ( !validator.isValid( value, constraintValidatorContext ) ) {
+ constraintViolations.addAll( executionContext.createConstraintViolations( value,
constraintValidatorContext ) );
+ }
+ if ( reportAsSingleViolation() && constraintViolations.size() > 0 ) {
+ constraintViolations.clear();
+ final String message = ( String ) getParent().getDescriptor().getAttributes().get(
"message" );
+ final String property = executionContext.peekPropertyPath();
+ ConstraintValidatorContextImpl.ErrorMessage error = constraintValidatorContext.new
ErrorMessage( message, property );
+ constraintViolations.add( executionContext.createConstraintViolation( value, error,
descriptor ) );
+ }
+ }
+
+ private boolean reportAsSingleViolation() {
+ return getParent() != null
+ && getParent().getDescriptor().isReportAsSingleViolation();
+ }
+
+ /**
+ * @param value The value to be validated.
+ * @param type The type of the value to be validated (the type of the member/class the
constraint was placed on).
+ * @param constraintFactory constraint factory used to instantiate the constraint
validator.
+ *
+ * @return A initalized constraint validator matching the type of the value to be
validated.
+ */
+ private <V> ConstraintValidator<A, V> getInitalizedValidator(V value, Type
type, ConstraintValidatorFactory constraintFactory) {
+ Class<? extends ConstraintValidator<?, ?>> validatorClass =
findMatchingValidatorClass( value, type );
+
+ @SuppressWarnings("unchecked")
+ ConstraintValidator<A, V> constraintValidator = ( ConstraintValidator<A, V>
) constraintFactory.getInstance(
+ validatorClass
+ );
+ initializeConstraint( descriptor, constraintValidator );
+ return constraintValidator;
+ }
+
+ /**
+ * Runs the validator resolution algorithm.
+ *
+ * @param value The value to be validated.
+ * @param type The type of the value to be validated (the type of the member/class the
constraint was placed on).
+ *
+ * @return The class of a matching validator.
+ */
+ private Class<? extends ConstraintValidator<?, ?>>
findMatchingValidatorClass(Object value, Type type) {
+ Map<Type, Class<? extends ConstraintValidator<?, ?>>> validatorsTypes
=
+ ValidatorTypeHelper.getValidatorsTypes( descriptor.getConstraintValidatorClasses()
);
+
+ List<Type> suitableTypes = new ArrayList<Type>();
+ findSuitableValidatorTypes( type, validatorsTypes, suitableTypes );
+ // TODO - do we really have to take the actual value into consideration here as well?
Or is it enough to
+ // work with the type the constraint was placed on?
+ if ( value != null ) {
+ findSuitableValidatorTypes( determineValueClass( value ), validatorsTypes,
suitableTypes );
+ }
+
+ resolveAssignableTypes( suitableTypes );
+ verifyResolveWasUnique( type, suitableTypes );
+
+ return validatorsTypes.get( suitableTypes.get( 0 ) );
+ }
+
+ private Class determineValueClass(Object value) {
+ Class valueClass = value.getClass();
+ if ( valueClass.isArray() ) {
+ valueClass = Array.class;
+ }
+ return valueClass;
+ }
+
+ private void verifyResolveWasUnique(Type valueClass, List<Type> assignableClasses)
{
+ if ( assignableClasses.size() == 0 ) {
+ throw new UnexpectedTypeException( "No validator could be found for type: "
+ valueClass );
+ }
+ else if ( assignableClasses.size() > 1 ) {
+ StringBuilder builder = new StringBuilder();
+ builder.append( "There are multiple validators which could validate the type
" );
+ builder.append( valueClass );
+ builder.append( ". The validator classes are: " );
+ for ( Type clazz : assignableClasses ) {
+ builder.append( clazz );
+ builder.append( ", " );
+ }
+ builder.delete( builder.length() - 2, builder.length() );
+ throw new UnexpectedTypeException( builder.toString() );
+ }
+ }
+
+ private void findSuitableValidatorTypes(Type type, Map<Type, Class<? extends
ConstraintValidator<?, ?>>> validatorsTypes, List<Type> suitableTypes)
{
+ for ( Type validatorType : validatorsTypes.keySet() ) {
+ if ( TypeUtils.isAssignable( validatorType, type ) && !suitableTypes.contains(
validatorType ) ) {
+ suitableTypes.add( validatorType );
+ }
+ }
+ }
+
+ /**
+ * Tries to reduce all assignable classes down to a single class.
+ *
+ * @param assignableTypes The set of all classes which are assignable to the class of
the value to be validated and
+ * which are handled by at least one of the validators for the specified constraint.
+ */
+ private void resolveAssignableTypes(List<Type> assignableTypes) {
+ if ( assignableTypes.size() == 0 || assignableTypes.size() == 1 ) {
+ return;
+ }
+
+ List<Type> typesToRemove = new ArrayList<Type>();
+ do {
+ typesToRemove.clear();
+ Type type = assignableTypes.get( 0 );
+ for ( int i = 1; i < assignableTypes.size(); i++ ) {
+ if ( TypeUtils.isAssignable( type, assignableTypes.get( i ) ) ) {
+ typesToRemove.add( type );
+ }
+ else if ( TypeUtils.isAssignable( assignableTypes.get( i ), type ) ) {
+ typesToRemove.add( assignableTypes.get( i ) );
+ }
+ }
+ assignableTypes.removeAll( typesToRemove );
+ } while ( typesToRemove.size() > 0 );
+ }
+
+ private <V> void initializeConstraint
+ (ConstraintDescriptor<A>
+ descriptor, ConstraintValidator<A, V>
+ constraintValidator) {
+ try {
+ constraintValidator.initialize( descriptor.getAnnotation() );
+ }
+ catch ( RuntimeException e ) {
+ throw new ValidationException( "Unable to intialize " +
constraintValidator.getClass().getName(), e );
+ }
+ }
+}
Modified:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/DefaultValidationProviderResolver.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/DefaultValidationProviderResolver.java 2009-04-22
09:02:56 UTC (rev 16394)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/DefaultValidationProviderResolver.java 2009-04-22
10:59:38 UTC (rev 16395)
@@ -1,17 +1,17 @@
package org.hibernate.validation.engine;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.net.URL;
-import java.io.InputStream;
-import java.io.BufferedReader;
-import java.io.InputStreamReader;
-import java.io.IOException;
+import javax.validation.ValidationException;
import javax.validation.ValidationProviderResolver;
-import javax.validation.ValidationException;
import javax.validation.spi.ValidationProvider;
/**
Modified:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ExecutionContext.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ExecutionContext.java 2009-04-22
09:02:56 UTC (rev 16394)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ExecutionContext.java 2009-04-22
10:59:38 UTC (rev 16395)
@@ -27,9 +27,9 @@
import java.util.Stack;
import javax.validation.ConstraintDescriptor;
import javax.validation.ConstraintValidatorFactory;
+import javax.validation.ConstraintViolation;
import javax.validation.MessageInterpolator;
import javax.validation.TraversableResolver;
-import javax.validation.ConstraintViolation;
import org.hibernate.validation.util.IdentitySet;
Modified:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/MessageInterpolatorContext.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/MessageInterpolatorContext.java 2009-04-22
09:02:56 UTC (rev 16394)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/MessageInterpolatorContext.java 2009-04-22
10:59:38 UTC (rev 16395)
@@ -1,7 +1,7 @@
package org.hibernate.validation.engine;
+import javax.validation.ConstraintDescriptor;
import javax.validation.MessageInterpolator;
-import javax.validation.ConstraintDescriptor;
/**
* Takes mandatory elements in the constructor
Deleted:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/MetaConstraint.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/MetaConstraint.java 2009-04-22
09:02:56 UTC (rev 16394)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/MetaConstraint.java 2009-04-22
10:59:38 UTC (rev 16395)
@@ -1,177 +0,0 @@
-// $Id$// $Id$
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2008, Red Hat Middleware LLC, and individual contributors
-* by the @authors tag. See the copyright.txt in the distribution for a
-* full listing of individual contributors.
-*
-* 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.hibernate.validation.engine;
-
-import java.lang.annotation.Annotation;
-import java.lang.annotation.ElementType;
-import java.lang.reflect.Array;
-import java.lang.reflect.Field;
-import java.lang.reflect.Member;
-import java.lang.reflect.Method;
-import java.lang.reflect.Type;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
-import javax.validation.ConstraintDescriptor;
-import javax.validation.ConstraintViolation;
-
-import org.hibernate.validation.util.ReflectionHelper;
-
-/**
- * Instances of this class abstract the constraint type (class, method or field
constraint) and gives access to
- * meta data about the constraint. This allows a unified handling of constraints in the
validator imlpementation.
- *
- * @author Hardy Ferentschik
- */
-public class MetaConstraint<T, A extends Annotation> {
-
- /**
- * The constraint tree created from the constraint annotation.
- */
- private final ConstraintTree<A> constraintTree;
-
- /**
- * The member the constraint was defined on.
- */
- private final Member member;
-
- /**
- * The JavaBeans name for this constraint.
- */
- private final String propertyName;
-
- /**
- * Describes on which level (<code>TYPE</code>,
<code>METHOD</code>, <code>FIELD</code>) the constraint was
- * defined on.
- */
- private final ElementType elementType;
-
- /**
- * The class of the bean hosting this constraint.
- */
- private final Class<T> beanClass;
-
- public MetaConstraint(Class<T> beanClass, ConstraintDescriptor<A>
constraintDescriptor) {
- this.elementType = ElementType.TYPE;
- this.member = null;
- this.propertyName = "";
- this.beanClass = beanClass;
- constraintTree = new ConstraintTree<A>( constraintDescriptor );
- }
-
- public MetaConstraint(Member member, Class<T> beanClass,
ConstraintDescriptor<A> constraintDescriptor) {
- if ( member instanceof Method ) {
- this.elementType = ElementType.METHOD;
- }
- else if ( member instanceof Field ) {
- this.elementType = ElementType.FIELD;
- }
- else {
- throw new IllegalArgumentException( "Non allowed member type: " + member );
- }
- this.member = member;
- this.propertyName = ReflectionHelper.getPropertyName( member );
- this.beanClass = beanClass;
- constraintTree = new ConstraintTree<A>( constraintDescriptor );
- }
-
-
- /**
- * @return Returns the list of groups this constraint is part of. This might include the
default group even when
- * it is not explicitly specified, but part of the redefined default group list
of the hosting bean.
- */
- public Set<Class<?>> getGroupList() {
- return constraintTree.getDescriptor().getGroups();
- }
-
- public ConstraintDescriptor getDescriptor() {
- return constraintTree.getDescriptor();
- }
-
- public Class<T> getBeanClass() {
- return beanClass;
- }
-
- public String getPropertyName() {
- return propertyName;
- }
-
- public ElementType getElementType() {
- return elementType;
- }
-
- public ConstraintTree getConstraintTree() {
- return constraintTree;
- }
-
- public <T> boolean validateConstraint(ExecutionContext<T> executionContext)
{
- final Object leafBeanInstance = executionContext.peekCurrentBean();
- Object value = getValue( leafBeanInstance );
- List<ConstraintViolation<T>> constraintViolations = new
ArrayList<ConstraintViolation<T>>();
- constraintTree.validateConstraints( value, typeOfAnnoatedElement(), executionContext,
constraintViolations );
- if ( constraintViolations.size() > 0 ) {
- executionContext.addConstraintFailures( constraintViolations );
- return false;
- }
- return true;
- }
-
- public <T> boolean validateConstraint(Object value, ExecutionContext<T>
executionContext) {
- List<ConstraintViolation<T>> constraintViolations = new
ArrayList<ConstraintViolation<T>>();
- constraintTree.validateConstraints( value, typeOfAnnoatedElement(), executionContext,
constraintViolations );
- if ( constraintViolations.size() > 0 ) {
- executionContext.addConstraintFailures( constraintViolations );
- return false;
- }
- return true;
- }
-
- private Type typeOfAnnoatedElement() {
- Type t;
- switch ( elementType ) {
- case TYPE: {
- t = beanClass;
- break;
- }
- default: {
- t = ReflectionHelper.typeOf( member );
- if ( t instanceof Class && ((Class) t).isArray()) {
- t = Array.class;
- }
- }
- }
- return t;
- }
-
- /**
- * @param o the object from which to retrieve the value.
- *
- * @return Returns the value for this constraint from the specified object. Depending on
the type either the value itself
- * is returned of method or field access is used to access the value.
- */
- private Object getValue(Object o) {
- switch ( elementType ) {
- case TYPE: {
- return o;
- }
- default: {
- return ReflectionHelper.getValue( member, o );
- }
- }
- }
-}
Added:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/MetaConstraint.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/MetaConstraint.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/MetaConstraint.java 2009-04-22
10:59:38 UTC (rev 16395)
@@ -0,0 +1,177 @@
+// $Id$// $Id$
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, and individual contributors
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* 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.hibernate.validation.engine;
+
+import java.lang.annotation.Annotation;
+import java.lang.annotation.ElementType;
+import java.lang.reflect.Array;
+import java.lang.reflect.Field;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import javax.validation.ConstraintDescriptor;
+import javax.validation.ConstraintViolation;
+
+import org.hibernate.validation.util.ReflectionHelper;
+
+/**
+ * Instances of this class abstract the constraint type (class, method or field
constraint) and gives access to
+ * meta data about the constraint. This allows a unified handling of constraints in the
validator imlpementation.
+ *
+ * @author Hardy Ferentschik
+ */
+public class MetaConstraint<T, A extends Annotation> {
+
+ /**
+ * The constraint tree created from the constraint annotation.
+ */
+ private final ConstraintTree<A> constraintTree;
+
+ /**
+ * The member the constraint was defined on.
+ */
+ private final Member member;
+
+ /**
+ * The JavaBeans name for this constraint.
+ */
+ private final String propertyName;
+
+ /**
+ * Describes on which level (<code>TYPE</code>,
<code>METHOD</code>, <code>FIELD</code>) the constraint was
+ * defined on.
+ */
+ private final ElementType elementType;
+
+ /**
+ * The class of the bean hosting this constraint.
+ */
+ private final Class<T> beanClass;
+
+ public MetaConstraint(Class<T> beanClass, ConstraintDescriptor<A>
constraintDescriptor) {
+ this.elementType = ElementType.TYPE;
+ this.member = null;
+ this.propertyName = "";
+ this.beanClass = beanClass;
+ constraintTree = new ConstraintTree<A>( constraintDescriptor );
+ }
+
+ public MetaConstraint(Member member, Class<T> beanClass,
ConstraintDescriptor<A> constraintDescriptor) {
+ if ( member instanceof Method ) {
+ this.elementType = ElementType.METHOD;
+ }
+ else if ( member instanceof Field ) {
+ this.elementType = ElementType.FIELD;
+ }
+ else {
+ throw new IllegalArgumentException( "Non allowed member type: " + member );
+ }
+ this.member = member;
+ this.propertyName = ReflectionHelper.getPropertyName( member );
+ this.beanClass = beanClass;
+ constraintTree = new ConstraintTree<A>( constraintDescriptor );
+ }
+
+
+ /**
+ * @return Returns the list of groups this constraint is part of. This might include the
default group even when
+ * it is not explicitly specified, but part of the redefined default group list
of the hosting bean.
+ */
+ public Set<Class<?>> getGroupList() {
+ return constraintTree.getDescriptor().getGroups();
+ }
+
+ public ConstraintDescriptor getDescriptor() {
+ return constraintTree.getDescriptor();
+ }
+
+ public Class<T> getBeanClass() {
+ return beanClass;
+ }
+
+ public String getPropertyName() {
+ return propertyName;
+ }
+
+ public ElementType getElementType() {
+ return elementType;
+ }
+
+ public ConstraintTree getConstraintTree() {
+ return constraintTree;
+ }
+
+ public <T> boolean validateConstraint(ExecutionContext<T> executionContext)
{
+ final Object leafBeanInstance = executionContext.peekCurrentBean();
+ Object value = getValue( leafBeanInstance );
+ List<ConstraintViolation<T>> constraintViolations = new
ArrayList<ConstraintViolation<T>>();
+ constraintTree.validateConstraints( value, typeOfAnnoatedElement(), executionContext,
constraintViolations );
+ if ( constraintViolations.size() > 0 ) {
+ executionContext.addConstraintFailures( constraintViolations );
+ return false;
+ }
+ return true;
+ }
+
+ public <T> boolean validateConstraint(Object value, ExecutionContext<T>
executionContext) {
+ List<ConstraintViolation<T>> constraintViolations = new
ArrayList<ConstraintViolation<T>>();
+ constraintTree.validateConstraints( value, typeOfAnnoatedElement(), executionContext,
constraintViolations );
+ if ( constraintViolations.size() > 0 ) {
+ executionContext.addConstraintFailures( constraintViolations );
+ return false;
+ }
+ return true;
+ }
+
+ private Type typeOfAnnoatedElement() {
+ Type t;
+ switch ( elementType ) {
+ case TYPE: {
+ t = beanClass;
+ break;
+ }
+ default: {
+ t = ReflectionHelper.typeOf( member );
+ if ( t instanceof Class && ((Class) t).isArray()) {
+ t = Array.class;
+ }
+ }
+ }
+ return t;
+ }
+
+ /**
+ * @param o the object from which to retrieve the value.
+ *
+ * @return Returns the value for this constraint from the specified object. Depending on
the type either the value itself
+ * is returned of method or field access is used to access the value.
+ */
+ private Object getValue(Object o) {
+ switch ( elementType ) {
+ case TYPE: {
+ return o;
+ }
+ default: {
+ return ReflectionHelper.getValue( member, o );
+ }
+ }
+ }
+}
Modified:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorFactoryImpl.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorFactoryImpl.java 2009-04-22
09:02:56 UTC (rev 16394)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorFactoryImpl.java 2009-04-22
10:59:38 UTC (rev 16395)
@@ -17,59 +17,21 @@
*/
package org.hibernate.validation.engine;
-import java.io.IOException;
import java.io.InputStream;
-import java.io.Serializable;
import java.lang.annotation.Annotation;
-import java.lang.reflect.Array;
-import java.lang.reflect.Field;
import java.lang.reflect.Member;
-import java.lang.reflect.Method;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
import java.util.Set;
-import javax.validation.Constraint;
-import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorFactory;
import javax.validation.MessageInterpolator;
import javax.validation.TraversableResolver;
-import javax.validation.ValidationException;
import javax.validation.Validator;
import javax.validation.ValidatorContext;
import javax.validation.ValidatorFactory;
import javax.validation.spi.ConfigurationState;
-import javax.xml.bind.JAXBContext;
-import javax.xml.bind.JAXBElement;
-import javax.xml.bind.JAXBException;
-import javax.xml.bind.Unmarshaller;
-import javax.xml.transform.stream.StreamSource;
-import javax.xml.validation.Schema;
-import javax.xml.validation.SchemaFactory;
-import org.slf4j.Logger;
-import org.xml.sax.SAXException;
+import org.hibernate.validation.engine.xml.AnnotationIgnores;
+import org.hibernate.validation.engine.xml.XmlMappingParser;
-import org.hibernate.validation.util.LoggerFactory;
-import org.hibernate.validation.util.ReflectionHelper;
-import org.hibernate.validation.util.annotationfactory.AnnotationDescriptor;
-import org.hibernate.validation.util.annotationfactory.AnnotationFactory;
-import org.hibernate.validation.xml.AnnotationType;
-import org.hibernate.validation.xml.BeanType;
-import org.hibernate.validation.xml.ClassType;
-import org.hibernate.validation.xml.ConstraintDefinitionType;
-import org.hibernate.validation.xml.ConstraintMappingsType;
-import org.hibernate.validation.xml.ConstraintType;
-import org.hibernate.validation.xml.ElementType;
-import org.hibernate.validation.xml.FieldType;
-import org.hibernate.validation.xml.GetterType;
-import org.hibernate.validation.xml.GroupSequenceType;
-import org.hibernate.validation.xml.GroupsType;
-import org.hibernate.validation.xml.ValidatedByType;
-
/**
* Factory returning initialized <code>Validator</code> instances.
*
@@ -78,24 +40,12 @@
*/
public class ValidatorFactoryImpl implements ValidatorFactory {
- private static final Logger log = LoggerFactory.make();
- private static final String VALIDATION_MAPPING_XSD =
"META-INF/validation-mapping-1.0.xsd";
- private static final String MESSAGE_PARAM = "message";
- private static final String GROUPS_PARAM = "groups";
- private static final String PACKAGE_SEPERATOR = ".";
-
private final MessageInterpolator messageInterpolator;
private final TraversableResolver traversableResolver;
private final ConstraintValidatorFactory constraintValidatorFactory;
private final ConstraintHelper constraintHelper;
private final BeanMetaDataCache beanMetaDataCache;
- private final Set<Class<?>> processedClasses = new
HashSet<Class<?>>();
- private final AnnotationIgnores annotationIgnores;
- private final Map<Class<?>, List<MetaConstraint<?, ? extends
Annotation>>> constraintMap;
- private final Map<Class<?>, List<Member>> cascadedMembers;
- private final Map<Class<?>, List<Class<?>>> defaultSequences;
-
public ValidatorFactoryImpl(ConfigurationState configurationState) {
this.messageInterpolator = configurationState.getMessageInterpolator();
this.constraintValidatorFactory = configurationState.getConstraintValidatorFactory();
@@ -103,13 +53,7 @@
this.constraintHelper = new ConstraintHelper();
this.beanMetaDataCache = new BeanMetaDataCache();
- this.annotationIgnores = new AnnotationIgnores();
- this.constraintMap = new HashMap<Class<?>, List<MetaConstraint<?, ?
extends Annotation>>>();
- this.cascadedMembers = new HashMap<Class<?>, List<Member>>();
- this.defaultSequences = new HashMap<Class<?>,
List<Class<?>>>();
-
- parseMappingFiles( configurationState.getMappingStreams() );
- initBeanMetaData();
+ initBeanMetaData( configurationState.getMappingStreams() );
}
/**
@@ -139,504 +83,27 @@
);
}
- private Schema getMappingSchema() {
- URL schemaUrl = this.getClass().getClassLoader().getResource( VALIDATION_MAPPING_XSD
);
- SchemaFactory sf = SchemaFactory.newInstance(
javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI );
- Schema schema = null;
- try {
- schema = sf.newSchema( schemaUrl );
- }
- catch ( SAXException e ) {
- log.warn( "Unable to create schema for {}: {}", VALIDATION_MAPPING_XSD,
e.getMessage() );
- }
- return schema;
- }
+ private <T> void initBeanMetaData(Set<InputStream> mappingStreams) {
- private void parseMappingFiles(Set<InputStream> mappingStreams) {
- for ( InputStream in : mappingStreams ) {
- try {
- ConstraintMappingsType mapping = getValidationConfig( in );
- parseConstraintDefinitions( mapping.getConstraintDefinition() );
- String defaultPackage = mapping.getDefaultPackage();
- for ( BeanType bean : mapping.getBean() ) {
- Class<?> beanClass = getClass( bean.getClazz(), defaultPackage );
- checkClassHasNotBeenProcessed( processedClasses, beanClass );
- annotationIgnores.setDefaultIgnoreAnnotation( beanClass, bean.isIgnoreAnnotations()
);
- parseClassLevelOverrides( bean.getClassType(), beanClass, defaultPackage );
- parseFieldLevelOverrides( bean.getField(), beanClass, defaultPackage );
- parsePropertyLevelOverrides( bean.getGetter(), beanClass, defaultPackage );
- processedClasses.add( beanClass );
- }
- }
- finally {
- try {
- in.close();
- }
- catch ( IOException e ) {
- log.warn( "Error closing input stream: {}", e.getMessage() );
- }
- }
- }
- }
+ XmlMappingParser mappingParser = new XmlMappingParser( constraintHelper );
+ mappingParser.parse( mappingStreams );
- @SuppressWarnings("unchecked")
- private void parseConstraintDefinitions(List<ConstraintDefinitionType>
constraintDefinitionList) {
- for ( ConstraintDefinitionType constraintDefinition : constraintDefinitionList ) {
- String annotationClassName = constraintDefinition.getAnnotation();
- Class<? extends Annotation> annotationClass;
- try {
- annotationClass = ( Class<? extends Annotation> )
ReflectionHelper.classForName(
- annotationClassName, this.getClass()
- );
- }
- catch ( ClassNotFoundException e ) {
- throw new ValidationException( "Unable to load class " +
annotationClassName );
- }
-
- if ( !annotationClass.isAnnotation() ) {
- throw new ValidationException( annotationClassName + " is not an
annotation" );
- }
-
- ValidatedByType validatedByType = constraintDefinition.getValidatedBy();
- List<Class<? extends ConstraintValidator<? extends Annotation, ?>>>
constraintValidatorClasses = new ArrayList<Class<? extends ConstraintValidator<?
extends Annotation, ?>>>();
- if ( validatedByType.isIncludeExistingValidators() != null &&
validatedByType.isIncludeExistingValidators() ) {
- constraintValidatorClasses.addAll( findConstraintValidatorClasses( annotationClass )
);
- }
- for ( String validatorClassName : validatedByType.getValue() ) {
- Class<? extends ConstraintValidator<?, ?>> validatorClass;
- try {
- validatorClass = ( Class<? extends ConstraintValidator<?, ?>> )
ReflectionHelper.classForName(
- validatorClassName,
- this.getClass()
- );
- }
- catch ( ClassNotFoundException e ) {
- throw new ValidationException( "Unable to load class " +
validatorClassName );
- }
-
- if ( !ConstraintValidator.class.isAssignableFrom(validatorClass) ) {
- throw new ValidationException( validatorClass + " is not a constraint validator
class" );
- }
-
- constraintValidatorClasses.add( validatorClass );
- }
- constraintHelper.addConstraintValidatorDefinition(
- annotationClass, constraintValidatorClasses
- );
- }
- }
-
- private void checkClassHasNotBeenProcessed(Set<Class<?>> processedClasses,
Class<?> beanClass) {
- if ( processedClasses.contains( beanClass ) ) {
- throw new ValidationException( beanClass.getName() + " has already be configured
in xml." );
- }
- }
-
- private void parseFieldLevelOverrides(List<FieldType> fields, Class<?>
beanClass, String defaultPackage) {
- for ( FieldType fieldType : fields ) {
- String fieldName = fieldType.getName();
- if ( !ReflectionHelper.containsField( beanClass, fieldName ) ) {
- throw new ValidationException( beanClass.getName() + " does not contain the
fieldType " + fieldName );
- }
- Field field = ReflectionHelper.getField( beanClass, fieldName );
-
- // ignore annotations
- boolean ignoreFieldAnnotation = fieldType.isIgnoreAnnotations() == null ? false :
fieldType.isIgnoreAnnotations();
- if ( ignoreFieldAnnotation ) {
- annotationIgnores.setIgnoreAnnotationsOnMember( field );
- }
-
- // valid
- if ( fieldType.getValid() != null ) {
- addCascadedMember( beanClass, field );
- }
-
- // constraints
- for ( ConstraintType constraint : fieldType.getConstraint() ) {
- MetaConstraint<?, ?> metaConstraint = createMetaConstraint(
- constraint, beanClass, field, defaultPackage
- );
- addMetaConstraint( beanClass, metaConstraint );
- }
- }
- }
-
- private void parsePropertyLevelOverrides(List<GetterType> getters, Class<?>
beanClass, String defaultPackage) {
- for ( GetterType getterType : getters ) {
- String getterName = getterType.getName();
- if ( !ReflectionHelper.containsMethod( beanClass, getterName ) ) {
- throw new ValidationException( beanClass.getName() + " does not contain the
property " + getterName );
- }
- Method method = ReflectionHelper.getMethod( beanClass, getterName );
-
- // ignore annotations
- boolean ignoreGetterAnnotation = getterType.isIgnoreAnnotations() == null ? false :
getterType.isIgnoreAnnotations();
- if ( ignoreGetterAnnotation ) {
- annotationIgnores.setIgnoreAnnotationsOnMember( method );
- }
-
- // valid
- if ( getterType.getValid() != null ) {
- addCascadedMember( beanClass, method );
- }
-
- // constraints
- for ( ConstraintType constraint : getterType.getConstraint() ) {
- MetaConstraint<?, ?> metaConstraint = createMetaConstraint(
- constraint, beanClass, method, defaultPackage
- );
- addMetaConstraint( beanClass, metaConstraint );
- }
- }
- }
-
- private void parseClassLevelOverrides(ClassType classType, Class<?> beanClass,
String defaultPackage) {
- if ( classType == null ) {
- return;
- }
-
- // ignore annotation
- boolean ignoreClassAnnotation = classType.isIgnoreAnnotations() == null ? false :
classType.isIgnoreAnnotations();
- if ( ignoreClassAnnotation ) {
- annotationIgnores.setIgnoreAnnotationsOnClass( beanClass );
- }
-
- // group sequence
- List<Class<?>> groupSequence = createGroupSequence(
classType.getGroupSequence(), defaultPackage );
- if ( !groupSequence.isEmpty() ) {
- defaultSequences.put( beanClass, groupSequence );
- }
-
- // constraints
- for ( ConstraintType constraint : classType.getConstraint() ) {
- MetaConstraint<?, ?> metaConstraint = createMetaConstraint( constraint,
beanClass, null, defaultPackage );
- addMetaConstraint( beanClass, metaConstraint );
- }
- }
-
- private List<Class<?>> createGroupSequence(GroupSequenceType
groupSequenceType, String defaultPackage) {
- List<Class<?>> groupSequence = new ArrayList<Class<?>>();
- for ( String groupName : groupSequenceType.getValue() ) {
- Class<?> group = getClass( groupName, defaultPackage );
- groupSequence.add( group );
- }
- return groupSequence;
- }
-
- private void addMetaConstraint(Class<?> beanClass, MetaConstraint<?, ?>
metaConstraint) {
- if ( constraintMap.containsKey( beanClass ) ) {
- constraintMap.get( beanClass ).add( metaConstraint );
- }
- else {
- List<MetaConstraint<?, ? extends Annotation>> constraintList = new
ArrayList<MetaConstraint<?, ? extends Annotation>>();
- constraintList.add( metaConstraint );
- constraintMap.put( beanClass, constraintList );
- }
- }
-
- private void addCascadedMember(Class<?> beanClass, Member member) {
- if ( cascadedMembers.containsKey( beanClass ) ) {
- cascadedMembers.get( beanClass ).add( member );
- }
- else {
- List<Member> tmpList = new ArrayList<Member>();
- tmpList.add( member );
- cascadedMembers.put( beanClass, tmpList );
- }
- }
-
- private <A extends Annotation, T> MetaConstraint<?, ?>
createMetaConstraint(ConstraintType constraint, Class<T> beanClass, Member member,
String defaultPackage) {
- @SuppressWarnings("unchecked")
- Class<A> annotationClass = ( Class<A> ) getClass(
constraint.getAnnotation(), defaultPackage );
- AnnotationDescriptor<A> annotationDescriptor = new AnnotationDescriptor<A>(
annotationClass );
-
- if ( constraint.getMessage() != null ) {
- annotationDescriptor.setValue( MESSAGE_PARAM, constraint.getMessage() );
- }
- annotationDescriptor.setValue( GROUPS_PARAM, getGroups( constraint.getGroups(),
defaultPackage ) );
-
- for ( ElementType elementType : constraint.getElement() ) {
- String name = elementType.getName();
- checkNameIsValid( name );
- Class<?> returnType = getAnnotationParamterType( annotationClass, name );
- Object elementValue = getElementValue( elementType, returnType );
- annotationDescriptor.setValue( name, elementValue );
- }
-
- A annotation = AnnotationFactory.create( annotationDescriptor );
- ConstraintDescriptorImpl<A> constraintDescriptor = new
ConstraintDescriptorImpl<A>(
- annotation, new Class[] { }, constraintHelper
- );
-
- MetaConstraint<T, A> metaConstraint;
- if ( member == null ) {
- metaConstraint = new MetaConstraint<T, A>( beanClass, constraintDescriptor );
- }
- else {
- metaConstraint = new MetaConstraint<T, A>( member, beanClass,
constraintDescriptor );
- }
- return metaConstraint;
- }
-
- private void checkNameIsValid(String name) {
- if ( MESSAGE_PARAM.equals( name ) || GROUPS_PARAM.equals( name ) ) {
- throw new ValidationException( MESSAGE_PARAM + " and " + GROUPS_PARAM +
" are reserved paramter names." );
- }
- }
-
- private <A extends Annotation> Class<?>
getAnnotationParamterType(Class<A> annotationClass, String name) {
- Method m;
- try {
- m = annotationClass.getMethod( name );
- }
- catch ( NoSuchMethodException e ) {
- throw new ValidationException( "Annotation of type " +
annotationClass.getName() + " does not contain a paramter " + name +
"." );
- }
- return m.getReturnType();
- }
-
- private Object getElementValue(ElementType elementType, Class<?> returnType) {
- removeEmptyContentElements( elementType );
-
- boolean isArray = returnType.isArray();
- if ( !isArray ) {
- if ( elementType.getContent().size() != 1 ) {
- throw new ValidationException( "Attempt to specify an array where single value
is expected." );
- }
- return getSingleValue( elementType.getContent().get( 0 ), returnType );
- }
- else {
- List<Object> values = new ArrayList<Object>();
- for ( Serializable s : elementType.getContent() ) {
- values.add( getSingleValue( s, returnType.getComponentType() ) );
- }
- return values.toArray( ( Object[] ) Array.newInstance( returnType.getComponentType(),
values.size() ) );
- }
- }
-
- private void removeEmptyContentElements(ElementType elementType) {
- List<Serializable> contentToDelete = new ArrayList<Serializable>();
- for ( Serializable content : elementType.getContent() ) {
- if ( content instanceof String && ( ( String ) content ).matches( "[\\n
].*" ) ) {
- contentToDelete.add( content );
- }
- }
- elementType.getContent().removeAll( contentToDelete );
- }
-
- private Object getSingleValue(Serializable serializable, Class<?> returnType) {
-
- Object returnValue;
- if ( serializable instanceof String ) {
- String value = ( String ) serializable;
- returnValue = convertStringToReturnType( returnType, value );
- }
- else if ( serializable instanceof JAXBElement && ( ( JAXBElement ) serializable
).getDeclaredType()
- .equals( String.class ) ) {
- JAXBElement<?> elem = ( JAXBElement<?> ) serializable;
- String value = ( String ) elem.getValue();
- returnValue = convertStringToReturnType( returnType, value );
- }
- else if ( serializable instanceof JAXBElement && ( ( JAXBElement ) serializable
).getDeclaredType()
- .equals( AnnotationType.class ) ) {
- JAXBElement<?> elem = ( JAXBElement<?> ) serializable;
- AnnotationType annotationType = ( AnnotationType ) elem.getValue();
- try {
- @SuppressWarnings("unchecked")
- Class<Annotation> annotationClass = ( Class<Annotation> ) returnType;
- returnValue = createAnnotation( annotationType, annotationClass );
- }
- catch ( ClassCastException e ) {
- throw new ValidationException( "Unexpected paramter value" );
- }
- }
- else {
- throw new ValidationException( "Unexpected paramter value" );
- }
- return returnValue;
-
- }
-
- private <A extends Annotation> Annotation createAnnotation(AnnotationType
annotationType, Class<A> returnType) {
- AnnotationDescriptor<A> annotationDescriptor = new AnnotationDescriptor<A>(
returnType );
- for ( ElementType elementType : annotationType.getElement() ) {
- String name = elementType.getName();
- Class<?> paramterType = getAnnotationParamterType( returnType, name );
- Object elementValue = getElementValue( elementType, paramterType );
- annotationDescriptor.setValue( name, elementValue );
- }
- return AnnotationFactory.create( annotationDescriptor );
- }
-
- private Object convertStringToReturnType(Class<?> returnType, String value) {
- Object returnValue;
- if ( returnType.getName().equals( byte.class.getName() ) ) {
- try {
- returnValue = Byte.parseByte( value );
- }
- catch ( NumberFormatException e ) {
- throw new ValidationException( "Invalid byte format", e );
- }
- }
- else if ( returnType.getName().equals( short.class.getName() ) ) {
- try {
- returnValue = Short.parseShort( value );
- }
- catch ( NumberFormatException e ) {
- throw new ValidationException( "Invalid short format", e );
- }
- }
- else if ( returnType.getName().equals( int.class.getName() ) ) {
- try {
- returnValue = Integer.parseInt( value );
- }
- catch ( NumberFormatException e ) {
- throw new ValidationException( "Invalid int format", e );
- }
- }
- else if ( returnType.getName().equals( long.class.getName() ) ) {
- try {
- returnValue = Long.parseLong( value );
- }
- catch ( NumberFormatException e ) {
- throw new ValidationException( "Invalid long format", e );
- }
- }
- else if ( returnType.getName().equals( float.class.getName() ) ) {
- try {
- returnValue = Float.parseFloat( value );
- }
- catch ( NumberFormatException e ) {
- throw new ValidationException( "Invalid float format", e );
- }
- }
- else if ( returnType.getName().equals( double.class.getName() ) ) {
- try {
- returnValue = Double.parseDouble( value );
- }
- catch ( NumberFormatException e ) {
- throw new ValidationException( "Invalid double format", e );
- }
- }
- else if ( returnType.getName().equals( boolean.class.getName() ) ) {
- returnValue = Boolean.parseBoolean( value );
- }
- else if ( returnType.getName().equals( char.class.getName() ) ) {
- if ( value.length() != 1 ) {
- throw new ValidationException( "Invalid char value: " + value );
- }
- returnValue = value.charAt( 0 );
- }
- else if ( returnType.getName().equals( String.class.getName() ) ) {
- returnValue = value;
- }
- else if ( returnType.getName().equals( Class.class.getName() ) ) {
- try {
- returnValue = ReflectionHelper.classForName( value, this.getClass() );
- }
- catch ( ClassNotFoundException e ) {
- throw new ValidationException( "Unable to instantiate class: " + value );
- }
- }
- else {
- try {
- @SuppressWarnings("unchecked")
- Class<Enum> enumClass = ( Class<Enum> ) returnType;
- returnValue = Enum.valueOf( enumClass, value );
- }
- catch ( ClassCastException e ) {
- throw new ValidationException( "Invalid return type: " + returnType +
". Should be a enumeration type." );
- }
- }
- return returnValue;
- }
-
- private Class<?>[] getGroups(GroupsType groupsType, String defaultPackage) {
- if ( groupsType == null ) {
- return new Class[] { };
- }
-
- List<Class<?>> groupList = new ArrayList<Class<?>>();
- for ( String groupClass : groupsType.getValue() ) {
- groupList.add( getClass( groupClass, defaultPackage ) );
- }
- return groupList.toArray( new Class[groupList.size()] );
- }
-
- private Class<?> getClass(String clazz, String defaultPackage) {
- String fullyQualifiedClass;
- if ( isQualifiedClass( clazz ) ) {
- fullyQualifiedClass = clazz;
- }
- else {
- fullyQualifiedClass = defaultPackage + PACKAGE_SEPERATOR + clazz;
- }
- try {
- return ReflectionHelper.classForName( fullyQualifiedClass, this.getClass() );
- }
- catch ( Exception e ) {
- throw new ValidationException( "Unable to instantiate class " +
fullyQualifiedClass );
- }
- }
-
- private boolean isQualifiedClass(String clazz) {
- return clazz.contains( PACKAGE_SEPERATOR );
- }
-
- private ConstraintMappingsType getValidationConfig(InputStream in) {
- ConstraintMappingsType constraintMappings;
- Schema schema = getMappingSchema();
- try {
- JAXBContext jc = JAXBContext.newInstance( ConstraintMappingsType.class );
- Unmarshaller unmarshaller = jc.createUnmarshaller();
- unmarshaller.setSchema( schema );
- StreamSource stream = new StreamSource( in );
- JAXBElement<ConstraintMappingsType> root = unmarshaller.unmarshal( stream,
ConstraintMappingsType.class );
- constraintMappings = root.getValue();
- }
- catch ( JAXBException e ) {
- String msg = "Error parsing mapping file.";
- log.error( msg );
- throw new ValidationException( msg, e );
- }
- return constraintMappings;
- }
-
- private <T> void initBeanMetaData() {
- for ( Class<?> beanClass : processedClasses ) {
+ AnnotationIgnores annotationIgnores = mappingParser.getAnnotationIgnores();
+ for ( Class<?> beanClass : mappingParser.getProcessedClasses() ) {
BeanMetaDataImpl<?> metaData = new BeanMetaDataImpl<T>(
( Class<T> ) beanClass, constraintHelper, annotationIgnores
);
- for ( MetaConstraint<?, ? extends Annotation> constraint : constraintMap.get(
beanClass ) ) {
+ for ( MetaConstraint<?, ? extends Annotation> constraint :
mappingParser.getConstraintMap()
+ .get( beanClass ) ) {
metaData.addMetaConstraint( constraint );
}
- for ( Member m : cascadedMembers.get( beanClass ) ) {
+ for ( Member m : mappingParser.getCascadedMembers().get( beanClass ) ) {
metaData.addCascadedMember( m );
}
- if ( defaultSequences.containsKey( beanClass ) ) {
- metaData.setDefaultGroupSequence( defaultSequences.get( beanClass ) );
+ if ( mappingParser.getDefaultSequences().containsKey( beanClass ) ) {
+ metaData.setDefaultGroupSequence( mappingParser.getDefaultSequences().get( beanClass
) );
}
beanMetaDataCache.addBeanMetaData( ( Class<T> ) beanClass, (
BeanMetaDataImpl<T> ) metaData );
}
}
-
- private List<Class<? extends ConstraintValidator<? extends Annotation,
?>>> findConstraintValidatorClasses(Class<? extends Annotation>
annotationType) {
- List<Class<? extends ConstraintValidator<? extends Annotation, ?>>>
constraintValidatorDefinitonClasses = new ArrayList<Class<? extends
ConstraintValidator<? extends Annotation, ?>>>();
- if ( constraintHelper.isBuiltinConstraint( annotationType ) ) {
- constraintValidatorDefinitonClasses.addAll( constraintHelper.getBuiltInConstraints(
annotationType ) );
- }
- else {
- Class<? extends ConstraintValidator<?, ?>>[] validatedBy = annotationType
- .getAnnotation( Constraint.class )
- .validatedBy();
- for ( Class<? extends ConstraintValidator<?, ?>> validator : validatedBy )
{
- //FIXME does this create a CCE at runtime?
- //FIXME if yes wrap into VE, if no we need to test the type here
- //Once resolved,we can @SuppressWarning("unchecked") on the cast
- Class<? extends ConstraintValidator<? extends Annotation, ?>>
safeValidator = validator;
- constraintValidatorDefinitonClasses.add( safeValidator );
- }
- }
- return constraintValidatorDefinitonClasses;
- }
}
Modified:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorImpl.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorImpl.java 2009-04-22
09:02:56 UTC (rev 16394)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorImpl.java 2009-04-22
10:59:38 UTC (rev 16395)
@@ -17,9 +17,9 @@
*/
package org.hibernate.validation.engine;
+import java.lang.annotation.Annotation;
import java.lang.reflect.Member;
import java.lang.reflect.Type;
-import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
Copied:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/xml/AnnotationIgnores.java
(from rev 16370,
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/AnnotationIgnores.java)
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/xml/AnnotationIgnores.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/xml/AnnotationIgnores.java 2009-04-22
10:59:38 UTC (rev 16395)
@@ -0,0 +1,119 @@
+// $Id$
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, and individual contributors
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* 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.hibernate.validation.engine.xml;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Member;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.slf4j.Logger;
+
+import org.hibernate.validation.util.LoggerFactory;
+
+/**
+ * This class instantiated during the parsing of the XML configuration data and keeps
+ * track of the annotations which should be ignored.
+ *
+ * @author Hardy Ferentschik
+ */
+public class AnnotationIgnores {
+
+ private static final Logger log = LoggerFactory.make();
+
+ /**
+ * Keeps track whether the 'ignore-annotations' flag is set on bean level in the
xml configuration. If 'ignore-annotations'
+ * is not specified <code>false</code> is the default.
+ */
+ private final Map<Class<?>, Boolean> ignoreAnnotationDefaults = new
HashMap<Class<?>, Boolean>();
+
+ /**
+ * Keeps track of explicitly excluded members (fields and properties) for a given class.
If a member appears in
+ * the list mapped to a given class 'ignore-annotations' was explicitly set to
<code>true</code> in the configuration
+ * for this class.
+ */
+ private final Map<Class<?>, List<Member>> ignoreAnnotationOnMember =
new HashMap<Class<?>, List<Member>>();
+
+ private final List<Class<?>> ignoreAnnotationOnClass = new
ArrayList<Class<?>>();
+
+ public void setDefaultIgnoreAnnotation(Class<?> clazz, Boolean b) {
+ if ( b == null ) {
+ ignoreAnnotationDefaults.put( clazz, Boolean.FALSE );
+ }
+ else {
+ ignoreAnnotationDefaults.put( clazz, b );
+ }
+ }
+
+ public boolean getDefaultIgnoreAnnotation(Class<?> clazz) {
+ return ignoreAnnotationDefaults.containsKey( clazz ) &&
ignoreAnnotationDefaults.get( clazz );
+ }
+
+ public void setIgnoreAnnotationsOnMember(Member member) {
+ Class<?> beanClass = member.getDeclaringClass();
+ if ( ignoreAnnotationOnMember.get( beanClass ) == null ) {
+ List<Member> tmpList = new ArrayList<Member>();
+ tmpList.add( member );
+ ignoreAnnotationOnMember.put( beanClass, tmpList );
+ }
+ else {
+ ignoreAnnotationOnMember.get( beanClass ).add( member );
+ }
+ }
+
+ public boolean isIgnoreAnnotations(Member member) {
+ boolean ignoreAnnotation;
+ Class<?> clazz = member.getDeclaringClass();
+ List<Member> ignoreAnnotationForMembers = ignoreAnnotationOnMember.get( clazz );
+ if ( ignoreAnnotationForMembers == null || !ignoreAnnotationForMembers.contains( member
) ) {
+ ignoreAnnotation = getDefaultIgnoreAnnotation( clazz );
+ }
+ else {
+ ignoreAnnotation = ignoreAnnotationForMembers.contains( member );
+ }
+ if ( ignoreAnnotation ) {
+ logMessage( member, clazz );
+ }
+ return ignoreAnnotation;
+ }
+
+ private void logMessage(Member member, Class<?> clazz) {
+ String type;
+ if ( member instanceof Field ) {
+ type = "Field";
+ }
+ else {
+ type = "Property";
+ }
+ log.debug( type + " level annotations are getting ignored for " +
clazz.getName() + "." + member.getName() );
+ }
+
+ public void setIgnoreAnnotationsOnClass(Class<?> clazz) {
+ ignoreAnnotationOnClass.add( clazz );
+ }
+
+ public boolean isIgnoreAnnotations(Class<?> clazz) {
+ boolean ignoreAnnotation = ignoreAnnotationOnClass.contains( clazz ) ||
getDefaultIgnoreAnnotation( clazz );
+ if ( log.isDebugEnabled() && ignoreAnnotation ) {
+ log.debug( "Class level annotation are getting ignored for " +
clazz.getName() );
+ }
+ return ignoreAnnotation;
+ }
+}
Property changes on:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/xml/AnnotationIgnores.java
___________________________________________________________________
Name: svn:keywords
+ Id
Added:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/xml/ValidationBootstrapParameters.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/xml/ValidationBootstrapParameters.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/xml/ValidationBootstrapParameters.java 2009-04-22
10:59:38 UTC (rev 16395)
@@ -0,0 +1,42 @@
+// $Id:$
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, and individual contributors
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* 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.hibernate.validation.engine.xml;
+
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import javax.validation.Configuration;
+import javax.validation.ConstraintValidatorFactory;
+import javax.validation.MessageInterpolator;
+import javax.validation.TraversableResolver;
+import javax.validation.spi.ValidationProvider;
+
+/**
+ * @author Hardy Ferentschik
+ */
+public class ValidationBootstrapParameters {
+ public ConstraintValidatorFactory constraintValidatorFactory;
+ public MessageInterpolator messageInterpolator;
+ public TraversableResolver traversableResolver;
+ public ValidationProvider provider;
+ public Class<? extends Configuration<?>> providerClass = null;
+ public final Map<String, String> configProperties = new HashMap<String,
String>();
+ public final Set<InputStream> mappings = new HashSet<InputStream>();
+}
Property changes on:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/xml/ValidationBootstrapParameters.java
___________________________________________________________________
Name: svn:keywords
+ Id
Added:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/xml/ValidationXmlParser.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/xml/ValidationXmlParser.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/xml/ValidationXmlParser.java 2009-04-22
10:59:38 UTC (rev 16395)
@@ -0,0 +1,252 @@
+// $Id:$
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, and individual contributors
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* 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.hibernate.validation.engine.xml;
+
+import java.io.InputStream;
+import java.net.URL;
+import javax.validation.Configuration;
+import javax.validation.ConstraintValidatorFactory;
+import javax.validation.MessageInterpolator;
+import javax.validation.TraversableResolver;
+import javax.validation.ValidationException;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+
+import org.slf4j.Logger;
+import org.xml.sax.SAXException;
+
+import org.hibernate.validation.util.LoggerFactory;
+import org.hibernate.validation.util.ReflectionHelper;
+import org.hibernate.validation.xml.PropertyType;
+import org.hibernate.validation.xml.ValidationConfigType;
+
+/**
+ * Parser for <i>validation.xml</i> using JAXB.
+ *
+ * @author Hardy Ferentschik
+ */
+public class ValidationXmlParser {
+
+ private static final Logger log = LoggerFactory.make();
+ private static final String VALIDATION_XML_FILE = "META-INF/validation.xml";
+ private static final String VALIDATION_CONFIGURATION_XSD =
"META-INF/validation-configuration-1.0.xsd";
+
+
+ /**
+ * Tries to check whether a validation.xml file exists and parses it using JAXB.
+ *
+ * @return The parameters parsed out of <i>validation.xml</i> wrapped in an
instance of <code>ConfigurationImpl.ValidationBootstrapParameters</code>.
+ */
+ public ValidationBootstrapParameters parseValidationXml() {
+ ValidationConfigType config = getValidationConfig();
+ ValidationBootstrapParameters xmlParameters = new ValidationBootstrapParameters();
+ if ( config != null ) {
+ // collect the paramters from the xml file
+ setProviderClassFromXml( config, xmlParameters );
+ setMessageInterpolatorFromXml( config, xmlParameters );
+ setTraversableResolverFromXml( config, xmlParameters );
+ setConstraintFactoryFromXml( config, xmlParameters );
+ setMappingStreamsFromXml( config, xmlParameters );
+ setPropertiesFromXml( config, xmlParameters );
+ }
+ return xmlParameters;
+ }
+
+ private void setConstraintFactoryFromXml(ValidationConfigType config,
ValidationBootstrapParameters xmlParameters) {
+ String constraintFactoryClass = config.getConstraintValidatorFactory();
+ if ( constraintFactoryClass != null ) {
+ try {
+ @SuppressWarnings("unchecked")
+ Class<ConstraintValidatorFactory> clazz = (
Class<ConstraintValidatorFactory> ) ReflectionHelper.classForName(
+ constraintFactoryClass, this.getClass()
+ );
+ xmlParameters.constraintValidatorFactory = clazz.newInstance();
+ log.info( "Using {} as constraint factory.", constraintFactoryClass );
+ }
+ catch ( ClassNotFoundException e ) {
+ throw new ValidationException(
+ "Unable to instantiate constraint factory class " +
constraintFactoryClass + ".", e
+ );
+ }
+ catch ( InstantiationException e ) {
+ throw new ValidationException(
+ "Unable to instantiate constraint factory class " +
constraintFactoryClass + ".", e
+ );
+ }
+ catch ( IllegalAccessException e ) {
+ throw new ValidationException(
+ "Unable to instantiate constraint factory class " +
constraintFactoryClass + ".", e
+ );
+ }
+ }
+ }
+
+ private void setPropertiesFromXml(ValidationConfigType config,
ValidationBootstrapParameters xmlParameters) {
+ for ( PropertyType property : config.getProperty() ) {
+ if ( log.isDebugEnabled() ) {
+ log.debug(
+ "Found property '{}' with value '{}' in
validation.xml.",
+ property.getName(),
+ property.getValue()
+ );
+ }
+ xmlParameters.configProperties.put( property.getName(), property.getValue() );
+ }
+ }
+
+ private void setMappingStreamsFromXml(ValidationConfigType config,
ValidationBootstrapParameters xmlParameters) {
+ for ( String mappingFileName : config.getConstraintMapping() ) {
+ if ( log.isDebugEnabled() ) {
+ log.debug(
+ "Trying to open input stream for {}.", mappingFileName
+ );
+ InputStream in = getInputStreamForPath( mappingFileName );
+ if ( in == null ) {
+ throw new ValidationException( "Unable to open input stream for mapping file
" + mappingFileName + "." );
+ }
+ xmlParameters.mappings.add( in );
+ }
+ }
+ }
+
+ private void setMessageInterpolatorFromXml(ValidationConfigType config,
ValidationBootstrapParameters xmlParameters) {
+ String messageInterpolatorClass = config.getMessageInterpolator();
+ if ( messageInterpolatorClass != null ) {
+ try {
+ @SuppressWarnings("unchecked")
+ Class<MessageInterpolator> clazz = ( Class<MessageInterpolator> )
ReflectionHelper.classForName(
+ messageInterpolatorClass, this.getClass()
+ );
+ xmlParameters.messageInterpolator = clazz.newInstance();
+ log.info( "Using {} as message interpolator.", messageInterpolatorClass );
+ }
+ catch ( ClassNotFoundException e ) {
+ throw new ValidationException(
+ "Unable to instantiate message interpolator class " +
messageInterpolatorClass + ".", e
+ );
+ }
+ catch ( InstantiationException e ) {
+ throw new ValidationException(
+ "Unable to instantiate message interpolator class " +
messageInterpolatorClass + ".", e
+ );
+ }
+ catch ( IllegalAccessException e ) {
+ throw new ValidationException(
+ "Unable to instantiate message interpolator class " +
messageInterpolatorClass + ".", e
+ );
+ }
+ }
+ }
+
+ private void setTraversableResolverFromXml(ValidationConfigType config,
ValidationBootstrapParameters xmlParameters) {
+ String traversableResolverClass = config.getTraversableResolver();
+ if ( traversableResolverClass != null ) {
+ try {
+ @SuppressWarnings("unchecked")
+ Class<TraversableResolver> clazz = ( Class<TraversableResolver> )
ReflectionHelper.classForName(
+ traversableResolverClass, this.getClass()
+ );
+ xmlParameters.traversableResolver = clazz.newInstance();
+ log.info( "Using {} as traversable resolver.", traversableResolverClass );
+ }
+ catch ( ClassNotFoundException e ) {
+ throw new ValidationException(
+ "Unable to instantiate traversable resolver class " +
traversableResolverClass + ".", e
+ );
+ }
+ catch ( InstantiationException e ) {
+ throw new ValidationException(
+ "Unable to instantiate traversable resolver class " +
traversableResolverClass + ".", e
+ );
+ }
+ catch ( IllegalAccessException e ) {
+ throw new ValidationException(
+ "Unable to instantiate traversable resolver class " +
traversableResolverClass + ".", e
+ );
+ }
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private void setProviderClassFromXml(ValidationConfigType config,
ValidationBootstrapParameters xmlParamters) {
+ String providerClassName = config.getDefaultProvider();
+ if ( providerClassName != null ) {
+ try {
+ xmlParamters.providerClass = ( Class<? extends Configuration<?>> )
ReflectionHelper.classForName(
+ providerClassName, this.getClass()
+ );
+ log.info( "Using {} as validation provider.", providerClassName );
+ }
+ catch ( Exception e ) {
+ throw new ValidationException( "Unable to instantiate validation provider class
" + providerClassName + "." );
+ }
+ }
+ }
+
+ private ValidationConfigType getValidationConfig() {
+ InputStream inputStream = getInputStreamForPath( VALIDATION_XML_FILE );
+ if ( inputStream == null ) {
+ log.info( "No {} found. Using annotation based configuration only!",
VALIDATION_XML_FILE );
+ return null;
+ }
+
+ log.info( "{} found.", VALIDATION_XML_FILE );
+
+ ValidationConfigType validationConfig = null;
+ Schema schema = getValidationConfigurationSchema();
+ try {
+ JAXBContext jc = JAXBContext.newInstance( ValidationConfigType.class );
+ Unmarshaller unmarshaller = jc.createUnmarshaller();
+ unmarshaller.setSchema( schema );
+ StreamSource stream = new StreamSource( inputStream );
+ JAXBElement<ValidationConfigType> root = unmarshaller.unmarshal( stream,
ValidationConfigType.class );
+ validationConfig = root.getValue();
+ }
+ catch ( JAXBException e ) {
+ log.error( "Error parsing validation.xml: {}", e.getMessage() );
+ }
+ return validationConfig;
+ }
+
+ private InputStream getInputStreamForPath(String path) {
+ InputStream inputStream = this.getClass().getResourceAsStream( path );
+ // try absolute path
+ if ( inputStream == null && !path.startsWith( "/" ) ) {
+ inputStream = this.getClass().getResourceAsStream( "/" + path );
+ }
+ return inputStream;
+ }
+
+ private Schema getValidationConfigurationSchema() {
+ URL schemaUrl = this.getClass().getClassLoader().getResource(
VALIDATION_CONFIGURATION_XSD );
+ SchemaFactory sf = SchemaFactory.newInstance(
javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI );
+ Schema schema = null;
+ try {
+ schema = sf.newSchema( schemaUrl );
+ }
+ catch ( SAXException e ) {
+ log.warn( "Unable to create schema for {}: {}",
VALIDATION_CONFIGURATION_XSD, e.getMessage() );
+ }
+ return schema;
+ }
+}
Property changes on:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/xml/ValidationXmlParser.java
___________________________________________________________________
Name: svn:keywords
+ Id
Added:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/xml/XmlMappingParser.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/xml/XmlMappingParser.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/xml/XmlMappingParser.java 2009-04-22
10:59:38 UTC (rev 16395)
@@ -0,0 +1,597 @@
+// $Id:$
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, and individual contributors
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* 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.hibernate.validation.engine.xml;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Array;
+import java.lang.reflect.Field;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.validation.Constraint;
+import javax.validation.ConstraintValidator;
+import javax.validation.ValidationException;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+
+import org.slf4j.Logger;
+import org.xml.sax.SAXException;
+
+import org.hibernate.validation.engine.ConstraintDescriptorImpl;
+import org.hibernate.validation.engine.ConstraintHelper;
+import org.hibernate.validation.engine.MetaConstraint;
+import org.hibernate.validation.util.LoggerFactory;
+import org.hibernate.validation.util.ReflectionHelper;
+import org.hibernate.validation.util.annotationfactory.AnnotationDescriptor;
+import org.hibernate.validation.util.annotationfactory.AnnotationFactory;
+import org.hibernate.validation.xml.AnnotationType;
+import org.hibernate.validation.xml.BeanType;
+import org.hibernate.validation.xml.ClassType;
+import org.hibernate.validation.xml.ConstraintDefinitionType;
+import org.hibernate.validation.xml.ConstraintMappingsType;
+import org.hibernate.validation.xml.ConstraintType;
+import org.hibernate.validation.xml.ElementType;
+import org.hibernate.validation.xml.FieldType;
+import org.hibernate.validation.xml.GetterType;
+import org.hibernate.validation.xml.GroupSequenceType;
+import org.hibernate.validation.xml.GroupsType;
+import org.hibernate.validation.xml.ValidatedByType;
+
+/**
+ * @author Hardy Ferentschik
+ */
+public class XmlMappingParser {
+
+ private static final Logger log = LoggerFactory.make();
+ private static final String VALIDATION_MAPPING_XSD =
"META-INF/validation-mapping-1.0.xsd";
+ private static final String MESSAGE_PARAM = "message";
+ private static final String GROUPS_PARAM = "groups";
+ private static final String PACKAGE_SEPERATOR = ".";
+
+ private final Set<Class<?>> processedClasses = new
HashSet<Class<?>>();
+ private final ConstraintHelper constraintHelper;
+ private final AnnotationIgnores annotationIgnores;
+ private final Map<Class<?>, List<MetaConstraint<?, ? extends
Annotation>>> constraintMap;
+ private final Map<Class<?>, List<Member>> cascadedMembers;
+ private final Map<Class<?>, List<Class<?>>> defaultSequences;
+
+ public XmlMappingParser(ConstraintHelper constraintHelper) {
+ this.constraintHelper = constraintHelper;
+ this.annotationIgnores = new AnnotationIgnores();
+ this.constraintMap = new HashMap<Class<?>, List<MetaConstraint<?, ?
extends Annotation>>>();
+ this.cascadedMembers = new HashMap<Class<?>, List<Member>>();
+ this.defaultSequences = new HashMap<Class<?>,
List<Class<?>>>();
+ }
+
+ public void parse(Set<InputStream> mappingStreams) {
+ for ( InputStream in : mappingStreams ) {
+ try {
+ ConstraintMappingsType mapping = getValidationConfig( in );
+ parseConstraintDefinitions( mapping.getConstraintDefinition() );
+ String defaultPackage = mapping.getDefaultPackage();
+ for ( BeanType bean : mapping.getBean() ) {
+ Class<?> beanClass = getClass( bean.getClazz(), defaultPackage );
+ checkClassHasNotBeenProcessed( processedClasses, beanClass );
+ annotationIgnores.setDefaultIgnoreAnnotation( beanClass, bean.isIgnoreAnnotations()
);
+ parseClassLevelOverrides( bean.getClassType(), beanClass, defaultPackage );
+ parseFieldLevelOverrides( bean.getField(), beanClass, defaultPackage );
+ parsePropertyLevelOverrides( bean.getGetter(), beanClass, defaultPackage );
+ processedClasses.add( beanClass );
+ }
+ }
+ finally {
+ try {
+ in.close();
+ }
+ catch ( IOException e ) {
+ log.warn( "Error closing input stream: {}", e.getMessage() );
+ }
+ }
+ }
+ }
+
+ public Set<Class<?>> getProcessedClasses() {
+ return processedClasses;
+ }
+
+ public AnnotationIgnores getAnnotationIgnores() {
+ return annotationIgnores;
+ }
+
+ public Map<Class<?>, List<MetaConstraint<?, ? extends
Annotation>>> getConstraintMap() {
+ return constraintMap;
+ }
+
+ public Map<Class<?>, List<Member>> getCascadedMembers() {
+ return cascadedMembers;
+ }
+
+ public Map<Class<?>, List<Class<?>>> getDefaultSequences() {
+ return defaultSequences;
+ }
+
+ @SuppressWarnings("unchecked")
+ private void parseConstraintDefinitions(List<ConstraintDefinitionType>
constraintDefinitionList) {
+ for ( ConstraintDefinitionType constraintDefinition : constraintDefinitionList ) {
+ String annotationClassName = constraintDefinition.getAnnotation();
+ Class<? extends Annotation> annotationClass;
+ try {
+ annotationClass = ( Class<? extends Annotation> )
ReflectionHelper.classForName(
+ annotationClassName, this.getClass()
+ );
+ }
+ catch ( ClassNotFoundException e ) {
+ throw new ValidationException( "Unable to load class " +
annotationClassName );
+ }
+
+ if ( !annotationClass.isAnnotation() ) {
+ throw new ValidationException( annotationClassName + " is not an
annotation" );
+ }
+
+ ValidatedByType validatedByType = constraintDefinition.getValidatedBy();
+ List<Class<? extends ConstraintValidator<? extends Annotation, ?>>>
constraintValidatorClasses = new ArrayList<Class<? extends ConstraintValidator<?
extends Annotation, ?>>>();
+ if ( validatedByType.isIncludeExistingValidators() != null &&
validatedByType.isIncludeExistingValidators() ) {
+ constraintValidatorClasses.addAll( findConstraintValidatorClasses( annotationClass )
);
+ }
+ for ( String validatorClassName : validatedByType.getValue() ) {
+ Class<? extends ConstraintValidator<?, ?>> validatorClass;
+ try {
+ validatorClass = ( Class<? extends ConstraintValidator<?, ?>> )
ReflectionHelper.classForName(
+ validatorClassName,
+ this.getClass()
+ );
+ }
+ catch ( ClassNotFoundException e ) {
+ throw new ValidationException( "Unable to load class " +
validatorClassName );
+ }
+
+ if ( !ConstraintValidator.class.isAssignableFrom( validatorClass ) ) {
+ throw new ValidationException( validatorClass + " is not a constraint validator
class" );
+ }
+
+ constraintValidatorClasses.add( validatorClass );
+ }
+ constraintHelper.addConstraintValidatorDefinition(
+ annotationClass, constraintValidatorClasses
+ );
+ }
+ }
+
+ private List<Class<? extends ConstraintValidator<? extends Annotation,
?>>> findConstraintValidatorClasses(Class<? extends Annotation>
annotationType) {
+ List<Class<? extends ConstraintValidator<? extends Annotation, ?>>>
constraintValidatorDefinitonClasses = new ArrayList<Class<? extends
ConstraintValidator<? extends Annotation, ?>>>();
+ if ( constraintHelper.isBuiltinConstraint( annotationType ) ) {
+ constraintValidatorDefinitonClasses.addAll( constraintHelper.getBuiltInConstraints(
annotationType ) );
+ }
+ else {
+ Class<? extends ConstraintValidator<?, ?>>[] validatedBy = annotationType
+ .getAnnotation( Constraint.class )
+ .validatedBy();
+ for ( Class<? extends ConstraintValidator<?, ?>> validator : validatedBy )
{
+ //FIXME does this create a CCE at runtime?
+ //FIXME if yes wrap into VE, if no we need to test the type here
+ //Once resolved,we can @SuppressWarning("unchecked") on the cast
+ Class<? extends ConstraintValidator<? extends Annotation, ?>>
safeValidator = validator;
+ constraintValidatorDefinitonClasses.add( safeValidator );
+ }
+ }
+ return constraintValidatorDefinitonClasses;
+ }
+
+ private void checkClassHasNotBeenProcessed(Set<Class<?>> processedClasses,
Class<?> beanClass) {
+ if ( processedClasses.contains( beanClass ) ) {
+ throw new ValidationException( beanClass.getName() + " has already be configured
in xml." );
+ }
+ }
+
+ private void parseFieldLevelOverrides(List<FieldType> fields, Class<?>
beanClass, String defaultPackage) {
+ for ( FieldType fieldType : fields ) {
+ String fieldName = fieldType.getName();
+ if ( !ReflectionHelper.containsField( beanClass, fieldName ) ) {
+ throw new ValidationException( beanClass.getName() + " does not contain the
fieldType " + fieldName );
+ }
+ Field field = ReflectionHelper.getField( beanClass, fieldName );
+
+ // ignore annotations
+ boolean ignoreFieldAnnotation = fieldType.isIgnoreAnnotations() == null ? false :
fieldType.isIgnoreAnnotations();
+ if ( ignoreFieldAnnotation ) {
+ annotationIgnores.setIgnoreAnnotationsOnMember( field );
+ }
+
+ // valid
+ if ( fieldType.getValid() != null ) {
+ addCascadedMember( beanClass, field );
+ }
+
+ // constraints
+ for ( ConstraintType constraint : fieldType.getConstraint() ) {
+ MetaConstraint<?, ?> metaConstraint = createMetaConstraint(
+ constraint, beanClass, field, defaultPackage
+ );
+ addMetaConstraint( beanClass, metaConstraint );
+ }
+ }
+ }
+
+ private void parsePropertyLevelOverrides(List<GetterType> getters, Class<?>
beanClass, String defaultPackage) {
+ for ( GetterType getterType : getters ) {
+ String getterName = getterType.getName();
+ if ( !ReflectionHelper.containsMethod( beanClass, getterName ) ) {
+ throw new ValidationException( beanClass.getName() + " does not contain the
property " + getterName );
+ }
+ Method method = ReflectionHelper.getMethod( beanClass, getterName );
+
+ // ignore annotations
+ boolean ignoreGetterAnnotation = getterType.isIgnoreAnnotations() == null ? false :
getterType.isIgnoreAnnotations();
+ if ( ignoreGetterAnnotation ) {
+ annotationIgnores.setIgnoreAnnotationsOnMember( method );
+ }
+
+ // valid
+ if ( getterType.getValid() != null ) {
+ addCascadedMember( beanClass, method );
+ }
+
+ // constraints
+ for ( ConstraintType constraint : getterType.getConstraint() ) {
+ MetaConstraint<?, ?> metaConstraint = createMetaConstraint(
+ constraint, beanClass, method, defaultPackage
+ );
+ addMetaConstraint( beanClass, metaConstraint );
+ }
+ }
+ }
+
+ private void parseClassLevelOverrides(ClassType classType, Class<?> beanClass,
String defaultPackage) {
+ if ( classType == null ) {
+ return;
+ }
+
+ // ignore annotation
+ boolean ignoreClassAnnotation = classType.isIgnoreAnnotations() == null ? false :
classType.isIgnoreAnnotations();
+ if ( ignoreClassAnnotation ) {
+ annotationIgnores.setIgnoreAnnotationsOnClass( beanClass );
+ }
+
+ // group sequence
+ List<Class<?>> groupSequence = createGroupSequence(
classType.getGroupSequence(), defaultPackage );
+ if ( !groupSequence.isEmpty() ) {
+ defaultSequences.put( beanClass, groupSequence );
+ }
+
+ // constraints
+ for ( ConstraintType constraint : classType.getConstraint() ) {
+ MetaConstraint<?, ?> metaConstraint = createMetaConstraint( constraint,
beanClass, null, defaultPackage );
+ addMetaConstraint( beanClass, metaConstraint );
+ }
+ }
+
+ private void addMetaConstraint(Class<?> beanClass, MetaConstraint<?, ?>
metaConstraint) {
+ if ( constraintMap.containsKey( beanClass ) ) {
+ constraintMap.get( beanClass ).add( metaConstraint );
+ }
+ else {
+ List<MetaConstraint<?, ? extends Annotation>> constraintList = new
ArrayList<MetaConstraint<?, ? extends Annotation>>();
+ constraintList.add( metaConstraint );
+ constraintMap.put( beanClass, constraintList );
+ }
+ }
+
+ private void addCascadedMember(Class<?> beanClass, Member member) {
+ if ( cascadedMembers.containsKey( beanClass ) ) {
+ cascadedMembers.get( beanClass ).add( member );
+ }
+ else {
+ List<Member> tmpList = new ArrayList<Member>();
+ tmpList.add( member );
+ cascadedMembers.put( beanClass, tmpList );
+ }
+ }
+
+ private List<Class<?>> createGroupSequence(GroupSequenceType
groupSequenceType, String defaultPackage) {
+ List<Class<?>> groupSequence = new ArrayList<Class<?>>();
+ for ( String groupName : groupSequenceType.getValue() ) {
+ Class<?> group = getClass( groupName, defaultPackage );
+ groupSequence.add( group );
+ }
+ return groupSequence;
+ }
+
+ private <A extends Annotation, T> MetaConstraint<?, ?>
createMetaConstraint(ConstraintType constraint, Class<T> beanClass, Member member,
String defaultPackage) {
+ @SuppressWarnings("unchecked")
+ Class<A> annotationClass = ( Class<A> ) getClass(
constraint.getAnnotation(), defaultPackage );
+ AnnotationDescriptor<A> annotationDescriptor = new AnnotationDescriptor<A>(
annotationClass );
+
+ if ( constraint.getMessage() != null ) {
+ annotationDescriptor.setValue( MESSAGE_PARAM, constraint.getMessage() );
+ }
+ annotationDescriptor.setValue( GROUPS_PARAM, getGroups( constraint.getGroups(),
defaultPackage ) );
+
+ for ( ElementType elementType : constraint.getElement() ) {
+ String name = elementType.getName();
+ checkNameIsValid( name );
+ Class<?> returnType = getAnnotationParamterType( annotationClass, name );
+ Object elementValue = getElementValue( elementType, returnType );
+ annotationDescriptor.setValue( name, elementValue );
+ }
+
+ A annotation = AnnotationFactory.create( annotationDescriptor );
+ ConstraintDescriptorImpl<A> constraintDescriptor = new
ConstraintDescriptorImpl<A>(
+ annotation, new Class[] { }, constraintHelper
+ );
+
+ MetaConstraint<T, A> metaConstraint;
+ if ( member == null ) {
+ metaConstraint = new MetaConstraint<T, A>( beanClass, constraintDescriptor );
+ }
+ else {
+ metaConstraint = new MetaConstraint<T, A>( member, beanClass,
constraintDescriptor );
+ }
+ return metaConstraint;
+ }
+
+ private <A extends Annotation> Class<?>
getAnnotationParamterType(Class<A> annotationClass, String name) {
+ Method m;
+ try {
+ m = annotationClass.getMethod( name );
+ }
+ catch ( NoSuchMethodException e ) {
+ throw new ValidationException( "Annotation of type " +
annotationClass.getName() + " does not contain a paramter " + name +
"." );
+ }
+ return m.getReturnType();
+ }
+
+ private Object getElementValue(ElementType elementType, Class<?> returnType) {
+ removeEmptyContentElements( elementType );
+
+ boolean isArray = returnType.isArray();
+ if ( !isArray ) {
+ if ( elementType.getContent().size() != 1 ) {
+ throw new ValidationException( "Attempt to specify an array where single value
is expected." );
+ }
+ return getSingleValue( elementType.getContent().get( 0 ), returnType );
+ }
+ else {
+ List<Object> values = new ArrayList<Object>();
+ for ( Serializable s : elementType.getContent() ) {
+ values.add( getSingleValue( s, returnType.getComponentType() ) );
+ }
+ return values.toArray( ( Object[] ) Array.newInstance( returnType.getComponentType(),
values.size() ) );
+ }
+ }
+
+ private void removeEmptyContentElements(ElementType elementType) {
+ List<Serializable> contentToDelete = new ArrayList<Serializable>();
+ for ( Serializable content : elementType.getContent() ) {
+ if ( content instanceof String && ( ( String ) content ).matches( "[\\n
].*" ) ) {
+ contentToDelete.add( content );
+ }
+ }
+ elementType.getContent().removeAll( contentToDelete );
+ }
+
+ private Object getSingleValue(Serializable serializable, Class<?> returnType) {
+
+ Object returnValue;
+ if ( serializable instanceof String ) {
+ String value = ( String ) serializable;
+ returnValue = convertStringToReturnType( returnType, value );
+ }
+ else if ( serializable instanceof JAXBElement && ( ( JAXBElement ) serializable
).getDeclaredType()
+ .equals( String.class ) ) {
+ JAXBElement<?> elem = ( JAXBElement<?> ) serializable;
+ String value = ( String ) elem.getValue();
+ returnValue = convertStringToReturnType( returnType, value );
+ }
+ else if ( serializable instanceof JAXBElement && ( ( JAXBElement ) serializable
).getDeclaredType()
+ .equals( AnnotationType.class ) ) {
+ JAXBElement<?> elem = ( JAXBElement<?> ) serializable;
+ AnnotationType annotationType = ( AnnotationType ) elem.getValue();
+ try {
+ @SuppressWarnings("unchecked")
+ Class<Annotation> annotationClass = ( Class<Annotation> ) returnType;
+ returnValue = createAnnotation( annotationType, annotationClass );
+ }
+ catch ( ClassCastException e ) {
+ throw new ValidationException( "Unexpected paramter value" );
+ }
+ }
+ else {
+ throw new ValidationException( "Unexpected paramter value" );
+ }
+ return returnValue;
+
+ }
+
+ private <A extends Annotation> Annotation createAnnotation(AnnotationType
annotationType, Class<A> returnType) {
+ AnnotationDescriptor<A> annotationDescriptor = new AnnotationDescriptor<A>(
returnType );
+ for ( ElementType elementType : annotationType.getElement() ) {
+ String name = elementType.getName();
+ Class<?> paramterType = getAnnotationParamterType( returnType, name );
+ Object elementValue = getElementValue( elementType, paramterType );
+ annotationDescriptor.setValue( name, elementValue );
+ }
+ return AnnotationFactory.create( annotationDescriptor );
+ }
+
+ private Object convertStringToReturnType(Class<?> returnType, String value) {
+ Object returnValue;
+ if ( returnType.getName().equals( byte.class.getName() ) ) {
+ try {
+ returnValue = Byte.parseByte( value );
+ }
+ catch ( NumberFormatException e ) {
+ throw new ValidationException( "Invalid byte format", e );
+ }
+ }
+ else if ( returnType.getName().equals( short.class.getName() ) ) {
+ try {
+ returnValue = Short.parseShort( value );
+ }
+ catch ( NumberFormatException e ) {
+ throw new ValidationException( "Invalid short format", e );
+ }
+ }
+ else if ( returnType.getName().equals( int.class.getName() ) ) {
+ try {
+ returnValue = Integer.parseInt( value );
+ }
+ catch ( NumberFormatException e ) {
+ throw new ValidationException( "Invalid int format", e );
+ }
+ }
+ else if ( returnType.getName().equals( long.class.getName() ) ) {
+ try {
+ returnValue = Long.parseLong( value );
+ }
+ catch ( NumberFormatException e ) {
+ throw new ValidationException( "Invalid long format", e );
+ }
+ }
+ else if ( returnType.getName().equals( float.class.getName() ) ) {
+ try {
+ returnValue = Float.parseFloat( value );
+ }
+ catch ( NumberFormatException e ) {
+ throw new ValidationException( "Invalid float format", e );
+ }
+ }
+ else if ( returnType.getName().equals( double.class.getName() ) ) {
+ try {
+ returnValue = Double.parseDouble( value );
+ }
+ catch ( NumberFormatException e ) {
+ throw new ValidationException( "Invalid double format", e );
+ }
+ }
+ else if ( returnType.getName().equals( boolean.class.getName() ) ) {
+ returnValue = Boolean.parseBoolean( value );
+ }
+ else if ( returnType.getName().equals( char.class.getName() ) ) {
+ if ( value.length() != 1 ) {
+ throw new ValidationException( "Invalid char value: " + value );
+ }
+ returnValue = value.charAt( 0 );
+ }
+ else if ( returnType.getName().equals( String.class.getName() ) ) {
+ returnValue = value;
+ }
+ else if ( returnType.getName().equals( Class.class.getName() ) ) {
+ try {
+ returnValue = ReflectionHelper.classForName( value, this.getClass() );
+ }
+ catch ( ClassNotFoundException e ) {
+ throw new ValidationException( "Unable to instantiate class: " + value );
+ }
+ }
+ else {
+ try {
+ @SuppressWarnings("unchecked")
+ Class<Enum> enumClass = ( Class<Enum> ) returnType;
+ returnValue = Enum.valueOf( enumClass, value );
+ }
+ catch ( ClassCastException e ) {
+ throw new ValidationException( "Invalid return type: " + returnType +
". Should be a enumeration type." );
+ }
+ }
+ return returnValue;
+ }
+
+ private void checkNameIsValid(String name) {
+ if ( MESSAGE_PARAM.equals( name ) || GROUPS_PARAM.equals( name ) ) {
+ throw new ValidationException( MESSAGE_PARAM + " and " + GROUPS_PARAM +
" are reserved paramter names." );
+ }
+ }
+
+ private Class<?>[] getGroups(GroupsType groupsType, String defaultPackage) {
+ if ( groupsType == null ) {
+ return new Class[] { };
+ }
+
+ List<Class<?>> groupList = new ArrayList<Class<?>>();
+ for ( String groupClass : groupsType.getValue() ) {
+ groupList.add( getClass( groupClass, defaultPackage ) );
+ }
+ return groupList.toArray( new Class[groupList.size()] );
+ }
+
+ private Class<?> getClass(String clazz, String defaultPackage) {
+ String fullyQualifiedClass;
+ if ( isQualifiedClass( clazz ) ) {
+ fullyQualifiedClass = clazz;
+ }
+ else {
+ fullyQualifiedClass = defaultPackage + PACKAGE_SEPERATOR + clazz;
+ }
+ try {
+ return ReflectionHelper.classForName( fullyQualifiedClass, this.getClass() );
+ }
+ catch ( Exception e ) {
+ throw new ValidationException( "Unable to instantiate class " +
fullyQualifiedClass );
+ }
+ }
+
+ private boolean isQualifiedClass(String clazz) {
+ return clazz.contains( PACKAGE_SEPERATOR );
+ }
+
+ private ConstraintMappingsType getValidationConfig(InputStream in) {
+ ConstraintMappingsType constraintMappings;
+ Schema schema = getMappingSchema();
+ try {
+ JAXBContext jc = JAXBContext.newInstance( ConstraintMappingsType.class );
+ Unmarshaller unmarshaller = jc.createUnmarshaller();
+ unmarshaller.setSchema( schema );
+ StreamSource stream = new StreamSource( in );
+ JAXBElement<ConstraintMappingsType> root = unmarshaller.unmarshal( stream,
ConstraintMappingsType.class );
+ constraintMappings = root.getValue();
+ }
+ catch ( JAXBException e ) {
+ String msg = "Error parsing mapping file.";
+ log.error( msg );
+ throw new ValidationException( msg, e );
+ }
+ return constraintMappings;
+ }
+
+ private Schema getMappingSchema() {
+ URL schemaUrl = this.getClass().getClassLoader().getResource( VALIDATION_MAPPING_XSD
);
+ SchemaFactory sf = SchemaFactory.newInstance(
javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI );
+ Schema schema = null;
+ try {
+ schema = sf.newSchema( schemaUrl );
+ }
+ catch ( SAXException e ) {
+ log.warn( "Unable to create schema for {}: {}", VALIDATION_MAPPING_XSD,
e.getMessage() );
+ }
+ return schema;
+ }
+}
Property changes on:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/xml/XmlMappingParser.java
___________________________________________________________________
Name: svn:keywords
+ Id
Property changes on:
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/xml/Optional.java
___________________________________________________________________
Name: svn:keywords
+ Id
Property changes on:
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/xml/TestGroup.java
___________________________________________________________________
Name: svn:keywords
+ Id
Property changes on:
validator/trunk/hibernate-validator-archetype/src/main/java/org/hibernate/validator/quickstart/Car.java
___________________________________________________________________
Name: svn:keywords
+ Id
Property changes on:
validator/trunk/hibernate-validator-archetype/src/test/java/org/hibernate/validator/quickstart/CarTest.java
___________________________________________________________________
Name: svn:keywords
+ Id
Property changes on:
validator/trunk/hibernate-validator-tck-runner/src/main/java/org/hibernate/validation/test/StandaloneContainersImpl.java
___________________________________________________________________
Name: svn:keywords
+ Id