Coverage Report - org.apache.myfaces.context.MyFacesExceptionHandlerWrapperImpl
 
Classes in this File Line Coverage Branch Coverage Complexity
MyFacesExceptionHandlerWrapperImpl
0%
0/106
0%
0/64
3.667
 
 1  
 /*
 2  
  * Licensed to the Apache Software Foundation (ASF) under one
 3  
  * or more contributor license agreements.  See the NOTICE file
 4  
  * distributed with this work for additional information
 5  
  * regarding copyright ownership.  The ASF licenses this file
 6  
  * to you under the Apache License, Version 2.0 (the
 7  
  * "License"); you may not use this file except in compliance
 8  
  * with the License.  You may obtain a copy of the License at
 9  
  *
 10  
  *   http://www.apache.org/licenses/LICENSE-2.0
 11  
  *
 12  
  * Unless required by applicable law or agreed to in writing,
 13  
  * software distributed under the License is distributed on an
 14  
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 15  
  * KIND, either express or implied.  See the License for the
 16  
  * specific language governing permissions and limitations
 17  
  * under the License.
 18  
  */
 19  
 package org.apache.myfaces.context;
 20  
 
 21  
 import java.util.ArrayList;
 22  
 import java.util.Collections;
 23  
 import java.util.LinkedList;
 24  
 import java.util.List;
 25  
 import java.util.Queue;
 26  
 import java.util.logging.Level;
 27  
 import java.util.logging.Logger;
 28  
 
 29  
 import javax.faces.FacesException;
 30  
 import javax.faces.application.ProjectStage;
 31  
 import javax.faces.component.UIComponent;
 32  
 import javax.faces.context.ExceptionHandler;
 33  
 import javax.faces.context.ExceptionHandlerWrapper;
 34  
 import javax.faces.context.FacesContext;
 35  
 import javax.faces.event.AbortProcessingException;
 36  
 import javax.faces.event.ExceptionQueuedEvent;
 37  
 import javax.faces.event.ExceptionQueuedEventContext;
 38  
 import javax.faces.event.SystemEvent;
 39  
 import javax.servlet.http.HttpServletResponse;
 40  
 
 41  
 import org.apache.myfaces.lifecycle.ViewNotFoundException;
 42  
 import org.apache.myfaces.renderkit.ErrorPageWriter;
 43  
 import org.apache.myfaces.shared.util.WebConfigParamUtils;
 44  
 import org.apache.myfaces.spi.WebConfigProvider;
 45  
 import org.apache.myfaces.spi.WebConfigProviderFactory;
 46  
 
 47  
 /**
 48  
  * Extended MyFaces-specific ExceptionHandler implementation. 
 49  
  * 
 50  
  * @author Leonardo Uribe
 51  
  *
 52  
  */
 53  0
 public class MyFacesExceptionHandlerWrapperImpl extends ExceptionHandlerWrapper
 54  
 {
 55  0
     private static final Logger log = Logger.getLogger(MyFacesExceptionHandlerWrapperImpl.class.getName());
 56  
     
 57  
     private Queue<ExceptionQueuedEvent> handled;
 58  
     private Queue<ExceptionQueuedEvent> unhandled;
 59  
     private ExceptionQueuedEvent handledAndThrown;
 60  
 
 61  
     
 62  
     private ExceptionHandler _delegate;
 63  
     private boolean _isErrorPagePresent;
 64  
     private boolean _useMyFacesErrorHandling;
 65  
     private boolean _inited;
 66  
 
 67  
     public MyFacesExceptionHandlerWrapperImpl(ExceptionHandler delegate)
 68  0
     {
 69  0
         this._delegate = delegate;
 70  0
         this._inited = false;
 71  0
     }
 72  
     
 73  
     protected void init()
 74  
     {
 75  0
         if (!_inited)
 76  
         {
 77  0
             FacesContext facesContext = FacesContext.getCurrentInstance();
 78  0
             WebConfigProvider webConfigProvider = WebConfigProviderFactory.getWebConfigProviderFactory(
 79  
                     facesContext.getExternalContext()).getWebConfigProvider(facesContext.getExternalContext());
 80  
     
 81  0
             _isErrorPagePresent = webConfigProvider.isErrorPagePresent(facesContext.getExternalContext());
 82  0
             _useMyFacesErrorHandling = WebConfigParamUtils.getBooleanInitParameter(facesContext.getExternalContext(),
 83  
                     ErrorPageWriter.ERROR_HANDLING_PARAMETER, facesContext.isProjectStage(ProjectStage.Development));
 84  0
             _inited = true;
 85  
         }
 86  0
     }
 87  
     
 88  
     protected void init(FacesContext facesContext)
 89  
     {
 90  0
         if (!_inited)
 91  
         {
 92  0
             if (facesContext == null)
 93  
             {
 94  0
                 facesContext = FacesContext.getCurrentInstance();
 95  
             }
 96  0
             WebConfigProvider webConfigProvider = WebConfigProviderFactory.getWebConfigProviderFactory(
 97  
                     facesContext.getExternalContext()).getWebConfigProvider(facesContext.getExternalContext());
 98  
     
 99  0
             _isErrorPagePresent = webConfigProvider.isErrorPagePresent(facesContext.getExternalContext());
 100  0
             _useMyFacesErrorHandling = WebConfigParamUtils.getBooleanInitParameter(facesContext.getExternalContext(),
 101  
                     ErrorPageWriter.ERROR_HANDLING_PARAMETER, facesContext.isProjectStage(ProjectStage.Development));
 102  0
             _inited = true;
 103  
         }
 104  0
     }
 105  
     
 106  
     protected void init(SystemEvent exceptionQueuedEvent)
 107  
     {
 108  0
         if (!_inited)
 109  
         {
 110  0
             if (exceptionQueuedEvent instanceof ExceptionQueuedEvent)
 111  
             {
 112  0
                 ExceptionQueuedEvent eqe = (ExceptionQueuedEvent)exceptionQueuedEvent;
 113  0
                 ExceptionQueuedEventContext eqec = eqe.getContext();
 114  0
                 if (eqec != null)
 115  
                 {
 116  0
                     FacesContext facesContext = eqec.getContext();
 117  0
                     if (facesContext != null)
 118  
                     {
 119  0
                         init(facesContext);
 120  0
                         return;
 121  
                     }
 122  
                 }
 123  
             }
 124  0
             init(FacesContext.getCurrentInstance());
 125  
         }
 126  0
     }
 127  
     
 128  
     protected boolean isUseMyFacesErrorHandling()
 129  
     {
 130  0
         return _useMyFacesErrorHandling;
 131  
     }
 132  
     
 133  
     protected boolean isErrorPagePresent()
 134  
     {
 135  0
         return _isErrorPagePresent;
 136  
     }
 137  
     
 138  
     /**
 139  
      * {@inheritDoc}
 140  
      */
 141  
     @Override
 142  
     public ExceptionQueuedEvent getHandledExceptionQueuedEvent()
 143  
     {
 144  0
         init();
 145  0
         if (!isUseMyFacesErrorHandling())
 146  
         {
 147  0
             return super.getHandledExceptionQueuedEvent();
 148  
         }
 149  
         else
 150  
         {
 151  0
             return handledAndThrown;
 152  
         }
 153  
     }
 154  
 
 155  
     /**
 156  
      * {@inheritDoc}
 157  
      */
 158  
     @Override
 159  
     public Iterable<ExceptionQueuedEvent> getHandledExceptionQueuedEvents()
 160  
     {
 161  0
         init();
 162  0
         if (!isUseMyFacesErrorHandling())
 163  
         {
 164  0
             return super.getHandledExceptionQueuedEvents();
 165  
         }
 166  
         else
 167  
         {
 168  0
             return handled == null ? Collections.<ExceptionQueuedEvent>emptyList() : handled;
 169  
         }
 170  
     }
 171  
 
 172  
     /**
 173  
      * {@inheritDoc}
 174  
      */
 175  
     @Override
 176  
     public Iterable<ExceptionQueuedEvent> getUnhandledExceptionQueuedEvents()
 177  
     {
 178  0
         init();
 179  0
         if (!isUseMyFacesErrorHandling())
 180  
         {
 181  0
             return super.getUnhandledExceptionQueuedEvents();
 182  
         }
 183  
         else
 184  
         {
 185  0
             return unhandled == null ? Collections.<ExceptionQueuedEvent>emptyList() : unhandled;
 186  
         }
 187  
     }
 188  
 
 189  
     /**
 190  
      * {@inheritDoc}
 191  
      */
 192  
     @Override
 193  
     public void handle() throws FacesException
 194  
     {
 195  0
         init();
 196  0
         if (!isUseMyFacesErrorHandling())
 197  
         {
 198  0
             if (isErrorPagePresent())
 199  
             {
 200  0
                 FacesContext facesContext = FacesContext.getCurrentInstance();
 201  
                 // save current view in the request map to access it on the error page
 202  0
                 facesContext.getExternalContext().getRequestMap().put(ErrorPageWriter.VIEW_KEY,
 203  
                                                                       facesContext.getViewRoot());
 204  
             }
 205  
             try
 206  
             {
 207  0
                 super.handle();
 208  
             }
 209  0
             catch (FacesException e)
 210  
             {
 211  0
                 FacesContext facesContext = FacesContext.getCurrentInstance();
 212  0
                 if (e.getCause() instanceof ViewNotFoundException)
 213  
                 {
 214  0
                     facesContext.getExternalContext().setResponseStatus(HttpServletResponse.SC_NOT_FOUND);
 215  
                 }
 216  
                 else
 217  
                 {
 218  0
                     facesContext.getExternalContext().setResponseStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
 219  
                 }
 220  0
                 throw e;
 221  0
             }
 222  0
             return;
 223  
         }
 224  
         else
 225  
         {
 226  0
             if (unhandled != null && !unhandled.isEmpty())
 227  
             {
 228  0
                 if (handled == null)
 229  
                 {
 230  0
                     handled = new LinkedList<ExceptionQueuedEvent>();
 231  
                 }
 232  
                 
 233  0
                 List<Throwable> throwableList = new ArrayList<Throwable>();
 234  0
                 List<UIComponent> components = new ArrayList<UIComponent>();
 235  0
                 FacesContext facesContext = null;
 236  
                 
 237  
                 do
 238  
                 {
 239  
                     // For each ExceptionEvent in the list
 240  
                     
 241  
                     // get the event to handle
 242  0
                     ExceptionQueuedEvent event = unhandled.peek();
 243  
                     try
 244  
                     {
 245  
                         // call its getContext() method
 246  0
                         ExceptionQueuedEventContext context = event.getContext();
 247  
     
 248  0
                         if (facesContext == null)
 249  
                         {
 250  0
                             facesContext = event.getContext().getContext();
 251  
                         }
 252  
                         
 253  
                         // and call getException() on the returned result
 254  0
                         Throwable exception = context.getException();
 255  
                         
 256  
                         // Upon encountering the first such Exception that is not an instance of
 257  
                         // javax.faces.event.AbortProcessingException
 258  0
                         if (!shouldSkip(exception))
 259  
                         {
 260  
                             // set handledAndThrown so that getHandledExceptionQueuedEvent() returns this event
 261  0
                             handledAndThrown = event;
 262  
                             
 263  0
                             Throwable rootCause = getRootCause(exception);
 264  
                             
 265  0
                             throwableList.add(rootCause == null ? exception : rootCause);
 266  0
                             components.add(event.getContext().getComponent());
 267  
                             
 268  
                             //break;
 269  0
                         }
 270  
                         else
 271  
                         {
 272  
                             // Testing mojarra it logs a message and the exception
 273  
                             // however, this behaviour is not mentioned in the spec
 274  0
                             log.log(Level.SEVERE, exception.getClass().getName() + " occured while processing " +
 275  
                                     (context.inBeforePhase() ? "beforePhase() of " : 
 276  
                                             (context.inAfterPhase() ? "afterPhase() of " : "")) + 
 277  
                                     "phase " + context.getPhaseId() + ": " +
 278  
                                     "UIComponent-ClientId=" + 
 279  
                                     (context.getComponent() != null ? 
 280  
                                             context.getComponent().getClientId(context.getContext()) : "") + ", " +
 281  
                                     "Message=" + exception.getMessage());
 282  
                             
 283  0
                             log.log(Level.SEVERE, exception.getMessage(), exception);
 284  
                         }
 285  
                     }
 286  
                     finally
 287  
                     {
 288  
                         // if we will throw the Exception or if we just logged it,
 289  
                         // we handled it in either way --> add to handled
 290  0
                         handled.add(event);
 291  0
                         unhandled.remove(event);
 292  0
                     }
 293  0
                 } while (!unhandled.isEmpty());
 294  
 
 295  0
                 if (facesContext == null)
 296  
                 {
 297  0
                     facesContext = FacesContext.getCurrentInstance();
 298  
                 }
 299  0
                 if (throwableList.size() == 1)
 300  
                 {
 301  0
                     ErrorPageWriter.handle(facesContext, components, throwableList.get(0));
 302  
                 }
 303  0
                 else if (throwableList.size() > 1)
 304  
                 {
 305  0
                     ErrorPageWriter.handle(facesContext, components,
 306  
                                            throwableList.toArray(new Throwable[throwableList.size()]));
 307  
                 }
 308  
             }
 309  
         }
 310  0
     }
 311  
 
 312  
     /**
 313  
      * {@inheritDoc}
 314  
      */
 315  
     @Override
 316  
     public void processEvent(SystemEvent exceptionQueuedEvent) throws AbortProcessingException
 317  
     {
 318  0
         init(exceptionQueuedEvent);
 319  
         
 320  0
         if (!isUseMyFacesErrorHandling())
 321  
         {
 322  0
             super.processEvent(exceptionQueuedEvent);
 323  
         }
 324  
         else
 325  
         {
 326  0
             if (unhandled == null)
 327  
             {
 328  0
                 unhandled = new LinkedList<ExceptionQueuedEvent>();
 329  
             }
 330  
             
 331  0
             unhandled.add((ExceptionQueuedEvent)exceptionQueuedEvent);
 332  
         }
 333  0
     }
 334  
 
 335  
     protected Throwable getRethrownException(Throwable exception)
 336  
     {
 337  
         // Let toRethrow be either the result of calling getRootCause() on the Exception, 
 338  
         // or the Exception itself, whichever is non-null
 339  0
         Throwable toRethrow = getRootCause(exception);
 340  0
         if (toRethrow == null)
 341  
         {
 342  0
             toRethrow = exception;
 343  
         }
 344  
         
 345  0
         return toRethrow;
 346  
     }
 347  
     
 348  
     protected FacesException wrap(Throwable exception)
 349  
     {
 350  0
         if (exception instanceof FacesException)
 351  
         {
 352  0
             return (FacesException) exception;
 353  
         }
 354  0
         return new FacesException(exception);
 355  
     }
 356  
     
 357  
     protected boolean shouldSkip(Throwable exception)
 358  
     {
 359  0
         return exception instanceof AbortProcessingException;
 360  
     }
 361  
     
 362  
     @Override
 363  
     public ExceptionHandler getWrapped()
 364  
     {
 365  0
         return _delegate;
 366  
     }
 367  
 }