001/*
002 * ====================================================================
003 * Licensed to the Apache Software Foundation (ASF) under one
004 * or more contributor license agreements.  See the NOTICE file
005 * distributed with this work for additional information
006 * regarding copyright ownership.  The ASF licenses this file
007 * to you under the Apache License, Version 2.0 (the
008 * "License"); you may not use this file except in compliance
009 * with the License.  You may obtain a copy of the License at
010 *
011 *   http://www.apache.org/licenses/LICENSE-2.0
012 *
013 * Unless required by applicable law or agreed to in writing,
014 * software distributed under the License is distributed on an
015 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
016 * KIND, either express or implied.  See the License for the
017 * specific language governing permissions and limitations
018 * under the License.
019 * ====================================================================
020 *
021 * This software consists of voluntary contributions made by many
022 * individuals on behalf of the Apache Software Foundation.  For more
023 * information on the Apache Software Foundation, please see
024 * <http://www.apache.org/>.
025 *
026 */
027
028package org.apache.http.impl;
029
030import java.util.Locale;
031
032import org.apache.http.HttpStatus;
033import org.apache.http.ReasonPhraseCatalog;
034import org.apache.http.annotation.ThreadingBehavior;
035import org.apache.http.annotation.Contract;
036import org.apache.http.util.Args;
037
038/**
039 * English reason phrases for HTTP status codes.
040 * All status codes defined in RFC1945 (HTTP/1.0), RFC2616 (HTTP/1.1), and
041 * RFC2518 (WebDAV) are supported.
042 *
043 * @since 4.0
044 */
045@Contract(threading = ThreadingBehavior.IMMUTABLE)
046public class EnglishReasonPhraseCatalog implements ReasonPhraseCatalog {
047
048    // static array with english reason phrases defined below
049
050    /**
051     * The default instance of this catalog.
052     * This catalog is thread safe, so there typically
053     * is no need to create other instances.
054     */
055    public final static EnglishReasonPhraseCatalog INSTANCE = new EnglishReasonPhraseCatalog();
056
057
058    /**
059     * Restricted default constructor, for derived classes.
060     * If you need an instance of this class, use {@link #INSTANCE INSTANCE}.
061     */
062    protected EnglishReasonPhraseCatalog() {
063        // no body
064    }
065
066
067    /**
068     * Obtains the reason phrase for a status code.
069     *
070     * @param status    the status code, in the range 100-599
071     * @param loc       ignored
072     *
073     * @return  the reason phrase, or {@code null}
074     */
075    @Override
076    public String getReason(final int status, final Locale loc) {
077        Args.check(status >= 100 && status < 600, "Unknown category for status code " + status);
078        final int category = status / 100;
079        final int subcode  = status - 100*category;
080
081        String reason = null;
082        if (REASON_PHRASES[category].length > subcode) {
083            reason = REASON_PHRASES[category][subcode];
084        }
085
086        return reason;
087    }
088
089
090    /** Reason phrases lookup table. */
091    private static final String[][] REASON_PHRASES = new String[][]{
092        null,
093        new String[3],  // 1xx
094        new String[8],  // 2xx
095        new String[8],  // 3xx
096        new String[25], // 4xx
097        new String[8]   // 5xx
098    };
099
100
101
102    /**
103     * Stores the given reason phrase, by status code.
104     * Helper method to initialize the static lookup table.
105     *
106     * @param status    the status code for which to define the phrase
107     * @param reason    the reason phrase for this status code
108     */
109    private static void setReason(final int status, final String reason) {
110        final int category = status / 100;
111        final int subcode  = status - 100*category;
112        REASON_PHRASES[category][subcode] = reason;
113    }
114
115
116    // ----------------------------------------------------- Static Initializer
117
118    /** Set up status code to "reason phrase" map. */
119    static {
120        // HTTP 1.0 Server status codes -- see RFC 1945
121        setReason(HttpStatus.SC_OK,
122                  "OK");
123        setReason(HttpStatus.SC_CREATED,
124                  "Created");
125        setReason(HttpStatus.SC_ACCEPTED,
126                  "Accepted");
127        setReason(HttpStatus.SC_NO_CONTENT,
128                  "No Content");
129        setReason(HttpStatus.SC_MOVED_PERMANENTLY,
130                  "Moved Permanently");
131        setReason(HttpStatus.SC_MOVED_TEMPORARILY,
132                  "Moved Temporarily");
133        setReason(HttpStatus.SC_NOT_MODIFIED,
134                  "Not Modified");
135        setReason(HttpStatus.SC_BAD_REQUEST,
136                  "Bad Request");
137        setReason(HttpStatus.SC_UNAUTHORIZED,
138                  "Unauthorized");
139        setReason(HttpStatus.SC_FORBIDDEN,
140                  "Forbidden");
141        setReason(HttpStatus.SC_NOT_FOUND,
142                  "Not Found");
143        setReason(HttpStatus.SC_INTERNAL_SERVER_ERROR,
144                  "Internal Server Error");
145        setReason(HttpStatus.SC_NOT_IMPLEMENTED,
146                  "Not Implemented");
147        setReason(HttpStatus.SC_BAD_GATEWAY,
148                  "Bad Gateway");
149        setReason(HttpStatus.SC_SERVICE_UNAVAILABLE,
150                  "Service Unavailable");
151
152        // HTTP 1.1 Server status codes -- see RFC 2048
153        setReason(HttpStatus.SC_CONTINUE,
154                  "Continue");
155        setReason(HttpStatus.SC_TEMPORARY_REDIRECT,
156                  "Temporary Redirect");
157        setReason(HttpStatus.SC_METHOD_NOT_ALLOWED,
158                  "Method Not Allowed");
159        setReason(HttpStatus.SC_CONFLICT,
160                  "Conflict");
161        setReason(HttpStatus.SC_PRECONDITION_FAILED,
162                  "Precondition Failed");
163        setReason(HttpStatus.SC_REQUEST_TOO_LONG,
164                  "Request Too Long");
165        setReason(HttpStatus.SC_REQUEST_URI_TOO_LONG,
166                  "Request-URI Too Long");
167        setReason(HttpStatus.SC_UNSUPPORTED_MEDIA_TYPE,
168                  "Unsupported Media Type");
169        setReason(HttpStatus.SC_MULTIPLE_CHOICES,
170                  "Multiple Choices");
171        setReason(HttpStatus.SC_SEE_OTHER,
172                  "See Other");
173        setReason(HttpStatus.SC_USE_PROXY,
174                  "Use Proxy");
175        setReason(HttpStatus.SC_PAYMENT_REQUIRED,
176                  "Payment Required");
177        setReason(HttpStatus.SC_NOT_ACCEPTABLE,
178                  "Not Acceptable");
179        setReason(HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED,
180                  "Proxy Authentication Required");
181        setReason(HttpStatus.SC_REQUEST_TIMEOUT,
182                  "Request Timeout");
183
184        setReason(HttpStatus.SC_SWITCHING_PROTOCOLS,
185                  "Switching Protocols");
186        setReason(HttpStatus.SC_NON_AUTHORITATIVE_INFORMATION,
187                  "Non Authoritative Information");
188        setReason(HttpStatus.SC_RESET_CONTENT,
189                  "Reset Content");
190        setReason(HttpStatus.SC_PARTIAL_CONTENT,
191                  "Partial Content");
192        setReason(HttpStatus.SC_GATEWAY_TIMEOUT,
193                  "Gateway Timeout");
194        setReason(HttpStatus.SC_HTTP_VERSION_NOT_SUPPORTED,
195                  "Http Version Not Supported");
196        setReason(HttpStatus.SC_GONE,
197                  "Gone");
198        setReason(HttpStatus.SC_LENGTH_REQUIRED,
199                  "Length Required");
200        setReason(HttpStatus.SC_REQUESTED_RANGE_NOT_SATISFIABLE,
201                  "Requested Range Not Satisfiable");
202        setReason(HttpStatus.SC_EXPECTATION_FAILED,
203                  "Expectation Failed");
204
205        // WebDAV Server-specific status codes
206        setReason(HttpStatus.SC_PROCESSING,
207                  "Processing");
208        setReason(HttpStatus.SC_MULTI_STATUS,
209                  "Multi-Status");
210        setReason(HttpStatus.SC_UNPROCESSABLE_ENTITY,
211                  "Unprocessable Entity");
212        setReason(HttpStatus.SC_INSUFFICIENT_SPACE_ON_RESOURCE,
213                  "Insufficient Space On Resource");
214        setReason(HttpStatus.SC_METHOD_FAILURE,
215                  "Method Failure");
216        setReason(HttpStatus.SC_LOCKED,
217                  "Locked");
218        setReason(HttpStatus.SC_INSUFFICIENT_STORAGE,
219                  "Insufficient Storage");
220        setReason(HttpStatus.SC_FAILED_DEPENDENCY,
221                  "Failed Dependency");
222    }
223
224
225}