001/* 002 * (C) Copyright 2006-2009 Nuxeo SA (http://nuxeo.com/) and contributors. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the GNU Lesser General Public License 006 * (LGPL) version 2.1 which accompanies this distribution, and is available at 007 * http://www.gnu.org/licenses/lgpl.html 008 * 009 * This library is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 012 * Lesser General Public License for more details. 013 * 014 * Contributors: 015 * Thierry Delprat 016 */ 017package org.nuxeo.ecm.platform.ui.web.util; 018 019import java.util.Map; 020 021import javax.faces.event.PhaseId; 022 023import org.jboss.seam.Component; 024import org.jboss.seam.annotations.intercept.Interceptor; 025import org.jboss.seam.contexts.FacesLifecycle; 026import org.jboss.seam.faces.FacesMessages; 027import org.jboss.seam.intercept.AbstractInterceptor; 028import org.jboss.seam.intercept.InvocationContext; 029import org.jboss.seam.international.StatusMessage.Severity; 030import org.nuxeo.common.utils.ExceptionUtils; 031import org.nuxeo.ecm.core.api.RecoverableClientException; 032import org.nuxeo.ecm.platform.web.common.exceptionhandling.ExceptionHelper; 033 034/** 035 * Intercepts Seam Bean call during the INVOKE_APPLICATION phase to see if a {@link RecoverableClientException} is 036 * raised. If this is the case, the INVOKE call returns null and the associated FacesMessage is generated. 037 * 038 * @author <a href="mailto:tdelprat@nuxeo.com">Tiry</a> 039 * @since 5.6 040 */ 041@Interceptor 042public class NuxeoExceptionInterceptor extends AbstractInterceptor { 043 044 private static final long serialVersionUID = 1L; 045 046 protected PhaseId getPhase() { 047 return FacesLifecycle.getPhaseId(); 048 } 049 050 protected Severity getSeverity(RecoverableClientException ce) { 051 if (ce.getSeverity() == RecoverableClientException.Severity.WARN) { 052 return Severity.WARN; 053 } else if (ce.getSeverity() == RecoverableClientException.Severity.FATAL) { 054 return Severity.FATAL; 055 } 056 return Severity.ERROR; 057 } 058 059 protected String getI18nMessage(String messageKey) { 060 @SuppressWarnings("unchecked") 061 Map<String, String> messages = (Map<String, String>) Component.getInstance( 062 "org.jboss.seam.international.messages", true); 063 064 if (messages == null) { 065 return messageKey; 066 } 067 String i18nMessage = messages.get(messageKey); 068 if (i18nMessage != null) { 069 return i18nMessage; 070 } else { 071 return messageKey; 072 } 073 } 074 075 @Override 076 public Object aroundInvoke(InvocationContext invocationContext) throws Exception { // stupid Seam API 077 try { 078 return invocationContext.proceed(); 079 } catch (Exception t) { // deals with interrupt below 080 ExceptionUtils.checkInterrupt(t); 081 RecoverableClientException ce = null; 082 if (t instanceof RecoverableClientException) { 083 ce = (RecoverableClientException) t; 084 } else { 085 Throwable unwrappedException = ExceptionHelper.unwrapException(t); 086 if (unwrappedException instanceof RecoverableClientException) { 087 ce = (RecoverableClientException) unwrappedException; 088 } 089 } 090 if (ce != null) { 091 Severity severity = getSeverity(ce); 092 FacesMessages.instance().add(severity, getI18nMessage(ce.getLocalizedMessage()), 093 (Object[]) ce.geLocalizedMessageParams()); 094 return null; 095 } 096 throw t; 097 } 098 } 099 100 @Override 101 public boolean isInterceptorEnabled() { 102 PhaseId phase = getPhase(); 103 if (phase == null) { 104 return true; 105 } 106 if (phase.equals(PhaseId.INVOKE_APPLICATION)) { 107 return true; 108 } 109 110 return false; 111 } 112 113}