Java tutorial
/* * Hibernate, Relational Persistence for Idiomatic Java * * Copyright (c) 2010, 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 com.mpe.common.validation; import java.util.HashSet; import java.util.Properties; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import javax.validation.ConstraintViolation; import javax.validation.ConstraintViolationException; import javax.validation.TraversableResolver; import javax.validation.Validation; import javax.validation.Validator; import javax.validation.ValidatorFactory; import org.hibernate.EntityMode; import org.hibernate.cfg.Configuration; import org.hibernate.cfg.beanvalidation.GroupsPerOperation; import org.hibernate.cfg.beanvalidation.HibernateTraversableResolver; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.event.spi.PreDeleteEvent; import org.hibernate.event.spi.PreDeleteEventListener; import org.hibernate.event.spi.PreInsertEvent; import org.hibernate.event.spi.PreInsertEventListener; import org.hibernate.event.spi.PreUpdateEvent; import org.hibernate.event.spi.PreUpdateEventListener; import org.hibernate.internal.CoreMessageLogger; import org.hibernate.persister.entity.EntityPersister; import org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator; import org.hibernate.validator.resourceloading.PlatformResourceBundleLocator; import org.jboss.logging.Logger; /** * Event listener used to enable Bean Validation for insert/update/delete events. * * @author Emmanuel Bernard * @author Hardy Ferentschik */ //FIXME review exception model public class BeanValidationEventListener implements PreInsertEventListener, PreUpdateEventListener, PreDeleteEventListener { //private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, BeanValidationEventListener.class.getName()); Logger logger = Logger.getLogger(this.getClass()); private ValidatorFactory factory; private ConcurrentHashMap<EntityPersister, Set<String>> associationsPerEntityPersister = new ConcurrentHashMap<EntityPersister, Set<String>>(); private GroupsPerOperation groupsPerOperation; boolean initialized; /** * No-arg constructor used when listener is configured via configuration file */ public BeanValidationEventListener() { } /** * Constructor used in an environment where validator factory is injected (JPA2). * * @param factory The {@code ValidatorFactory} to use to create {@code Validator} instance(s) * @param properties Configued properties */ public BeanValidationEventListener(ValidatorFactory factory, Properties properties) { init(factory, properties); } public void initialize(Configuration cfg) { if (!initialized) { ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); Properties props = cfg.getProperties(); init(factory, props); } } public boolean onPreInsert(PreInsertEvent event) { validate(event.getEntity(), event.getPersister().getEntityMode(), event.getPersister(), event.getSession().getFactory(), GroupsPerOperation.Operation.INSERT); return false; } public boolean onPreUpdate(PreUpdateEvent event) { validate(event.getEntity(), event.getPersister().getEntityMode(), event.getPersister(), event.getSession().getFactory(), GroupsPerOperation.Operation.UPDATE); return false; } public boolean onPreDelete(PreDeleteEvent event) { validate(event.getEntity(), event.getPersister().getEntityMode(), event.getPersister(), event.getSession().getFactory(), GroupsPerOperation.Operation.DELETE); return false; } private void init(ValidatorFactory factory, Properties properties) { this.factory = factory; groupsPerOperation = new GroupsPerOperation(properties); initialized = true; } private <T> void validate(T object, EntityMode mode, EntityPersister persister, SessionFactoryImplementor sessionFactory, GroupsPerOperation.Operation operation) { if (object == null || mode != EntityMode.POJO) { return; } TraversableResolver tr = new HibernateTraversableResolver(persister, associationsPerEntityPersister, sessionFactory); Validator validator = factory.usingContext() .messageInterpolator( new ResourceBundleMessageInterpolator(new PlatformResourceBundleLocator("globalMessages"))) .traversableResolver(tr).getValidator(); final Class<?>[] groups = groupsPerOperation.get(operation); if (groups.length > 0) { final Set<ConstraintViolation<T>> constraintViolations = validator.validate(object, groups); if (constraintViolations.size() > 0) { /*Set<ConstraintViolation<?>> propagatedViolations = new HashSet<ConstraintViolation<?>>( constraintViolations.size() ); Set<String> classNames = new HashSet<String>(); for ( ConstraintViolation<?> violation : constraintViolations ) { LOG.trace( violation ); propagatedViolations.add( violation ); classNames.add( violation.getLeafBean().getClass().getName() ); } StringBuilder builder = new StringBuilder(); builder.append( "Validation failed for classes " ); builder.append( classNames ); builder.append( " during " ); builder.append( operation.getName() ); builder.append( " time for groups " ); builder.append( toString( groups ) ); builder.append( "\nList of constraint violations:[\n" ); for (ConstraintViolation<?> violation : constraintViolations) { builder.append( "\t" ).append( violation.toString() ).append("\n"); } builder.append( "]" ); throw new ConstraintViolationException( builder.toString(), propagatedViolations );*/ Set<ConstraintViolation<?>> propagatedViolations = new HashSet<ConstraintViolation<?>>( constraintViolations.size()); StringBuilder builder = new StringBuilder(); for (ConstraintViolation<?> violation : constraintViolations) { builder.append(violation.getMessage()).append("\n"); } logger.info("CCC >> " + builder.toString()); throw new ConstraintViolationException(builder.toString(), propagatedViolations); } } } private String toString(Class<?>[] groups) { StringBuilder toString = new StringBuilder("["); for (Class<?> group : groups) { toString.append(group.getName()).append(", "); } toString.append("]"); return toString.toString(); } }