001    /*
002      GRANITE DATA SERVICES
003      Copyright (C) 2011 GRANITE DATA SERVICES S.A.S.
004    
005      This file is part of Granite Data Services.
006    
007      Granite Data Services is free software; you can redistribute it and/or modify
008      it under the terms of the GNU Library General Public License as published by
009      the Free Software Foundation; either version 2 of the License, or (at your
010      option) any later version.
011    
012      Granite Data Services is distributed in the hope that it will be useful, but
013      WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
014      FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
015      for more details.
016    
017      You should have received a copy of the GNU Library General Public License
018      along with this library; if not, see <http://www.gnu.org/licenses/>.
019    */
020    
021    package org.granite.tide.validation;
022    
023    import java.util.Set;
024    
025    import javax.naming.InitialContext;
026    import javax.naming.NamingException;
027    import javax.validation.ConstraintViolation;
028    import javax.validation.Validation;
029    import javax.validation.Validator;
030    import javax.validation.ValidatorFactory;
031    
032    import org.granite.logging.Logger;
033    import org.granite.tide.validators.EntityValidator;
034    import org.granite.tide.validators.InvalidValue;
035    
036    /**
037     * @author William DRAI
038     */
039    public class BeanValidation implements EntityValidator {
040            
041            private static final Logger log = Logger.getLogger(BeanValidation.class);
042        
043        private ValidatorFactory validatorFactory = null;
044        
045        
046        public BeanValidation() {
047            try {
048                    InitialContext ic = new InitialContext();
049                    this.validatorFactory = (ValidatorFactory)ic.lookup("java:comp/ValidatorFactory");
050            }
051            catch (NamingException e) {
052                    log.info("ValidatorFactory not found in JNDI, build default");
053                    this.validatorFactory = Validation.buildDefaultValidatorFactory();
054            }
055        }
056        
057        public BeanValidation(ValidatorFactory validatorFactory) {
058            this.validatorFactory = validatorFactory;
059        }
060        
061        
062        @SuppressWarnings("unchecked")
063        public InvalidValue[] getPotentialInvalidValues(Class<?> entityClass, String propertyName, Object value) {
064            Validator validator = validatorFactory.getValidator();
065            
066            Set<?> constraintViolations = validator.validateValue(entityClass, propertyName, value);
067            return convertConstraintViolations((Set<ConstraintViolation<?>>)constraintViolations);
068        }
069    
070    
071        public static InvalidValue[] convertConstraintViolations(Set<ConstraintViolation<?>> constraintViolations) {
072            InvalidValue[] converted = new org.granite.tide.validators.InvalidValue[constraintViolations.size()];
073            int i = 0;
074            for (ConstraintViolation<?> cv : constraintViolations) {
075                if (cv.getRootBean() == null) {
076                    converted[i++] = new InvalidValue(
077                        cv.getRootBeanClass(),
078                        cv.getPropertyPath().toString(),
079                        cv.getInvalidValue(),
080                        cv.getMessage()
081                    );
082                }
083                else {
084                    converted[i++] = new InvalidValue(
085                        cv.getRootBean(),
086                        cv.getLeafBean() != null ? cv.getLeafBean() : cv.getRootBean(),
087                        cv.getPropertyPath().toString(),
088                        cv.getInvalidValue(),
089                        cv.getMessage()
090                    );
091                }
092            }
093            return converted;
094        }
095    }