001/** 002 * GRANITE DATA SERVICES 003 * Copyright (C) 2006-2013 GRANITE DATA SERVICES S.A.S. 004 * 005 * This file is part of the Granite Data Services Platform. 006 * 007 * *** 008 * 009 * Community License: GPL 3.0 010 * 011 * This file is free software: you can redistribute it and/or modify 012 * it under the terms of the GNU General Public License as published 013 * by the Free Software Foundation, either version 3 of the License, 014 * or (at your option) any later version. 015 * 016 * This file is distributed in the hope that it will be useful, but 017 * WITHOUT ANY WARRANTY; without even the implied warranty of 018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 019 * GNU General Public License for more details. 020 * 021 * You should have received a copy of the GNU General Public License 022 * along with this program. If not, see <http://www.gnu.org/licenses/>. 023 * 024 * *** 025 * 026 * Available Commercial License: GraniteDS SLA 1.0 027 * 028 * This is the appropriate option if you are creating proprietary 029 * applications and you are not prepared to distribute and share the 030 * source code of your application under the GPL v3 license. 031 * 032 * Please visit http://www.granitedataservices.com/license for more 033 * details. 034 */ 035package org.granite.client.validation; 036 037import java.util.HashMap; 038import java.util.HashSet; 039import java.util.Map; 040import java.util.Set; 041 042import javax.validation.ConstraintViolation; 043import javax.validation.Validator; 044import javax.validation.metadata.BeanDescriptor; 045 046/** 047 * @author William DRAI 048 */ 049public class DefaultNotifyingValidator implements NotifyingValidator { 050 051 private final Validator validator; 052 private final ValidationNotifier validationNotifier; 053 054 public DefaultNotifyingValidator(Validator validator, ValidationNotifier validationNotifier) { 055 this.validator = validator; 056 this.validationNotifier = validationNotifier; 057 } 058 059 @Override 060 public <T> Set<ConstraintViolation<T>> validate(T object, Class<?>... groups) { 061 Set<ConstraintViolation<T>> constraintViolations = validator.validate(object, groups); 062 063 Set<ConstraintViolation<?>> genericsAreAPainInTheAss = new HashSet<ConstraintViolation<?>>(constraintViolations.size()); 064 genericsAreAPainInTheAss.addAll(constraintViolations); 065 066 notifyConstraintViolations(object, genericsAreAPainInTheAss); 067 068 return constraintViolations; 069 } 070 071 @SuppressWarnings("unchecked") 072 public <T> void notifyConstraintViolations(T root, Set<ConstraintViolation<?>> constraintViolations) { 073 Map<Object, Set<ConstraintViolation<Object>>> violationsMap = new HashMap<Object, Set<ConstraintViolation<Object>>>(); 074 075 for (ConstraintViolation<?> violation : constraintViolations) { 076 Object rootBean = violation.getRootBean(); 077 Object leafBean = violation.getLeafBean(); 078 Object bean = leafBean != null ? leafBean : rootBean; 079 080 Set<ConstraintViolation<Object>> violations = violationsMap.get(bean); 081 if (violations == null) { 082 violations = new HashSet<ConstraintViolation<Object>>(); 083 violationsMap.put(bean, violations); 084 } 085 violations.add((ConstraintViolation<Object>)violation); 086 } 087 088 for (Object bean : violationsMap.keySet()) { 089 if (bean != root) 090 validationNotifier.notifyConstraintViolations(bean, violationsMap.get(bean)); 091 } 092 093 validationNotifier.notifyConstraintViolations(root, violationsMap.get(root)); 094 } 095 096 @Override 097 public <T> Set<ConstraintViolation<T>> validateProperty(T object, String propertyName, Class<?>... groups) { 098 return validator.validateProperty(object, propertyName, groups); 099 } 100 101 @Override 102 public <T> Set<ConstraintViolation<T>> validateValue(Class<T> beanType, String propertyName, Object value, Class<?>... groups) { 103 return validator.validateValue(beanType, propertyName, value, groups); 104 } 105 106 @Override 107 public BeanDescriptor getConstraintsForClass(Class<?> entityClass) { 108 return validator.getConstraintsForClass(entityClass); 109 } 110 111 @Override 112 public <T> T unwrap(Class<T> entityClass) { 113 return validator.unwrap(entityClass); 114 } 115 116 117 @Override 118 public <T> void addConstraintViolationsHandler(T entity, ConstraintViolationsHandler<T> handler) { 119 validationNotifier.addConstraintViolationsHandler(entity, handler); 120 } 121 122 @Override 123 public <T> void removeConstraintViolationsHandler(T entity, ConstraintViolationsHandler<T> handler) { 124 validationNotifier.removeConstraintViolationsHandler(entity, handler); 125 } 126 127 128}