1 /*
2  * JBoss, Home of Professional Open Source.
3  * Copyright 2014 Red Hat, Inc., and individual contributors
4  * as indicated by the @author tags.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * 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, software
13  *  distributed under the License is distributed on an "AS IS" BASIS,
14  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  *  See the License for the specific language governing permissions and
16  *  limitations under the License.
17  */

18
19 package io.undertow.servlet.core;
20
21 import io.undertow.util.StatusCodes;
22
23 import java.util.Map;
24
25 import javax.servlet.ServletException;
26
27 /**
28  * Class that maintains information about error page mappings.
29  *
30  * @author Stuart Douglas
31  */

32 public class ErrorPages {
33
34     private final Map<Integer, String> errorCodeLocations;
35     private final Map<Class<? extends Throwable>, String> exceptionMappings;
36     private final String defaultErrorPage;
37
38     public ErrorPages(final Map<Integer, String> errorCodeLocations, final Map<Class<? extends Throwable>, String> exceptionMappings, final String defaultErrorPage) {
39         this.errorCodeLocations = errorCodeLocations;
40         this.exceptionMappings = exceptionMappings;
41         this.defaultErrorPage = defaultErrorPage;
42     }
43
44     public String getErrorLocation(final int code) {
45         String location = errorCodeLocations.get(code);
46         if (location == null) {
47             return defaultErrorPage;
48         }
49         return location;
50     }
51
52     public String getErrorLocation(final Throwable exception) {
53         if (exception == null) {
54             return null;
55         }
56         //todo: this is kinda slow, but there is probably not a great deal that can be done about it
57         String location = null;
58         for (Class c = exception.getClass(); c != null && location == null; c = c.getSuperclass()) {
59             location = exceptionMappings.get(c);
60         }
61         if (location == null && exception instanceof ServletException) {
62             Throwable rootCause = ((ServletException) exception).getRootCause();
63             //Iterate through any nested JasperException in case it is in JSP development mode
64             while (rootCause != null && rootCause instanceof ServletException && location == null) {
65                 for (Class c = rootCause.getClass(); c != null && location == null; c = c.getSuperclass()) {
66                     location = exceptionMappings.get(c);
67                 }
68                 rootCause = ((ServletException) rootCause).getRootCause();
69             }
70             if (rootCause != null && location == null) {
71                 for (Class c = rootCause.getClass(); c != null && location == null; c = c.getSuperclass()) {
72                     location = exceptionMappings.get(c);
73                 }
74             }
75         }
76         if (location == null) {
77             location = getErrorLocation(StatusCodes.INTERNAL_SERVER_ERROR);
78         }
79         return location;
80     }
81
82
83 }
84