alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Hibernate example source code file (BeanValidationIntegrator.java)

This example Hibernate source code file (BeanValidationIntegrator.java) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Hibernate tags/keywords

activator_class, class, exception, exception, hibernateexception, hibernateexception, mode_property, mode_property, override, reflection, sessionfactoryserviceregistry, set, string, string, unable, util

The Hibernate BeanValidationIntegrator.java source code

/*
 * Hibernate, Relational Persistence for Idiomatic Java
 *
 * Copyright (c) 2011, Red Hat Inc. or third-party contributors as
 * indicated by the @author tags or express copyright attribution
 * statements applied by the authors.  All third-party contributions are
 * distributed under license by Red Hat Inc.
 *
 * This copyrighted material is made available to anyone wishing to use, modify,
 * copy, or redistribute it subject to the terms and conditions of the GNU
 * Lesser General Public License, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
 * for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this distribution; if not, write to:
 * Free Software Foundation, Inc.
 * 51 Franklin Street, Fifth Floor
 * Boston, MA  02110-1301  USA
 */
package org.hibernate.cfg.beanvalidation;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.HashSet;
import java.util.Properties;
import java.util.Set;

import org.jboss.logging.Logger;

import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.integrator.spi.Integrator;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.internal.util.config.ConfigurationHelper;
import org.hibernate.metamodel.source.MetadataImplementor;
import org.hibernate.service.classloading.spi.ClassLoaderService;
import org.hibernate.event.service.spi.EventListenerRegistry;
import org.hibernate.service.spi.SessionFactoryServiceRegistry;

/**
 * @author Steve Ebersole
 */
public class BeanValidationIntegrator implements Integrator {
	private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, BeanValidationIntegrator.class.getName());

	public static final String APPLY_CONSTRAINTS = "hibernate.validator.apply_to_ddl";

	public static final String BV_CHECK_CLASS = "javax.validation.Validation";

	public static final String MODE_PROPERTY = "javax.persistence.validation.mode";

	private static final String ACTIVATOR_CLASS = "org.hibernate.cfg.beanvalidation.TypeSafeActivator";
	private static final String DDL_METHOD = "applyDDL";
	private static final String ACTIVATE_METHOD = "activateBeanValidation";
	private static final String VALIDATE_METHOD = "validateFactory";

	public static void validateFactory(Object object) {
		try {
			final Class activatorClass = BeanValidationIntegrator.class.getClassLoader().loadClass( ACTIVATOR_CLASS );
			try {
				final Method validateMethod = activatorClass.getMethod( VALIDATE_METHOD, Object.class );
				if ( ! validateMethod.isAccessible() ) {
					validateMethod.setAccessible( true );
				}
				try {
					validateMethod.invoke( null, object );
				}
				catch (InvocationTargetException e) {
					if ( e.getTargetException() instanceof HibernateException ) {
						throw (HibernateException) e.getTargetException();
					}
					throw new HibernateException( "Unable to check validity of passed ValidatorFactory", e );
				}
				catch (IllegalAccessException e) {
					throw new HibernateException( "Unable to check validity of passed ValidatorFactory", e );
				}
			}
			catch (HibernateException e) {
				throw e;
			}
			catch (Exception e) {
				throw new HibernateException( "Could not locate method needed for ValidatorFactory validation", e );
			}
		}
		catch (HibernateException e) {
			throw e;
		}
		catch (Exception e) {
			throw new HibernateException( "Could not locate TypeSafeActivator class", e );
		}
	}

	@Override
	public void integrate(
			Configuration configuration,
			SessionFactoryImplementor sessionFactory,
			SessionFactoryServiceRegistry serviceRegistry) {
		// determine requested validation modes.
		final Set<ValidationMode> modes = ValidationMode.getModes( configuration.getProperties().get( MODE_PROPERTY ) );

		final ClassLoaderService classLoaderService = serviceRegistry.getService( ClassLoaderService.class );

		// try to locate a BV class to see if it is available on the classpath
		boolean isBeanValidationAvailable;
		try {
			classLoaderService.classForName( BV_CHECK_CLASS );
			isBeanValidationAvailable = true;
		}
		catch ( Exception e ) {
			isBeanValidationAvailable = false;
		}

		// locate the type safe activator class
		final Class typeSafeActivatorClass = loadTypeSafeActivatorClass( serviceRegistry );

		// todo : if this works out, probably better to simply alter TypeSafeActivator into a single method...

		applyRelationalConstraints(
				modes,
				isBeanValidationAvailable,
				typeSafeActivatorClass,
				configuration
		);
		applyHibernateListeners(
				modes,
				isBeanValidationAvailable,
				typeSafeActivatorClass,
				configuration,
				sessionFactory,
				serviceRegistry
		);
	}

	/**
	 * {@inheritDoc}
	 *
	 * @see org.hibernate.integrator.spi.Integrator#integrate(org.hibernate.metamodel.source.MetadataImplementor, org.hibernate.engine.spi.SessionFactoryImplementor, org.hibernate.service.spi.SessionFactoryServiceRegistry)
	 */
	@Override
	public void integrate( MetadataImplementor metadata,
	                       SessionFactoryImplementor sessionFactory,
	                       SessionFactoryServiceRegistry serviceRegistry ) {
//	    Properties props = sessionFactory.getProperties();
//        final Set<ValidationMode> modes = ValidationMode.getModes(props.get(MODE_PROPERTY));
//        final ClassLoaderService classLoaderService = serviceRegistry.getService( ClassLoaderService.class );
//        // try to locate a BV class to see if it is available on the classpath
//        boolean isBeanValidationAvailable;
//        try {
//            classLoaderService.classForName( BV_CHECK_CLASS );
//            isBeanValidationAvailable = true;
//        } catch (Exception error) {
//            isBeanValidationAvailable = false;
//        }
//        // locate the type safe activator class
//        final Class typeSafeActivatorClass = loadTypeSafeActivatorClass(serviceRegistry);
//        // todo : if this works out, probably better to simply alter TypeSafeActivator into a single method...
//        applyRelationalConstraints(modes, isBeanValidationAvailable, typeSafeActivatorClass, props, metadata);
//        applyHibernateListeners(modes, isBeanValidationAvailable, typeSafeActivatorClass, sessionFactory, serviceRegistry);
	}

	private Class loadTypeSafeActivatorClass(SessionFactoryServiceRegistry serviceRegistry) {
		try {
			return serviceRegistry.getService( ClassLoaderService.class ).classForName( ACTIVATOR_CLASS );
		}
		catch (Exception e) {
			return null;
		}
	}

	private void applyRelationalConstraints(
			Set<ValidationMode> modes,
			boolean beanValidationAvailable,
			Class typeSafeActivatorClass,
			Configuration configuration) {
		if ( ! ConfigurationHelper.getBoolean( APPLY_CONSTRAINTS, configuration.getProperties(), true ) ){
			LOG.debug( "Skipping application of relational constraints from legacy Hibernate Validator" );
			return;
		}

		if ( ! ( modes.contains( ValidationMode.DDL ) || modes.contains( ValidationMode.AUTO ) ) ) {
			return;
		}

		if ( ! beanValidationAvailable ) {
			if ( modes.contains( ValidationMode.DDL ) ) {
				throw new HibernateException( "Bean Validation not available in the class path but required in " + MODE_PROPERTY );
			}
			else if (modes.contains( ValidationMode.AUTO ) ) {
				//nothing to activate
				return;
			}
		}

		try {
			Method applyDDLMethod = typeSafeActivatorClass.getMethod( DDL_METHOD, Collection.class, Properties.class );
			try {
				applyDDLMethod.invoke(
						null,
						configuration.createMappings().getClasses().values(),
						configuration.getProperties()
				);
			}
			catch (HibernateException e) {
				throw e;
			}
			catch (Exception e) {
				throw new HibernateException( "Error applying BeanValidation relational constraints", e );
			}
		}
		catch (HibernateException e) {
			throw e;
		}
		catch (Exception e) {
			throw new HibernateException( "Unable to locate TypeSafeActivator#applyDDL method", e );
		}
	}

