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.seam;
022    
023    import javax.faces.application.FacesMessage;
024    import javax.faces.context.FacesContext;
025    
026    import org.granite.logging.Logger;
027    import org.granite.messaging.service.DefaultServiceExceptionHandler;
028    import org.granite.messaging.service.ServiceException;
029    import org.granite.messaging.service.ServiceInvocationContext;
030    import org.granite.messaging.service.security.SecurityServiceException;
031    import org.hibernate.validator.InvalidStateException;
032    import org.hibernate.validator.InvalidValue;
033    
034    /**
035     * @author Venkat DANDA
036     * @author Cameron INGRAM
037     *
038     * Update services-config.xml to use the seam service exception handler
039     * <factory id="seamFactory" class="org.granite.seam.SeamServiceFactory" >
040     *      <properties>
041     *              <service-exception-handler>org.granite.seam.SeamServiceExceptionHandler</service-exception-handler>
042     *      </properties>
043     * </factory>
044     */
045    public class SeamServiceExceptionHandler extends DefaultServiceExceptionHandler {
046    
047        private static final long serialVersionUID = -929771583032427716L;
048            private static final Logger log = Logger.getLogger(SeamServiceExceptionHandler.class);
049    
050        public SeamServiceExceptionHandler() {
051            this(true);
052        }
053    
054        public SeamServiceExceptionHandler(boolean logException) {
055                    super(logException);
056            }
057    
058        @Override
059        public ServiceException handleInvocationException(ServiceInvocationContext context, Throwable t) {
060            try {
061                while ((!(t instanceof InvalidStateException) && (t.getCause() != null)))
062                    t = t.getCause();
063    
064                if (t instanceof InvalidStateException) {
065                    InvalidStateException ise = (InvalidStateException)t;
066                    InvalidValue[] temp = ise.getInvalidValues();
067                    if (temp != null && temp.length > 0) {
068                                            for (int i = 0; i < temp.length; i++)
069                                                    FacesContext.getCurrentInstance().addMessage(temp[i].getPropertyName(), new FacesMessage(temp[i].getMessage()));
070                                    }
071                }
072            }
073            catch(Exception e) {
074                log.error(e, "Could not add FacesMessage for exception: %s", t);
075            }
076    
077            if (t instanceof SecurityServiceException)
078                log.debug(t, "Could not process remoting message: %s", context.getMessage());
079            else
080                log.error(t, "Could not process remoting message: %s", context.getMessage());
081    
082            
083            return getServiceException(context, t);
084        }
085    
086    }