001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: *
019: */
020: package org.safehaus.asyncweb.common;
021:
022: import java.io.Serializable;
023:
024: public class HttpResponseStatus implements Serializable {
025:
026: private static final long serialVersionUID = -5885201751942967031L;
027:
028: private static final int MIN_ID = 100;
029: private static final int MAX_ID = 599;
030:
031: private static final HttpResponseStatus[] RESPONSE_TABLE = new HttpResponseStatus[MAX_ID + 1];
032:
033: // Informational status codes
034:
035: public static final HttpResponseStatus CONTINUE = new HttpResponseStatus(
036: 100, "Continue", true, false);
037:
038: public static final HttpResponseStatus SWITCHING_PROTOCOLS = new HttpResponseStatus(
039: 101, "Switching Protocols", true, false);
040:
041: // Successful status codes
042:
043: public static final HttpResponseStatus OK = new HttpResponseStatus(
044: 200, "OK", true, false);
045:
046: public static final HttpResponseStatus CREATED = new HttpResponseStatus(
047: 201, "Created", true, false);
048:
049: public static final HttpResponseStatus ACCEPTED = new HttpResponseStatus(
050: 202, "Accepted", true, false);
051:
052: public static final HttpResponseStatus NON_AUTHORITATIVE = new HttpResponseStatus(
053: 203, "Non-Authoritative Information", true, false);
054:
055: public static final HttpResponseStatus NO_CONTENT = new HttpResponseStatus(
056: 204, "No Content", false, false);
057:
058: public static final HttpResponseStatus RESET_CONTENT = new HttpResponseStatus(
059: 205, "Reset Content", false, false);
060:
061: public static final HttpResponseStatus PARTIAL_CONTENT = new HttpResponseStatus(
062: 206, "Partial Content", true, false);
063:
064: // Redirection status codes
065:
066: public static final HttpResponseStatus MULTIPLE_CHOICES = new HttpResponseStatus(
067: 300, "Multiple Choices", true, false);
068:
069: public static final HttpResponseStatus MOVED_PERMANENTLY = new HttpResponseStatus(
070: 301, "Moved Permanently", true, false);
071:
072: public static final HttpResponseStatus FOUND = new HttpResponseStatus(
073: 302, "Found", true, false);
074:
075: public static final HttpResponseStatus SEE_OTHER = new HttpResponseStatus(
076: 303, "See Other", true, false);
077:
078: public static final HttpResponseStatus NOT_MODIFIED = new HttpResponseStatus(
079: 304, "Not Modified", false, false);
080:
081: public static final HttpResponseStatus USE_PROXY = new HttpResponseStatus(
082: 305, "Use Proxy", true, false);
083:
084: public static final HttpResponseStatus TEMPORARY_REDIRECT = new HttpResponseStatus(
085: 307, "Temporary Redirect", true, false);
086:
087: // Client error codes
088:
089: public static final HttpResponseStatus BAD_REQUEST = new HttpResponseStatus(
090: 400, "Bad Request", true, true);
091:
092: public static final HttpResponseStatus UNAUTHORIZED = new HttpResponseStatus(
093: 401, "Unauthorized", true, false);
094:
095: public static final HttpResponseStatus PAYMENT_REQUIRED = new HttpResponseStatus(
096: 402, "Payment Required", true, false);
097:
098: public static final HttpResponseStatus FORBIDDEN = new HttpResponseStatus(
099: 403, "Forbidden", true, false);
100:
101: public static final HttpResponseStatus NOT_FOUND = new HttpResponseStatus(
102: 404, "Not Found", true, false);
103:
104: public static final HttpResponseStatus METHOD_NOT_ALLOWED = new HttpResponseStatus(
105: 405, "Method Not Allowed", true, false);
106:
107: public static final HttpResponseStatus NOT_ACCEPTABLE = new HttpResponseStatus(
108: 406, "Not Acceptable", true, false);
109:
110: public static final HttpResponseStatus PROXY_AUTHENTICATION_REQUIRED = new HttpResponseStatus(
111: 407, "Proxy Authentication Required", true, false);
112:
113: public static final HttpResponseStatus REQUEST_TIMEOUT = new HttpResponseStatus(
114: 408, "Request Time-out", true, true);
115:
116: public static final HttpResponseStatus CONFLICT = new HttpResponseStatus(
117: 409, "Conflict", true, false);
118:
119: public static final HttpResponseStatus GONE = new HttpResponseStatus(
120: 410, "Gone", true, false);
121:
122: public static final HttpResponseStatus LENGTH_REQUIRED = new HttpResponseStatus(
123: 411, "Length Required", true, true);
124:
125: public static final HttpResponseStatus PRECONDITION_FAILED = new HttpResponseStatus(
126: 412, "Precondition Failed", true, false);
127:
128: public static final HttpResponseStatus REQUEST_ENTITY_TOO_LARGE = new HttpResponseStatus(
129: 413, "Request Entity Too Large", true, true);
130:
131: public static final HttpResponseStatus REQUEST_URI_TOO_LONG = new HttpResponseStatus(
132: 414, "Request-URI Too Large", true, true);
133:
134: public static final HttpResponseStatus UNSUPPORTED_MEDIA_TYPE = new HttpResponseStatus(
135: 415, "Unsupported Media Type", true, false);
136:
137: public static final HttpResponseStatus REQUEST_RANGE_NOT_SATISFIABLE = new HttpResponseStatus(
138: 416, "Requested range not satisfiable", true, false);
139:
140: public static final HttpResponseStatus EXPECTATION_FAILED = new HttpResponseStatus(
141: 417, "Expectation Failed", true, false);
142:
143: // Server error codes
144:
145: public static final HttpResponseStatus INTERNAL_SERVER_ERROR = new HttpResponseStatus(
146: 500, "Internal Server Error", true, true);
147:
148: public static final HttpResponseStatus NOT_IMPLEMENTED = new HttpResponseStatus(
149: 501, "Not Implemented", true, true);
150:
151: public static final HttpResponseStatus BAD_GATEWAY = new HttpResponseStatus(
152: 502, "Bad Gateway", true, false);
153:
154: public static final HttpResponseStatus SERVICE_UNAVAILABLE = new HttpResponseStatus(
155: 503, "Service Unavailable", true, true);
156:
157: public static final HttpResponseStatus GATEWAY_TIMEOUT = new HttpResponseStatus(
158: 504, "Gateway Time-out", true, false);
159:
160: public static final HttpResponseStatus HTTP_VERSION_NOT_SUPPORTED = new HttpResponseStatus(
161: 505, "HTTP Version not supported", true, false);
162:
163: private final int code;
164: private final transient boolean allowsMessageBody;
165: private final transient boolean forcesConnectionClosure;
166: private final transient Category category;
167: private final transient String description;
168:
169: /**
170: * @return <code>true</code> iff a message body may be transmitted in
171: * a response containing this response status
172: */
173: public boolean allowsMessageBody() {
174: return allowsMessageBody;
175: }
176:
177: /**
178: * @return <code>true</code> iff a connection which would normally be
179: * kept alive should be closed as a result of this response
180: */
181: public boolean forcesConnectionClosure() {
182: return forcesConnectionClosure;
183: }
184:
185: /**
186: * @return The response code of this status
187: */
188: public int getCode() {
189: return code;
190: }
191:
192: /**
193: * @return The category of this status
194: */
195: public Category getCategory() {
196: return category;
197: }
198:
199: /**
200: * @return A description of this status
201: */
202: public String getDescription() {
203: return description;
204: }
205:
206: /**
207: * A string description of this status
208: */
209: public String toString() {
210: return code + ": " + category + " - " + description;
211: }
212:
213: /**
214: * Returns the <code>ResponseStatus</code> with the specified
215: * status id.
216: * If no status exists with the specified id, a new status is created
217: * and registered based on the category applicable to the id:<br/>
218: * <table border="1">
219: * <tr><td>100 - 199</td><td>Informational</td></tr>
220: * <tr><td>200 - 299</td><td>Successful</td></tr>
221: * <tr><td>300 - 399</td><td>Redirection</td></tr>
222: * <tr><td>400 - 499</td><td>Client Error</td></tr>
223: * <tr><td>500 - 599</td><td>Server Error</td></tr>
224: * <table>.
225: *
226: * @param id The id of the desired response status
227: * @return The <code>ResponseStatus</code>
228: * @throws IllegalStateException If the specified id is invalid
229: */
230: public static HttpResponseStatus forId(int id) {
231: if (id < MIN_ID || id > MAX_ID) {
232: throw new IllegalArgumentException("Illegal response id: "
233: + id);
234: }
235: HttpResponseStatus status = RESPONSE_TABLE[id];
236: if (status == null) {
237: Category cat = categoryForId(id);
238: if (cat == null) {
239: throw new IllegalArgumentException(
240: "Illegal response id: " + id);
241: }
242: status = new HttpResponseStatus(id, cat.toString(), true,
243: cat.isDefaultConnectionClosure());
244: RESPONSE_TABLE[id] = status;
245: }
246: return status;
247: }
248:
249: /**
250: * Obtains the response category which covers the specified response
251: * id
252: *
253: * @param id The id
254: * @return The category - or <code>null</code> if no category covers
255: * the specified response id
256: */
257: private static Category categoryForId(int id) {
258: int catId = id / 100;
259: switch (catId) {
260: case 1:
261: return Category.INFORMATIONAL;
262: case 2:
263: return Category.SUCCESSFUL;
264: case 3:
265: return Category.REDIRECTION;
266: case 4:
267: return Category.CLIENT_ERROR;
268: case 5:
269: return Category.SERVER_ERROR;
270: default:
271: return null;
272: }
273: }
274:
275: private HttpResponseStatus(int code, String description,
276: boolean allowsMessageBody, boolean forcesConnectionClosure) {
277: RESPONSE_TABLE[code] = this ;
278: this .code = code;
279: this .category = categoryForId(code);
280: this .description = description;
281: this .allowsMessageBody = allowsMessageBody;
282: this .forcesConnectionClosure = forcesConnectionClosure;
283: }
284:
285: private Object readResolve() {
286: return forId(this .code);
287: }
288:
289: /**
290: * Category of response
291: *
292: * @author irvingd
293: */
294: public static enum Category {
295: /**
296: * Indicates a provisional response
297: */
298: INFORMATIONAL,
299:
300: /**
301: * Indicates that the client's request was successfully received,
302: * understood, and accepted
303: */
304: SUCCESSFUL,
305:
306: /**
307: * Indicates that further action needs to be taken by the user agent in order
308: * to fulfill the request
309: */
310: REDIRECTION,
311:
312: /**
313: * Indicates that the client seems to have erred
314: */
315: CLIENT_ERROR,
316:
317: /**
318: * Indicate that the server is aware that it has erred or is incapable
319: * of performing the request
320: */
321: SERVER_ERROR(true), ;
322:
323: private boolean defaultConnectionClosure;
324:
325: private Category() {
326: this (false);
327: }
328:
329: private Category(boolean defaultConnectionClosure) {
330: this .defaultConnectionClosure = defaultConnectionClosure;
331: }
332:
333: public boolean isDefaultConnectionClosure() {
334: return defaultConnectionClosure;
335: }
336: }
337: }
|