001 /*
002 GRANITE DATA SERVICES
003 Copyright (C) 2012 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.client.tide.data;
022
023 import java.util.HashMap;
024 import java.util.HashSet;
025 import java.util.Map;
026 import java.util.Set;
027
028 import javax.validation.ConstraintViolation;
029
030 import org.granite.client.messaging.messages.responses.FaultMessage;
031 import org.granite.client.messaging.messages.responses.FaultMessage.Code;
032 import org.granite.client.tide.Context;
033 import org.granite.client.tide.server.ExceptionHandler;
034 import org.granite.client.tide.server.TideFaultEvent;
035 import org.granite.client.validation.InvalidValue;
036 import org.granite.client.validation.ServerConstraintViolation;
037
038 /**
039 * @author William DRAI
040 */
041 public class ValidationExceptionHandler implements ExceptionHandler {
042
043 @Override
044 public boolean accepts(FaultMessage emsg) {
045 return emsg.getCode().equals(Code.VALIDATION_FAILED);
046 }
047
048 @Override
049 public void handle(Context context, FaultMessage emsg, TideFaultEvent faultEvent) {
050 Object[] invalidValues = emsg.getExtended() != null ? (Object[])emsg.getExtended().get("invalidValues") : null;
051 if (invalidValues != null) {
052 Map<Object, Set<ConstraintViolation<?>>> violationsMap = new HashMap<Object, Set<ConstraintViolation<?>>>();
053 for (Object v : invalidValues) {
054 InvalidValue iv = (InvalidValue)v;
055 Object rootBean = context.getEntityManager().getCachedObject(iv.getRootBean(), true);
056 Object leafBean = null;
057 if (iv.getBean() != null) {
058 leafBean = context.getEntityManager().getCachedObject(iv.getBean(), true);
059 if (leafBean == null) {
060 // Embedded ?
061 Object bean = rootBean;
062 String[] path = iv.getPath().split("\\.");
063 for (int i = 0; i < path.length-1; i++)
064 bean = context.getDataManager().getProperty(bean, path[i]);
065 leafBean = bean;
066 }
067 }
068 Object bean = leafBean != null ? leafBean : rootBean;
069
070 Set<ConstraintViolation<?>> violations = violationsMap.get(bean);
071 if (violations == null) {
072 violations = new HashSet<ConstraintViolation<?>>();
073 violationsMap.put(bean, violations);
074 }
075
076 ServerConstraintViolation violation = new ServerConstraintViolation(iv, rootBean, leafBean);
077 violations.add(violation);
078 }
079
080 for (Object bean : violationsMap.keySet())
081 context.getDataManager().notifyConstraintViolations(bean, violationsMap.get(bean));
082 }
083 }
084
085 }