org.hibernate.validator.internal.xml.MetaConstraintBuilder Maven / Gradle / Ivy
/*
* JBoss, Home of Professional Open Source
* Copyright 2013, 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.internal.xml;
import java.io.Serializable;
import java.lang.annotation.Annotation;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.util.List;
import javax.validation.Payload;
import javax.validation.ValidationException;
import javax.xml.bind.JAXBElement;
import org.hibernate.validator.internal.metadata.core.ConstraintHelper;
import org.hibernate.validator.internal.metadata.core.ConstraintOrigin;
import org.hibernate.validator.internal.metadata.core.MetaConstraint;
import org.hibernate.validator.internal.metadata.descriptor.ConstraintDescriptorImpl;
import org.hibernate.validator.internal.metadata.location.ConstraintLocation;
import org.hibernate.validator.internal.util.ReflectionHelper;
import org.hibernate.validator.internal.util.annotationfactory.AnnotationDescriptor;
import org.hibernate.validator.internal.util.annotationfactory.AnnotationFactory;
import org.hibernate.validator.internal.util.logging.Log;
import org.hibernate.validator.internal.util.logging.LoggerFactory;
import static org.hibernate.validator.internal.util.CollectionHelper.newArrayList;
/**
* Build meta constraint from XML
*
* @author Hardy Ferentschik
*/
public class MetaConstraintBuilder {
private static final Log log = LoggerFactory.make();
private static final String MESSAGE_PARAM = "message";
private static final String GROUPS_PARAM = "groups";
private static final String PAYLOAD_PARAM = "payload";
private MetaConstraintBuilder() {
}
@SuppressWarnings("unchecked")
public static MetaConstraint buildMetaConstraint(ConstraintLocation constraintLocation,
ConstraintType constraint,
java.lang.annotation.ElementType type,
String defaultPackage,
ConstraintHelper constraintHelper) {
Class annotationClass;
try {
annotationClass = (Class) ReflectionHelper.loadClass( constraint.getAnnotation(), defaultPackage );
}
catch ( ValidationException e ) {
throw log.getUnableToLoadConstraintAnnotationClassException( constraint.getAnnotation(), e );
}
AnnotationDescriptor annotationDescriptor = new AnnotationDescriptor( annotationClass );
if ( constraint.getMessage() != null ) {
annotationDescriptor.setValue( MESSAGE_PARAM, constraint.getMessage() );
}
annotationDescriptor.setValue( GROUPS_PARAM, getGroups( constraint.getGroups(), defaultPackage ) );
annotationDescriptor.setValue( PAYLOAD_PARAM, getPayload( constraint.getPayload(), defaultPackage ) );
for ( ElementType elementType : constraint.getElement() ) {
String name = elementType.getName();
checkNameIsValid( name );
Class returnType = getAnnotationParameterType( annotationClass, name );
Object elementValue = getElementValue( elementType, returnType, defaultPackage );
annotationDescriptor.setValue( name, elementValue );
}
A annotation;
try {
annotation = AnnotationFactory.create( annotationDescriptor );
}
catch ( RuntimeException e ) {
throw log.getUnableToCreateAnnotationForConfiguredConstraintException( e );
}
// we set initially ConstraintOrigin.DEFINED_LOCALLY for all xml configured constraints
// later we will make copies of this constraint descriptor when needed and adjust the ConstraintOrigin
ConstraintDescriptorImpl constraintDescriptor = new ConstraintDescriptorImpl(
constraintLocation.getMember(), annotation, constraintHelper, type, ConstraintOrigin.DEFINED_LOCALLY
);
return new MetaConstraint( constraintDescriptor, constraintLocation );
}
private static Annotation buildAnnotation(AnnotationType annotationType, Class returnType, String defaultPackage) {
AnnotationDescriptor annotationDescriptor = new AnnotationDescriptor( returnType );
for ( ElementType elementType : annotationType.getElement() ) {
String name = elementType.getName();
Class parameterType = getAnnotationParameterType( returnType, name );
Object elementValue = getElementValue( elementType, parameterType, defaultPackage );
annotationDescriptor.setValue( name, elementValue );
}
return AnnotationFactory.create( annotationDescriptor );
}
private static void checkNameIsValid(String name) {
if ( MESSAGE_PARAM.equals( name ) || GROUPS_PARAM.equals( name ) ) {
throw log.getReservedParameterNamesException( MESSAGE_PARAM, GROUPS_PARAM, PAYLOAD_PARAM );
}
}
private static Class getAnnotationParameterType(Class annotationClass, String name) {
Method m = ReflectionHelper.getMethod( annotationClass, name );
if ( m == null ) {
throw log.getAnnotationDoesNotContainAParameterException( annotationClass.getName(), name );
}
return m.getReturnType();
}
private static Object getElementValue(ElementType elementType, Class returnType, String defaultPackage) {
removeEmptyContentElements( elementType );
boolean isArray = returnType.isArray();
if ( !isArray ) {
if ( elementType.getContent().size() != 1 ) {
throw log.getAttemptToSpecifyAnArrayWhereSingleValueIsExpectedException();
}
return getSingleValue( elementType.getContent().get( 0 ), returnType, defaultPackage );
}
else {
List