001/*
002 * Copyright 2012-2018 the original author or authors.
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
017package org.springframework.boot.web.server;
018
019import org.springframework.http.HttpStatus;
020import org.springframework.util.ObjectUtils;
021
022/**
023 * Simple server-independent abstraction for error pages. Roughly equivalent to the
024 * {@literal <error-page>} element traditionally found in web.xml.
025 *
026 * @author Dave Syer
027 * @since 2.0.0
028 */
029public class ErrorPage {
030
031        private final HttpStatus status;
032
033        private final Class<? extends Throwable> exception;
034
035        private final String path;
036
037        public ErrorPage(String path) {
038                this.status = null;
039                this.exception = null;
040                this.path = path;
041        }
042
043        public ErrorPage(HttpStatus status, String path) {
044                this.status = status;
045                this.exception = null;
046                this.path = path;
047        }
048
049        public ErrorPage(Class<? extends Throwable> exception, String path) {
050                this.status = null;
051                this.exception = exception;
052                this.path = path;
053        }
054
055        /**
056         * The path to render (usually implemented as a forward), starting with "/". A custom
057         * controller or servlet path can be used, or if the server supports it, a template
058         * path (e.g. "/error.jsp").
059         * @return the path that will be rendered for this error
060         */
061        public String getPath() {
062                return this.path;
063        }
064
065        /**
066         * Returns the exception type (or {@code null} for a page that matches by status).
067         * @return the exception type or {@code null}
068         */
069        public Class<? extends Throwable> getException() {
070                return this.exception;
071        }
072
073        /**
074         * The HTTP status value that this error page matches (or {@code null} for a page that
075         * matches by exception).
076         * @return the status or {@code null}
077         */
078        public HttpStatus getStatus() {
079                return this.status;
080        }
081
082        /**
083         * The HTTP status value that this error page matches.
084         * @return the status value (or 0 for a page that matches any status)
085         */
086        public int getStatusCode() {
087                return (this.status != null) ? this.status.value() : 0;
088        }
089
090        /**
091         * The exception type name.
092         * @return the exception type name (or {@code null} if there is none)
093         */
094        public String getExceptionName() {
095                return (this.exception != null) ? this.exception.getName() : null;
096        }
097
098        /**
099         * Return if this error page is a global one (matches all unmatched status and
100         * exception types).
101         * @return if this is a global error page
102         */
103        public boolean isGlobal() {
104                return (this.status == null && this.exception == null);
105        }
106
107        @Override
108        public boolean equals(Object obj) {
109                if (this == obj) {
110                        return true;
111                }
112                if (obj == null) {
113                        return false;
114                }
115                if (obj instanceof ErrorPage) {
116                        ErrorPage other = (ErrorPage) obj;
117                        boolean rtn = true;
118                        rtn = rtn && ObjectUtils.nullSafeEquals(getExceptionName(),
119                                        other.getExceptionName());
120                        rtn = rtn && ObjectUtils.nullSafeEquals(this.path, other.path);
121                        rtn = rtn && this.status == other.status;
122                        return rtn;
123                }
124                return false;
125        }
126
127        @Override
128        public int hashCode() {
129                final int prime = 31;
130                int result = 1;
131                result = prime * result + ObjectUtils.nullSafeHashCode(getExceptionName());
132                result = prime * result + ObjectUtils.nullSafeHashCode(this.path);
133                result = prime * result + this.getStatusCode();
134                return result;
135        }
136
137}