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.lang.reflect.Array; 038import java.util.Set; 039 040import javax.validation.ConstraintViolation; 041 042import org.granite.client.util.WeakIdentityHashMap; 043import org.granite.client.validation.NotifyingValidator.ConstraintViolationsHandler; 044 045/** 046 * @author William DRAI 047 */ 048public class ValidationNotifier { 049 050 private final WeakIdentityHashMap<Object, ConstraintViolationsHandler<?>[]> handlersMap = new WeakIdentityHashMap<Object, ConstraintViolationsHandler<?>[]>(); 051 052 053 public <T> void notifyConstraintViolations(T entity, Set<ConstraintViolation<T>> constraintViolations) { 054 @SuppressWarnings("unchecked") 055 ConstraintViolationsHandler<T>[] handlers = (ConstraintViolationsHandler<T>[])handlersMap.get(entity); 056 if (handlers == null) 057 return; 058 059 for (ConstraintViolationsHandler<T> handler : handlers) 060 handler.handle(entity, constraintViolations); 061 } 062 063 @SuppressWarnings("unchecked") 064 public <T> void addConstraintViolationsHandler(T entity, ConstraintViolationsHandler<T> handler) { 065 ConstraintViolationsHandler<T>[] handlers = (ConstraintViolationsHandler<T>[])handlersMap.get(entity); 066 if (handlers == null) { 067 handlers = (ConstraintViolationsHandler<T>[])Array.newInstance(ConstraintViolationsHandler.class, 1); 068 handlers[0] = handler; 069 } 070 else { 071 ConstraintViolationsHandler<T>[] newHandlers = (ConstraintViolationsHandler<T>[])Array.newInstance(ConstraintViolationsHandler.class, handlers.length+1); 072 System.arraycopy(handlers, 0, newHandlers, 0, handlers.length); 073 newHandlers[handlers.length] = handler; 074 handlers = newHandlers; 075 } 076 handlersMap.put(entity, handlers); 077 } 078 079 public <T> void removeConstraintViolationsHandler(T entity, ConstraintViolationsHandler<T> handler) { 080 @SuppressWarnings("unchecked") 081 ConstraintViolationsHandler<T>[] handlers = (ConstraintViolationsHandler<T>[])handlersMap.get(entity); 082 if (handlers == null) 083 return; 084 if (handlers.length == 1 && handlers[0] == handler) { 085 handlersMap.remove(entity); 086 return; 087 } 088 int index = -1; 089 for (int i = 0; i < handlers.length; i++) { 090 if (handlers[i] == handler) { 091 index = i; 092 break; 093 } 094 } 095 if (index < 0) 096 return; // Handler not found 097 098 @SuppressWarnings({"rawtypes", "unchecked"}) 099 ConstraintViolationsHandler[] newHandlers = (ConstraintViolationsHandler<T>[])Array.newInstance(ConstraintViolationsHandler.class, handlers.length-1); 100 if (index > 0) 101 System.arraycopy(handlers, 0, newHandlers, 0, index); 102 if (index < handlers.length-1) 103 System.arraycopy(handlers, index+1, newHandlers, index, handlers.length-index-1); 104 handlersMap.put(entity, newHandlers); 105 } 106 107 108}