All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.bval.jsr303.xml.ValidationParser Maven / Gradle / Ivy

There is a newer version: 4.0.0
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.apache.bval.jsr303.xml;


import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Enumeration;

import javax.validation.ConstraintValidatorFactory;
import javax.validation.MessageInterpolator;
import javax.validation.TraversableResolver;
import javax.validation.ValidationException;
import javax.validation.spi.ValidationProvider;
import javax.xml.XMLConstants;
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.apache.bval.jsr303.ConfigurationImpl;
import org.apache.bval.jsr303.util.IOUtils;
import org.apache.bval.jsr303.util.SecureActions;
import org.apache.bval.util.PrivilegedActions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.SAXException;

/**
 * Description: uses jaxb to parse validation.xml
*/ @SuppressWarnings("restriction") public class ValidationParser { private static final String DEFAULT_VALIDATION_XML_FILE = "META-INF/validation.xml"; private static final String VALIDATION_CONFIGURATION_XSD = "META-INF/validation-configuration-1.0.xsd"; private static final Logger log = LoggerFactory.getLogger(ValidationParser.class); private final String validationXmlFile; /** * Create a new ValidationParser instance. * @param file */ public ValidationParser(String file) { if(file == null) { validationXmlFile = DEFAULT_VALIDATION_XML_FILE; } else { validationXmlFile = file; } } /** * Process the validation configuration into targetConfig. * @param targetConfig */ public void processValidationConfig(ConfigurationImpl targetConfig) { ValidationConfigType xmlConfig = parseXmlConfig(); if (xmlConfig != null) { applyConfig(xmlConfig, targetConfig); } } private ValidationConfigType parseXmlConfig() { InputStream inputStream = null; try { inputStream = getInputStream(validationXmlFile); if (inputStream == null) { log.debug("No {} found. Using annotation based configuration only.", validationXmlFile); return null; } log.debug("{} found.", validationXmlFile); Schema schema = getSchema(); JAXBContext jc = JAXBContext.newInstance(ValidationConfigType.class); Unmarshaller unmarshaller = jc.createUnmarshaller(); unmarshaller.setSchema(schema); StreamSource stream = new StreamSource(inputStream); JAXBElement root = unmarshaller.unmarshal(stream, ValidationConfigType.class); return root.getValue(); } catch (JAXBException e) { throw new ValidationException("Unable to parse " + validationXmlFile, e); } catch (IOException e) { throw new ValidationException("Unable to parse " + validationXmlFile, e); } finally { IOUtils.closeQuietly(inputStream); } } private InputStream getInputStream(String path) throws IOException { ClassLoader loader = PrivilegedActions.getClassLoader(getClass()); InputStream inputStream = loader.getResourceAsStream( path ); if ( inputStream != null ) { // spec says: If more than one META-INF/validation.xml file // is found in the classpath, a ValidationException is raised. if ( path.equals("META-INF/validation.xml") ) { Enumeration urls = loader.getResources(path); if ( urls.hasMoreElements() && (urls.nextElement() != null) && urls.hasMoreElements() ) { throw new ValidationException("More than one " + path + " is found in the classpath"); } } } return inputStream; } private Schema getSchema() { return getSchema(VALIDATION_CONFIGURATION_XSD); } /** * Get a Schema object from the specified resource name. * @param xsd * @return {@link Schema} */ static Schema getSchema(String xsd) { ClassLoader loader = PrivilegedActions.getClassLoader(ValidationParser.class); SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); URL schemaUrl = loader.getResource(xsd); try { return sf.newSchema(schemaUrl); } catch (SAXException e) { log.warn("Unable to parse schema: " + xsd, e); return null; } } private void applyConfig(ValidationConfigType xmlConfig, ConfigurationImpl targetConfig) { applyProviderClass(xmlConfig, targetConfig); applyMessageInterpolator(xmlConfig, targetConfig); applyTraversableResolver(xmlConfig, targetConfig); applyConstraintFactory(xmlConfig, targetConfig); applyMappingStreams(xmlConfig, targetConfig); applyProperties(xmlConfig, targetConfig); } private void applyProperties(ValidationConfigType xmlConfig, ConfigurationImpl target) { for (PropertyType property : xmlConfig.getProperty()) { if (log.isDebugEnabled()) { log.debug("Found property '" + property.getName() + "' with value '" + property.getValue() + "' in " + validationXmlFile); } target.addProperty(property.getName(), property.getValue()); } } @SuppressWarnings("unchecked") private void applyProviderClass(ValidationConfigType xmlConfig, ConfigurationImpl target) { String providerClassName = xmlConfig.getDefaultProvider(); if (providerClassName != null) { Class> clazz = (Class>) SecureActions .loadClass(providerClassName, this.getClass()); target.setProviderClass(clazz); log.info("Using {} as validation provider.", providerClassName); } } @SuppressWarnings("unchecked") private void applyMessageInterpolator(ValidationConfigType xmlConfig, ConfigurationImpl target) { String messageInterpolatorClass = xmlConfig.getMessageInterpolator(); if ( target.getMessageInterpolator() == null ) { if (messageInterpolatorClass != null) { Class clazz = (Class) SecureActions .loadClass(messageInterpolatorClass, this.getClass()); target.messageInterpolator(SecureActions.newInstance(clazz)); log.info("Using {} as message interpolator.", messageInterpolatorClass); } } } @SuppressWarnings("unchecked") private void applyTraversableResolver(ValidationConfigType xmlConfig, ConfigurationImpl target) { String traversableResolverClass = xmlConfig.getTraversableResolver(); if ( target.getTraversableResolver() == null ) { if (traversableResolverClass != null) { Class clazz = (Class) SecureActions .loadClass(traversableResolverClass, this.getClass()); target.traversableResolver(SecureActions.newInstance(clazz)); log.info("Using {} as traversable resolver.", traversableResolverClass); } } } @SuppressWarnings("unchecked") private void applyConstraintFactory(ValidationConfigType xmlConfig, ConfigurationImpl target) { String constraintFactoryClass = xmlConfig.getConstraintValidatorFactory(); if ( target.getConstraintValidatorFactory() == null ) { if (constraintFactoryClass != null) { Class clazz = (Class) SecureActions .loadClass(constraintFactoryClass, this.getClass()); target.constraintValidatorFactory(SecureActions.newInstance(clazz)); log.info("Using {} as constraint factory.", constraintFactoryClass); } } } private void applyMappingStreams(ValidationConfigType xmlConfig, ConfigurationImpl target) { for (JAXBElement mappingFileNameElement : xmlConfig.getConstraintMapping()) { String mappingFileName = mappingFileNameElement.getValue(); if ( mappingFileName.startsWith("/") ) { // Classloader needs a path without a starting / mappingFileName = mappingFileName.substring(1); } log.debug("Trying to open input stream for {}", mappingFileName); InputStream in = null; try { in = getInputStream(mappingFileName); if (in == null) { throw new ValidationException( "Unable to open input stream for mapping file " + mappingFileName); } } catch (IOException e) { throw new ValidationException("Unable to open input stream for mapping file " + mappingFileName, e); } target.addMapping(in); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy