001/* 002 * (C) Copyright 2006-2009 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * Thierry Delprat 018 */ 019package org.nuxeo.ecm.platform.ui.web.util; 020 021import java.util.Map; 022 023import javax.faces.event.PhaseId; 024 025import org.jboss.seam.Component; 026import org.jboss.seam.annotations.intercept.Interceptor; 027import org.jboss.seam.contexts.FacesLifecycle; 028import org.jboss.seam.faces.FacesMessages; 029import org.jboss.seam.intercept.AbstractInterceptor; 030import org.jboss.seam.intercept.InvocationContext; 031import org.jboss.seam.international.StatusMessage.Severity; 032import org.nuxeo.common.utils.ExceptionUtils; 033import org.nuxeo.ecm.core.api.RecoverableClientException; 034import org.nuxeo.ecm.platform.web.common.exceptionhandling.ExceptionHelper; 035 036/** 037 * Intercepts Seam Bean call during the INVOKE_APPLICATION phase to see if a {@link RecoverableClientException} is 038 * raised. If this is the case, the INVOKE call returns null and the associated FacesMessage is generated. 039 * 040 * @author <a href="mailto:[email protected]">Tiry</a> 041 * @since 5.6 042 */ 043@Interceptor 044public class NuxeoExceptionInterceptor extends AbstractInterceptor { 045 046 private static final long serialVersionUID = 1L; 047 048 protected PhaseId getPhase() { 049 return FacesLifecycle.getPhaseId(); 050 } 051 052 protected Severity getSeverity(RecoverableClientException ce) { 053 if (ce.getSeverity() == RecoverableClientException.Severity.WARN) { 054 return Severity.WARN; 055 } else if (ce.getSeverity() == RecoverableClientException.Severity.FATAL) { 056 return Severity.FATAL; 057 } 058 return Severity.ERROR; 059 } 060 061 protected String getI18nMessage(String messageKey) { 062 @SuppressWarnings("unchecked") 063 Map<String, String> messages = (Map<String, String>) Component.getInstance( 064 "org.jboss.seam.international.messages", true); 065 066 if (messages == null) { 067 return messageKey; 068 } 069 String i18nMessage = messages.get(messageKey); 070 if (i18nMessage != null) { 071 return i18nMessage; 072 } else { 073 return messageKey; 074 } 075 } 076 077 @Override 078 public Object aroundInvoke(InvocationContext invocationContext) throws Exception { // stupid Seam API 079 try { 080 return invocationContext.proceed(); 081 } catch (Exception t) { // deals with interrupt below 082 ExceptionUtils.checkInterrupt(t); 083 RecoverableClientException ce = null; 084 if (t instanceof RecoverableClientException) { 085 ce = (RecoverableClientException) t; 086 } else { 087 Throwable unwrappedException = ExceptionHelper.unwrapException(t); 088 if (unwrappedException instanceof RecoverableClientException) { 089 ce = (RecoverableClientException) unwrappedException; 090 } 091 } 092 if (ce != null) { 093 Severity severity = getSeverity(ce); 094 FacesMessages.instance().add(severity, getI18nMessage(ce.getLocalizedMessage()), 095 (Object[]) ce.geLocalizedMessageParams()); 096 return null; 097 } 098 throw t; 099 } 100 } 101 102 @Override 103 public boolean isInterceptorEnabled() { 104 PhaseId phase = getPhase(); 105 if (phase == null) { 106 return true; 107 } 108 if (phase.equals(PhaseId.INVOKE_APPLICATION)) { 109 return true; 110 } 111 112 return false; 113 } 114 115}