001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.wicket.protocol.http.servlet;
018
019import javax.servlet.RequestDispatcher;
020import javax.servlet.ServletRequest;
021import javax.servlet.http.HttpServletRequest;
022
023import org.apache.wicket.util.lang.Args;
024import org.apache.wicket.util.string.Strings;
025
026/**
027 * Represents additional error attributes present in a {@link ServletRequest} when the servlet
028 * container is handling an error or a forward to an error page mapped by {@code error-page} element
029 * in {@code web.xml}.
030 * 
031 * See documentation for the following request attributes for the values stored in this object:
032 * <ul>
033 * <li>{@link RequestDispatcher#ERROR_STATUS_CODE}</li>
034 * <li>{@link RequestDispatcher#ERROR_MESSAGE}</li>
035 * <li>{@link RequestDispatcher#ERROR_REQUEST_URI}</li>
036 * <li>{@link RequestDispatcher#ERROR_SERVLET_NAME}</li>
037 * <li>{@link RequestDispatcher#ERROR_EXCEPTION_TYPE}</li>
038 * <li>{@link RequestDispatcher#ERROR_EXCEPTION}</li>
039 * </ul>
040 * 
041 * @author igor
042 */
043public class ErrorAttributes
044{
045        // javax.servlet.error.status_code
046        private final Integer statusCode;
047        // javax.servlet.error.message
048        private final String message;
049        // javax.servlet.error.request_uri
050        private final String requestUri;
051        // javax.servlet.error.servlet_name
052        private final String servletName;
053        // javax.servlet.error.exception_type
054        private final Class<? extends Throwable> exceptionType;
055        // javax.servlet.error.exception
056        private final Throwable exception;
057
058        /**
059         * Constructor
060         * 
061         * @param statusCode
062         * @param message
063         * @param requestUri
064         * @param servletName
065         * @param exceptionType
066         * @param exception
067         */
068        private ErrorAttributes(Integer statusCode, String message, String requestUri,
069                String servletName, Class<? extends Throwable> exceptionType, Throwable exception)
070        {
071                this.statusCode = statusCode;
072                this.message = message;
073                this.requestUri = requestUri;
074                this.servletName = servletName;
075                this.exceptionType = exceptionType;
076                this.exception = exception;
077        }
078
079        /**
080         * Gets statusCode.
081         * 
082         * @return statusCode
083         */
084        public Integer getStatusCode()
085        {
086                return statusCode;
087        }
088
089        /**
090         * Gets message.
091         * 
092         * @return message
093         */
094        public String getMessage()
095        {
096                return message;
097        }
098
099        /**
100         * Gets requestUri.
101         * 
102         * @return requestUri
103         */
104        public String getRequestUri()
105        {
106                return requestUri;
107        }
108
109        /**
110         * Gets servletName.
111         * 
112         * @return servletName
113         */
114        public String getServletName()
115        {
116                return servletName;
117        }
118
119        /**
120         * Gets exceptionType.
121         * 
122         * @return exceptionType
123         */
124        public Class<? extends Throwable> getExceptionType()
125        {
126                return exceptionType;
127        }
128
129        /**
130         * Gets exception.
131         * 
132         * @return exception
133         */
134        public Throwable getException()
135        {
136                return exception;
137        }
138
139        /**
140         * Factory for creating instances of this class.
141         * 
142         * @param request
143         * @return instance of request contains error attributes or {@code null} if it does not.
144         */
145        public static ErrorAttributes of(HttpServletRequest request, String filterPrefix)
146        {
147                Args.notNull(request, "request");
148                Integer code = (Integer)request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE);
149                String message = (String)request.getAttribute(RequestDispatcher.ERROR_MESSAGE);
150                String uri = DispatchedRequestUtils.getRequestUri(request, RequestDispatcher.ERROR_REQUEST_URI, filterPrefix);
151                String servlet = (String)request.getAttribute(RequestDispatcher.ERROR_SERVLET_NAME);
152                @SuppressWarnings("unchecked")
153                Class<? extends Throwable> type = (Class<? extends Throwable>)request.getAttribute(RequestDispatcher.ERROR_EXCEPTION_TYPE);
154                Throwable ex = (Throwable)request.getAttribute(RequestDispatcher.ERROR_EXCEPTION);
155
156                if (!Strings.isEmpty(uri) || code != null || ex != null)
157                {
158                        return new ErrorAttributes(code, message, uri, servlet, type, ex);
159                }
160                return null;
161        }
162
163        @Override
164        public String toString()
165        {
166                return "ErrorAttributes{" +
167                                "statusCode=" + statusCode +
168                                ", message='" + message + '\'' +
169                                ", requestUri='" + requestUri + '\'' +
170                                ", servletName='" + servletName + '\'' +
171                                ", exceptionType=" + exceptionType +
172                                ", exception=" + exception +
173                                '}';
174        }
175}