//    private void applyRelationalConstraints( Set<ValidationMode> modes,
//                                             boolean beanValidationAvailable,
//                                             Class typeSafeActivatorClass,
//                                             Properties properties,
//                                             MetadataImplementor metadata ) {
//        if (!ConfigurationHelper.getBoolean(APPLY_CONSTRAINTS, properties, true)){
//            LOG.debug("Skipping application of relational constraints from legacy Hibernate Validator");
//            return;
//        }
//        if (!(modes.contains(ValidationMode.DDL) || modes.contains(ValidationMode.AUTO))) return;
//        if (!beanValidationAvailable) {
//            if (modes.contains(ValidationMode.DDL))
//                throw new HibernateException("Bean Validation not available in the class path but required in " + MODE_PROPERTY);
//            if(modes.contains(ValidationMode.AUTO)) return; //nothing to activate
//        }
//        try {
//            Method applyDDLMethod = typeSafeActivatorClass.getMethod(DDL_METHOD, Iterable.class, Properties.class, ClassLoaderService.class);
//            try {
//                applyDDLMethod.invoke(null, metadata.getEntityBindings(), properties,
//                                      metadata.getServiceRegistry().getService(ClassLoaderService.class));
//            } catch (HibernateException error) {
//                throw error;
//            } catch (Exception error) {
//                throw new HibernateException("Error applying BeanValidation relational constraints", error);
//            }
//        } catch (HibernateException error) {
//            throw error;
//        } catch (Exception error) {
//            throw new HibernateException("Unable to locate TypeSafeActivator#applyDDL method", error);
//        }
//    }

	private void applyHibernateListeners(
			Set<ValidationMode> modes,
			boolean beanValidationAvailable,
			Class typeSafeActivatorClass,
			Configuration configuration,
			SessionFactoryImplementor sessionFactory,
			SessionFactoryServiceRegistry serviceRegistry) {
		// de-activate not-null tracking at the core level when Bean Validation is present unless the user explicitly
		// asks for it
		if ( configuration.getProperty( Environment.CHECK_NULLABILITY ) == null ) {
			sessionFactory.getSettings().setCheckNullability( false );
		}

		if ( ! ( modes.contains( ValidationMode.CALLBACK ) || modes.contains( ValidationMode.AUTO ) ) ) {
			return;
		}

		if ( ! beanValidationAvailable ) {
			if ( modes.contains( ValidationMode.CALLBACK ) ) {
				throw new HibernateException( "Bean Validation not available in the class path but required in " + MODE_PROPERTY );
			}
			else if (modes.contains( ValidationMode.AUTO ) ) {
				//nothing to activate
				return;
			}
		}

		try {
			Method activateMethod = typeSafeActivatorClass.getMethod( ACTIVATE_METHOD, EventListenerRegistry.class, Configuration.class );
			try {
				activateMethod.invoke(
						null,
						serviceRegistry.getService( EventListenerRegistry.class ),
						configuration
				);
			}
			catch (HibernateException e) {
				throw e;
			}
			catch (Exception e) {
				throw new HibernateException( "Error applying BeanValidation relational constraints", e );
			}
		}
		catch (HibernateException e) {
			throw e;
		}
		catch (Exception e) {
			throw new HibernateException( "Unable to locate TypeSafeActivator#applyDDL method", e );
		}
	}

