Skip to content

Commit

Permalink
HV-441: Extracting processing of XML constraints from ValidatorFactor…
Browse files Browse the repository at this point in the history
…y to separate class
  • Loading branch information
gunnarmorling committed Sep 5, 2011
1 parent e3232f6 commit 2549814
Show file tree
Hide file tree
Showing 3 changed files with 303 additions and 62 deletions.
Expand Up @@ -22,6 +22,7 @@
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
Expand All @@ -42,6 +43,7 @@
import org.hibernate.validator.metadata.AggregatedMethodMetaData;
import org.hibernate.validator.metadata.AnnotationIgnores;
import org.hibernate.validator.metadata.BeanMetaConstraint;
import org.hibernate.validator.metadata.BeanMetaDataBuilder;
import org.hibernate.validator.metadata.BeanMetaDataCache;
import org.hibernate.validator.metadata.BeanMetaDataImpl;
import org.hibernate.validator.metadata.ConstraintDescriptorImpl;
Expand Down Expand Up @@ -99,7 +101,10 @@ public ValidatorFactoryImpl(ConfigurationState configurationState) {

// HV-302; don't load XmlMappingParser if not necessary
if ( !configurationState.getMappingStreams().isEmpty() ) {
initXmlConfiguration( configurationState.getMappingStreams() );
// initXmlConfiguration( configurationState.getMappingStreams() );

BeanMetaDataBuilder builder = new BeanMetaDataBuilder( constraintHelper, beanMetaDataCache );
initXmlConfiguration( configurationState.getMappingStreams(), builder );
}

if ( configurationState instanceof ConfigurationImpl ) {
Expand Down Expand Up @@ -157,9 +162,9 @@ public HibernateValidatorContext usingContext() {
* @param mapping The constraint configuration created via the programmatic API.
*/
private <T> void initProgrammaticConfiguration(ConstraintMapping mapping) {
ConstraintMappingContext context = ConstraintMappingContext.getFromMapping(mapping);

ConstraintMappingContext context = ConstraintMappingContext.getFromMapping( mapping );

final Map<Class<?>, List<ConfiguredConstraint<?, BeanConstraintLocation>>> constraintsByType = context.getConstraintConfig();
final Map<Class<?>, List<ConfiguredConstraint<?, MethodConstraintLocation>>> methodConstraintsByType = context
.getMethodConstraintConfig();
Expand Down Expand Up @@ -238,69 +243,34 @@ private <T> void initProgrammaticConfiguration(ConstraintMapping mapping) {
}
}

private <T> void initXmlConfiguration(Set<InputStream> mappingStreams) {
private void initXmlConfiguration(Set<InputStream> mappingStreams, BeanMetaDataBuilder builder) {

XmlMappingParser mappingParser = new XmlMappingParser( constraintHelper );
mappingParser.parse( mappingStreams );

Set<Class<?>> xmlConfiguredClasses = mappingParser.getXmlConfiguredClasses();
AnnotationIgnores annotationIgnores = mappingParser.getAnnotationIgnores();
for ( Class<?> clazz : xmlConfiguredClasses ) {
@SuppressWarnings("unchecked")
Class<T> beanClass = (Class<T>) clazz;
builder.setAnnotationIgnores( mappingParser.getAnnotationIgnores() );

List<Class<?>> classes = ReflectionHelper.computeClassHierarchy( beanClass, true );
Map<Class<?>, List<BeanMetaConstraint<?>>> constraints = newHashMap();
Set<Member> cascadedMembers = newHashSet();
// we need to collect all constraints which apply for a single class. Due to constraint inheritance
// some constraints might be configured in super classes or interfaces. The xml configuration does not
// imply any order so we have to check whether any of the super classes or interfaces of a given bean has
// as well been configured via xml
for ( Class<?> classInHierarchy : classes ) {
if ( xmlConfiguredClasses.contains( classInHierarchy ) ) {
addXmlConfiguredConstraints( mappingParser, beanClass, classInHierarchy, constraints );
addXmlCascadedMember( mappingParser, classInHierarchy, cascadedMembers );
}
}
for ( Class<?> clazz : xmlConfiguredClasses ) {

BeanMetaDataImpl<T> metaData = new BeanMetaDataImpl<T>(
beanClass,
constraintHelper,
mappingParser.getDefaultSequenceForClass( beanClass ),
null,
constraints,
Collections.<AggregatedMethodMetaData>emptySet(),
cascadedMembers,
annotationIgnores,
beanMetaDataCache
builder.addBeanConfiguration(
clazz,
new HashSet<BeanMetaConstraint<?>>( mappingParser.getConstraintsForClass( clazz ) ),
new HashSet<Member>( mappingParser.getCascadedMembersForClass( clazz ) ),
mappingParser.getDefaultSequenceForClass( clazz )
);

beanMetaDataCache.addBeanMetaData( beanClass, metaData );
}
}

@SuppressWarnings("unchecked")
private <T, A extends Annotation> void addXmlConfiguredConstraints(XmlMappingParser mappingParser,
Class<T> rootClass,
Class<?> hierarchyClass, Map<Class<?>, List<BeanMetaConstraint<?>>> constraints) {
for ( BeanMetaConstraint<?> constraint : mappingParser.getConstraintsForClass( hierarchyClass ) ) {
List<BeanMetaDataImpl<?>> allMetaData = builder.getBeanMetaData();

ConstraintOrigin definedIn = definedIn( rootClass, hierarchyClass );
ConstraintDescriptorImpl<A> descriptor = new ConstraintDescriptorImpl<A>(
(A) constraint.getDescriptor().getAnnotation(),
constraintHelper,
constraint.getElementType(),
definedIn
);
for ( BeanMetaDataImpl<?> oneBeanMetaData : allMetaData ) {
registerWithCache( oneBeanMetaData );
}

BeanMetaConstraint<A> newMetaConstraint = new BeanMetaConstraint<A>(
descriptor,
constraint.getLocation().getBeanClass(),
constraint.getLocation().getMember()
);
}

addConstraintToMap( hierarchyClass, newMetaConstraint, constraints );
}
private <T> void registerWithCache(BeanMetaDataImpl<T> metaData) {
beanMetaDataCache.addBeanMetaData( metaData.getBeanClass(), metaData );
}

@SuppressWarnings("unchecked")
Expand Down Expand Up @@ -335,14 +305,6 @@ private <M extends MetaConstraint<?>> void addConstraintToMap(Class<?> hierarchy
constraintList.add( constraint );
}

private void addXmlCascadedMember(XmlMappingParser mappingParser,
Class<?> hierarchyClass,
Set<Member> cascadedMembers) {
for ( Member m : mappingParser.getCascadedMembersForClass( hierarchyClass ) ) {
cascadedMembers.add( m );
}
}

private void addProgrammaticConfiguredCascade(List<BeanConstraintLocation> cascades,
Set<Member> cascadedMembers) {

Expand Down
@@ -0,0 +1,93 @@
/*
* JBoss, Home of Professional Open Source
* Copyright 2011, Red Hat, Inc. and/or its affiliates, 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.validator.metadata;

import java.lang.reflect.Member;
import java.util.List;
import java.util.Set;

/**
* @author Gunnar Morling
*/
public class BeanConfiguration<T> {

private final Class<T> beanClass;

private final Set<BeanMetaConstraint<?>> constraints;

private final Set<Member> cascadedMembers;

private List<Class<?>> defaultGroupSequence;

/**
* @param beanClass
* @param constraints
* @param cascadedMembers
* @param defaultGroupSequence
*/
public BeanConfiguration(Class<T> beanClass,
Set<BeanMetaConstraint<?>> constraints,
Set<Member> cascadedMembers, List<Class<?>> defaultGroupSequence) {

this.beanClass = beanClass;
this.constraints = constraints;
this.cascadedMembers = cascadedMembers;
this.defaultGroupSequence = defaultGroupSequence;
}

public Class<T> getBeanClass() {
return beanClass;
}

public Set<BeanMetaConstraint<?>> getConstraints() {
return constraints;
}

public Set<Member> getCascadedMembers() {
return cascadedMembers;
}

public List<Class<?>> getDefaultGroupSequence() {
return defaultGroupSequence;
}

@Override
public String toString() {
return "BeanConfiguration [beanClass=" + beanClass + ", constraints="
+ constraints + ", cascadedMembers=" + cascadedMembers
+ ", defaultGroupSequence=" + defaultGroupSequence + "]";
}

public void merge(BeanConfiguration<T> other) {

if ( !other.getBeanClass().equals( beanClass ) ) {
throw new IllegalArgumentException(
"Can only merge configurations for same bean class. This bean class is " + beanClass + ", other bean class is " + other
.getBeanClass()
);
}

constraints.addAll( other.getConstraints() );
cascadedMembers.addAll( other.getCascadedMembers() );

//TODO GM: Determine which default sequence should be taken
if ( defaultGroupSequence == null && other.getDefaultGroupSequence() != null ) {
defaultGroupSequence = other.getDefaultGroupSequence();
}
}

}

0 comments on commit 2549814

Please sign in to comment.