Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
*/
package org.hibernate.validator.internal.engine;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
Expand Down Expand Up @@ -135,11 +136,20 @@ public final ConfigurationImpl constraintValidatorFactory(ConstraintValidatorFac
return this;
}

public final HibernateValidatorConfiguration addMapping(InputStream stream) {
/**
* {@inheritDoc}
*
* @param stream XML mapping stream.
* <p>
* <b>Note</b>: In order to reuse the {@code ConfigurationInstance} to build multiple
* validator factories a {@link java.io.BufferedInputStream} has to be provided.
* </p>
*/

public final HibernateValidatorConfiguration addMapping(InputStream stream) {
Contracts.assertNotNull( stream, MESSAGES.parameterMustNotBeNull( "stream" ) );

validationBootstrapParameters.addMapping( stream );
validationBootstrapParameters.addMapping( stream.markSupported() ? stream : new BufferedInputStream(stream) );
return this;
}

Expand Down Expand Up @@ -201,8 +211,6 @@ public final ValidatorFactory buildValidatorFactory() {
}
}

// reset the param holder
validationBootstrapParameters = new ValidationBootstrapParameters();
return factory;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,15 @@
* XML descriptors as defined by the Bean Validation API.
*
* @author Gunnar Morling
* @author Hardy Ferentschik
*/
public class XmlConfigurationMetaDataProvider extends MetaDataProviderImplBase {

private final AnnotationIgnores annotationIgnores;

/**
* @param mappingStreams
* @param constraintHelper the constraint helper utility
* @param mappingStreams the defined mapping streams
*/
public XmlConfigurationMetaDataProvider(ConstraintHelper constraintHelper, Set<InputStream> mappingStreams) {

Expand All @@ -66,7 +68,7 @@ public XmlConfigurationMetaDataProvider(ConstraintHelper constraintHelper, Set<I
Map<ConstraintLocation, Set<MetaConstraint<?>>> constraintsByLocation = partition(
mappingParser.getConstraintsForClass( clazz ), byLocation()
);
Set<BeanConstraintLocation> cascades = getCascades( mappingParser, clazz );
Set<ConstraintLocation> cascades = getCascades( mappingParser, clazz );

Set<ConstrainedElement> constrainedElements = getConstrainedElements( constraintsByLocation, cascades );

Expand All @@ -85,7 +87,7 @@ public XmlConfigurationMetaDataProvider(ConstraintHelper constraintHelper, Set<I
annotationIgnores = mappingParser.getAnnotationIgnores();
}

private Set<ConstrainedElement> getConstrainedElements(Map<ConstraintLocation, Set<MetaConstraint<?>>> constraintsByLocation, Set<BeanConstraintLocation> cascades) {
private Set<ConstrainedElement> getConstrainedElements(Map<ConstraintLocation, Set<MetaConstraint<?>>> constraintsByLocation, Set<ConstraintLocation> cascades) {

Set<ConstraintLocation> configuredLocations = new HashSet<ConstraintLocation>( cascades );
configuredLocations.addAll( constraintsByLocation.keySet() );
Expand Down Expand Up @@ -129,20 +131,20 @@ else if ( oneConfiguredLocation.getElementType() == ElementType.TYPE ) {
}

/**
* @param mappingParser
* @param clazz
* @param mappingParser the xml parser
* @param clazz the type for which to retrieve cascaded members
*
* @return
* @return returns a set of cascaded constraints
*/
private Set<BeanConstraintLocation> getCascades(XmlMappingParser mappingParser, Class<?> clazz) {
private Set<ConstraintLocation> getCascades(XmlMappingParser mappingParser, Class<?> clazz) {

Set<BeanConstraintLocation> theValue = newHashSet();
Set<ConstraintLocation> cascadedConstraintSet = newHashSet();

for ( Member member : mappingParser.getCascadedMembersForClass( clazz ) ) {
theValue.add( new BeanConstraintLocation( member ) );
cascadedConstraintSet.add( new BeanConstraintLocation( member ) );
}

return theValue;
return cascadedConstraintSet;
}

public AnnotationIgnores getAnnotationIgnores() {
Expand All @@ -156,5 +158,4 @@ public ConstraintLocation getPartition(MetaConstraint<?> constraint) {
}
};
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
*/
package org.hibernate.validator.internal.xml;

import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.lang.annotation.Annotation;
Expand Down Expand Up @@ -577,12 +579,27 @@ private ConstraintMappingsType getValidationConfig(InputStream in) {
ConstraintMappingsType constraintMappings;
Schema schema = getMappingSchema();
try {
// check whether mark is supported, if so we can reset the stream in order to allow reuse of Configuration
boolean markSupported = in.markSupported();
if ( markSupported ) {
in.mark( Integer.MAX_VALUE );
}

JAXBContext jc = JAXBContext.newInstance( ConstraintMappingsType.class );
Unmarshaller unmarshaller = jc.createUnmarshaller();
unmarshaller.setSchema( schema );
StreamSource stream = new StreamSource( in );
StreamSource stream = new StreamSource( new CloseIgnoringInputStream( in ) );
JAXBElement<ConstraintMappingsType> root = unmarshaller.unmarshal( stream, ConstraintMappingsType.class );
constraintMappings = root.getValue();

if ( markSupported ) {
try {
in.reset();
}
catch ( IOException e ) {
log.debug( "Unable to reset input stream." );
}
}
}
catch ( JAXBException e ) {
throw log.getErrorParsingMappingFileException( e );
Expand All @@ -603,4 +620,16 @@ private Schema getMappingSchema() {
}
return schema;
}

// JAXB closes the underlying input stream
public class CloseIgnoringInputStream extends FilterInputStream {
public CloseIgnoringInputStream(InputStream in) {
super( in );
}

@Override
public void close() {
// do nothing
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
/*
* JBoss, Home of Professional Open Source
* Copyright 2012, 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.test.internal.engine;

import java.io.InputStream;
import java.lang.annotation.ElementType;
import javax.validation.Configuration;
import javax.validation.Path;
import javax.validation.TraversableResolver;
import javax.validation.ValidationException;
import javax.validation.ValidatorFactory;

import org.testng.annotations.Test;

import org.hibernate.validator.HibernateValidatorConfiguration;
import org.hibernate.validator.testutil.TestForIssue;

import static org.hibernate.validator.testutil.ValidatorUtil.getConfiguration;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertNotSame;
import static org.testng.Assert.assertTrue;

/**
* @author Hardy Ferentschik
*/
public class ConfigurationImplTest {

@Test
@TestForIssue(jiraKey = "HV-563")
public void testCallBuildValidatorFactoryMultipleTimes() {
final Configuration<HibernateValidatorConfiguration> configuration = getConfiguration();

ValidatorFactory factory1 = configuration.buildValidatorFactory();
assertNotNull( factory1 );

ValidatorFactory factory2 = configuration.buildValidatorFactory();
assertNotNull( factory2 );

assertNotSame( factory1, factory2 );
}

@Test
@TestForIssue(jiraKey = "HV-563")
public void testConfigurationReusableAndMutable() {
final Configuration<HibernateValidatorConfiguration> configuration = getConfiguration();

ValidatorFactory factory1 = configuration.buildValidatorFactory();
assertNotNull( factory1 );

configuration.traversableResolver( new TestTraversableResolver() );
ValidatorFactory factory2 = configuration.buildValidatorFactory();
assertNotNull( factory2 );

assertNotSame( factory1.getTraversableResolver(), factory2.getTraversableResolver() );
assertTrue( factory2.getTraversableResolver() instanceof TestTraversableResolver );
}


@Test
@TestForIssue(jiraKey = "HV-563")
public void testReusableConfigurationWithInputStream() throws Exception {
final Configuration<HibernateValidatorConfiguration> configuration = getConfiguration();

InputStream mappingStream = ConfigurationImplTest.class.getResourceAsStream( "mapping.xml" );

try {
configuration.addMapping( mappingStream );
ValidatorFactory factory1 = configuration.buildValidatorFactory();
assertNotNull( factory1 );

ValidatorFactory factory2 = configuration.buildValidatorFactory();
assertNotNull( factory2 );

assertNotSame( factory1, factory2 );
}
finally {
mappingStream.close();
}
}

@Test(expectedExceptions = ValidationException.class, expectedExceptionsMessageRegExp = "HV000115.*")
@TestForIssue(jiraKey = "HV-563")
public void testReusableConfigurationWithClosedInputStream() throws Exception {
final Configuration<HibernateValidatorConfiguration> configuration = getConfiguration();

InputStream mappingStream = ConfigurationImplTest.class.getResourceAsStream( "mapping.xml" );

try {
configuration.addMapping( mappingStream );
ValidatorFactory factory1 = configuration.buildValidatorFactory();
assertNotNull( factory1 );
}
finally {
mappingStream.close();
}

configuration.buildValidatorFactory();
}

public class TestTraversableResolver implements TraversableResolver {

public boolean isReachable(Object traversableObject, Path.Node traversableProperty, Class<?> rootBeanType, Path pathToTraversableObject, ElementType elementType) {
return true;
}

public boolean isCascadable(Object traversableObject, Path.Node traversableProperty, Class<?> rootBeanType, Path pathToTraversableObject, ElementType elementType) {
return true;
}
}
}


Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import org.hibernate.validator.HibernateValidatorConfiguration;
import org.hibernate.validator.cfg.ConstraintMapping;
import org.hibernate.validator.cfg.defs.SizeDef;
import org.hibernate.validator.testutil.TestForIssue;
import org.hibernate.validator.testutil.ValidatorUtil;

import static org.hibernate.validator.testutil.ConstraintViolationAssert.assertCorrectConstraintViolationMessages;
Expand All @@ -45,9 +46,7 @@
public class XmlMappingTest {

@Test
/**
* HV-214
*/
@TestForIssue(jiraKey = "HV-214")
public void testConstraintInheritanceWithXmlConfiguration() {

final Configuration<?> configuration = ValidatorUtil.getConfiguration();
Expand All @@ -62,9 +61,7 @@ public void testConstraintInheritanceWithXmlConfiguration() {
}

@Test
/**
* HV-252
*/
@TestForIssue(jiraKey = "HV-252")
public void testListOfString() {

final Configuration<?> configuration = ValidatorUtil.getConfiguration();
Expand All @@ -86,9 +83,7 @@ public void testListOfString() {
}

@Test
/**
* HV-262
*/
@TestForIssue(jiraKey = "HV-262")
public void testInterfaceConfiguration() {

final Configuration<?> configuration = ValidatorUtil.getConfiguration();
Expand All @@ -102,9 +97,7 @@ public void testInterfaceConfiguration() {
}

@Test
/**
* HV-262
*/
@TestForIssue(jiraKey = "HV-262")
public void testInterfaceImplementationConfiguration() {

final Configuration<?> configuration = ValidatorUtil.getConfiguration();
Expand All @@ -118,9 +111,7 @@ public void testInterfaceImplementationConfiguration() {
}

@Test
/**
* HV-263
*/
@TestForIssue(jiraKey = "HV-263")
public void testEmptyInterfaceConfiguration() {

final Configuration<?> configuration = ValidatorUtil.getConfiguration();
Expand All @@ -133,10 +124,8 @@ public void testEmptyInterfaceConfiguration() {
assertEquals( violations.size(), 0 );
}

/**
* HV-480
*/
@Test
@TestForIssue(jiraKey = "HV-480")
public void testConstraintsFromXmlAndProgrammaticApiAddUp() {

//given
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<constraint-mappings
xmlns="http://jboss.org/xml/ns/javax/validation/mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=
"http://jboss.org/xml/ns/javax/validation/mapping validation-mapping-1.0.xsd">

<default-package>org.hibernate.validator.test.internal.engine</default-package>
</constraint-mappings>