//    private void applyHibernateListeners( Set<ValidationMode> modes,
//                                          boolean beanValidationAvailable,
//                                          Class typeSafeActivatorClass,
//                                          SessionFactoryImplementor sessionFactory,
//                                          SessionFactoryServiceRegistry serviceRegistry ) {
//        // de-activate not-null tracking at the core level when Bean Validation is present unless the user explicitly
//        // asks for it
//        if (sessionFactory.getProperties().getProperty(Environment.CHECK_NULLABILITY) == null)
//            sessionFactory.getSettings().setCheckNullability( false );
//        if (!(modes.contains( ValidationMode.CALLBACK) || modes.contains(ValidationMode.AUTO))) return;
//        if (!beanValidationAvailable) {
//            if (modes.contains(ValidationMode.CALLBACK))
//                throw new HibernateException("Bean Validation not available in the class path but required in " + MODE_PROPERTY);
//            if (modes.contains(ValidationMode.AUTO)) return; //nothing to activate
//        }
//        try {
//            Method activateMethod = typeSafeActivatorClass.getMethod(ACTIVATE_METHOD, EventListenerRegistry.class);
//            try {
//                activateMethod.invoke(null, serviceRegistry.getService(EventListenerRegistry.class));
//            }
//            catch (HibernateException e) {
//                throw e;
//            }
//            catch (Exception e) {
//                throw new HibernateException( "Error applying BeanValidation relational constraints", e );
//            }
//        }
//        catch (HibernateException e) {
//            throw e;
//        }
//        catch (Exception e) {
//            throw new HibernateException( "Unable to locate TypeSafeActivator#applyDDL method", e );
//        }
//    }

	// Because the javax validation classes might not be on the runtime classpath
	private static enum ValidationMode {
		AUTO,
		CALLBACK,
		NONE,
		DDL;

		public static Set<ValidationMode> getModes(Object modeProperty) {
			Set<ValidationMode> modes = new HashSet(3);
			if (modeProperty == null) {
				modes.add(ValidationMode.AUTO);
			}
			else {
				final String[] modesInString = modeProperty.toString().split( "," );
				for ( String modeInString : modesInString ) {
					modes.add( getMode(modeInString) );
				}
			}
			if ( modes.size() > 1 && ( modes.contains( ValidationMode.AUTO ) || modes.contains( ValidationMode.NONE ) ) ) {
				StringBuilder message = new StringBuilder( "Incompatible validation modes mixed: " );
				for (ValidationMode mode : modes) {
					message.append( mode ).append( ", " );
				}
				throw new HibernateException( message.substring( 0, message.length() - 2 ) );
			}
			return modes;
		}

		private static ValidationMode getMode(String modeProperty) {
			if (modeProperty == null || modeProperty.length() == 0) {
				return AUTO;
			}
			else {
				try {
					return valueOf( modeProperty.trim().toUpperCase() );
				}
				catch ( IllegalArgumentException e ) {
					throw new HibernateException( "Unknown validation mode in " + MODE_PROPERTY + ": " + modeProperty );
				}
			}
		}
	}

	@Override
	public void disintegrate(SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry) {
		// nothing to do here afaik
	}
}

Other Hibernate examples (source code examples)

Here is a short list of links related to this Hibernate BeanValidationIntegrator.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.