001/* 002 * The contents of this file are subject to the terms of the Common Development and 003 * Distribution License (the License). You may not use this file except in compliance with the 004 * License. 005 * 006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the 007 * specific language governing permission and limitations under the License. 008 * 009 * When distributing Covered Software, include this CDDL Header Notice in each file and include 010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL 011 * Header, with the fields enclosed by brackets [] replaced by your own identifying 012 * information: "Portions Copyright [year] [name of copyright owner]". 013 * 014 * Copyright 2010–2011 ApexIdentity Inc. 015 * Portions Copyright 2011-2014 ForgeRock AS. 016 */ 017 018package org.forgerock.openig.filter; 019 020import static org.forgerock.util.Utils.*; 021 022import java.io.IOException; 023 024import org.forgerock.openig.handler.Handler; 025import org.forgerock.openig.handler.HandlerException; 026import org.forgerock.openig.heap.GenericHeaplet; 027import org.forgerock.openig.heap.HeapException; 028import org.forgerock.openig.http.Exchange; 029 030/** 031 * Catches any exceptions thrown during handing of a request. This allows friendlier error 032 * pages to be displayed than would otherwise be displayed by the container. Caught exceptions 033 * are logged with a log level of {@link org.forgerock.openig.log.LogLevel#WARNING} and the exchange is diverted to 034 * the specified exception handler. 035 * <p> 036 * Note: While the response object will be retained in the exchange object, this class will 037 * close any open entity within the response object prior to dispatching the exchange to the 038 * exception handler. 039 */ 040public class ExceptionFilter extends GenericFilter { 041 042 /** Handler to dispatch to in the event of caught exceptions. */ 043 private final Handler handler; 044 045 /** 046 * Build a new exception filter that will divert the flow to the given handler in case of exception. 047 * @param handler exception handler 048 */ 049 public ExceptionFilter(final Handler handler) { 050 this.handler = handler; 051 } 052 053 @Override 054 public void filter(Exchange exchange, Handler next) throws HandlerException, IOException { 055 try { 056 next.handle(exchange); 057 } catch (Throwable t) { 058 // user-impacting 059 logger.warning(t); 060 closeSilently(exchange.response); 061 handler.handle(exchange); 062 } 063 } 064 065 /** 066 * Creates and initializes an exception filter in a heap environment. 067 */ 068 public static class Heaplet extends GenericHeaplet { 069 @Override 070 public Object create() throws HeapException { 071 return new ExceptionFilter(heap.resolve(config.get("handler"), Handler.class)); 072 } 073 } 074}