/******************************************************************************* * Copyright (c) 2009, 2016 Oracle, Inc. All rights reserved. * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 * which accompanies this distribution. * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html * and the Eclipse Distribution License is available at * http://www.eclipse.org/org/documents/edl-v10.php. * * Contributors: * 08/01/2012-2.5 Chris Delahunt * - 371950: Metadata caching ******************************************************************************/ package org.eclipse.persistence.internal.jpa.deployment; import java.security.AccessController; import java.security.PrivilegedActionException; import java.util.Map; import javax.validation.Validation; import javax.validation.ValidatorFactory; import org.eclipse.persistence.config.PersistenceUnitProperties; import org.eclipse.persistence.descriptors.ClassDescriptor; import org.eclipse.persistence.exceptions.PersistenceUnitLoadingException; import org.eclipse.persistence.internal.jpa.metadata.listeners.BeanValidationListener; import org.eclipse.persistence.internal.security.PrivilegedAccessHelper; import org.eclipse.persistence.internal.security.PrivilegedClassForName; import org.eclipse.persistence.internal.sessions.AbstractSession; /** * Responsible for intialializing Bean Validation. The only expected instance of this interface is the inner class. * @author Mitesh Meswani */ public interface BeanValidationInitializationHelper { public void bootstrapBeanValidation(Map puProperties, AbstractSession session, ClassLoader appClassLoader); static class BeanValidationInitializationHelperImpl implements BeanValidationInitializationHelper { @Override public void bootstrapBeanValidation(Map puProperties, AbstractSession session, ClassLoader appClassLoader) { ValidatorFactory validatorFactory = getValidatorFactory(puProperties); //Check user/environment has specified the validator factory if (validatorFactory != null) { // We could obtain a validator factory => Bean Validation API is available at runtime. It is ok to cast now ValidatorFactory beanValidatorFactory = validatorFactory; Class[] groupPrePersit = translateValidationGroups( (String) puProperties.get(PersistenceUnitProperties.VALIDATION_GROUP_PRE_PERSIST), appClassLoader) ; Class[] groupPreUpdate = translateValidationGroups( (String) puProperties.get(PersistenceUnitProperties.VALIDATION_GROUP_PRE_UPDATE), appClassLoader); Class[] groupPreRemove = translateValidationGroups( (String) puProperties.get(PersistenceUnitProperties.VALIDATION_GROUP_PRE_REMOVE), appClassLoader); BeanValidationListener validationListener = new BeanValidationListener(beanValidatorFactory, groupPrePersit, groupPreUpdate, groupPreRemove); //Install BeanValidationListener on the desc for (ClassDescriptor descriptor : session.getProject().getOrderedDescriptors()) { if (descriptor.isDescriptorTypeNormal()) { //add only to entities descriptor.getEventManager().addInternalListener(validationListener); } } } } /** * INTERNAL: * @param puProperties merged properties for this persitence unit * @return ValidatorFactory instance to be used for this persistence unit. */ private ValidatorFactory getValidatorFactory(Map puProperties) { ValidatorFactory validatorFactory = (ValidatorFactory)puProperties.get(PersistenceUnitProperties.VALIDATOR_FACTORY); if (validatorFactory == null) { validatorFactory = Validation.buildDefaultValidatorFactory(); } return validatorFactory; } /** * INTERNAL: * translate validation group specified as fully qualifed class names deliminated by ',' into Class[] * @param validationGroups Array of "," deliminated fully qualified class names * @param appClassLoader The classloader for application * @return Array of classes corresponding to classnames in given <code>validationGroups</code>. * <code>null<code> if given <code>validationGroups</code> is null or empty */ private Class[] translateValidationGroups(String validationGroups, ClassLoader appClassLoader) { Class[] validationGroupsClasses = null; if(validationGroups != null && validationGroups.length() != 0 ) { String[] validationGroupClassNames = validationGroups.split(","); validationGroupsClasses = new Class[validationGroupClassNames.length]; for(int i = 0; i < validationGroupClassNames.length; i++) { String validationGroupClassName = validationGroupClassNames[i]; try { validationGroupsClasses[i] = loadClass(validationGroupClassName, appClassLoader); } catch (Exception e) { throw PersistenceUnitLoadingException.exceptionLoadingClassWhileInitializingValidationGroups(validationGroupClassName, e); } } } return validationGroupsClasses; } /** * Internal: * Helper to load class. * Please do not make this method protected or public else it would expose a security hole that would * allow malicious code to use this method to load any class without security permission * @param className Fully qualified class name * @param classLoader ClassLoader to be used for loading the class * @return Loaded Class * @throws java.security.PrivilegedActionException * @throws ClassNotFoundException */ private Class loadClass(String className, ClassLoader classLoader) throws PrivilegedActionException, ClassNotFoundException { Class loadedClass = null; if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()) { loadedClass = AccessController.doPrivileged( new PrivilegedClassForName(className, true, classLoader)); } else { loadedClass = PrivilegedAccessHelper.getClassForName(className, true, classLoader); } return loadedClass; } } }