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.message; 029 030import java.util.Locale; 031 032import org.apache.http.HttpEntity; 033import org.apache.http.HttpResponse; 034import org.apache.http.HttpVersion; 035import org.apache.http.ProtocolVersion; 036import org.apache.http.ReasonPhraseCatalog; 037import org.apache.http.StatusLine; 038import org.apache.http.util.Args; 039 040/** 041 * Basic implementation of {@link HttpResponse}. 042 * 043 * @see org.apache.http.impl.DefaultHttpResponseFactory 044 * 045 * @since 4.0 046 */ 047public class BasicHttpResponse extends AbstractHttpMessage implements HttpResponse { 048 049 private StatusLine statusline; 050 private ProtocolVersion ver; 051 private int code; 052 private String reasonPhrase; 053 private HttpEntity entity; 054 private final ReasonPhraseCatalog reasonCatalog; 055 private Locale locale; 056 057 /** 058 * Creates a new response. 059 * This is the constructor to which all others map. 060 * 061 * @param statusline the status line 062 * @param catalog the reason phrase catalog, or 063 * {@code null} to disable automatic 064 * reason phrase lookup 065 * @param locale the locale for looking up reason phrases, or 066 * {@code null} for the system locale 067 */ 068 public BasicHttpResponse(final StatusLine statusline, 069 final ReasonPhraseCatalog catalog, 070 final Locale locale) { 071 super(); 072 this.statusline = Args.notNull(statusline, "Status line"); 073 this.ver = statusline.getProtocolVersion(); 074 this.code = statusline.getStatusCode(); 075 this.reasonPhrase = statusline.getReasonPhrase(); 076 this.reasonCatalog = catalog; 077 this.locale = locale; 078 } 079 080 /** 081 * Creates a response from a status line. 082 * The response will not have a reason phrase catalog and 083 * use the system default locale. 084 * 085 * @param statusline the status line 086 */ 087 public BasicHttpResponse(final StatusLine statusline) { 088 super(); 089 this.statusline = Args.notNull(statusline, "Status line"); 090 this.ver = statusline.getProtocolVersion(); 091 this.code = statusline.getStatusCode(); 092 this.reasonPhrase = statusline.getReasonPhrase(); 093 this.reasonCatalog = null; 094 this.locale = null; 095 } 096 097 /** 098 * Creates a response from elements of a status line. 099 * The response will not have a reason phrase catalog and 100 * use the system default locale. 101 * 102 * @param ver the protocol version of the response 103 * @param code the status code of the response 104 * @param reason the reason phrase to the status code, or 105 * {@code null} 106 */ 107 public BasicHttpResponse(final ProtocolVersion ver, 108 final int code, 109 final String reason) { 110 super(); 111 Args.notNegative(code, "Status code"); 112 this.statusline = null; 113 this.ver = ver; 114 this.code = code; 115 this.reasonPhrase = reason; 116 this.reasonCatalog = null; 117 this.locale = null; 118 } 119 120 121 // non-javadoc, see interface HttpMessage 122 @Override 123 public ProtocolVersion getProtocolVersion() { 124 return this.ver; 125 } 126 127 // non-javadoc, see interface HttpResponse 128 @Override 129 public StatusLine getStatusLine() { 130 if (this.statusline == null) { 131 this.statusline = new BasicStatusLine( 132 this.ver != null ? this.ver : HttpVersion.HTTP_1_1, 133 this.code, 134 this.reasonPhrase != null ? this.reasonPhrase : getReason(this.code)); 135 } 136 return this.statusline; 137 } 138 139 // non-javadoc, see interface HttpResponse 140 @Override 141 public HttpEntity getEntity() { 142 return this.entity; 143 } 144 145 @Override 146 public Locale getLocale() { 147 return this.locale; 148 } 149 150 // non-javadoc, see interface HttpResponse 151 @Override 152 public void setStatusLine(final StatusLine statusline) { 153 this.statusline = Args.notNull(statusline, "Status line"); 154 this.ver = statusline.getProtocolVersion(); 155 this.code = statusline.getStatusCode(); 156 this.reasonPhrase = statusline.getReasonPhrase(); 157 } 158 159 // non-javadoc, see interface HttpResponse 160 @Override 161 public void setStatusLine(final ProtocolVersion ver, final int code) { 162 Args.notNegative(code, "Status code"); 163 this.statusline = null; 164 this.ver = ver; 165 this.code = code; 166 this.reasonPhrase = null; 167 } 168 169 // non-javadoc, see interface HttpResponse 170 @Override 171 public void setStatusLine( 172 final ProtocolVersion ver, final int code, final String reason) { 173 Args.notNegative(code, "Status code"); 174 this.statusline = null; 175 this.ver = ver; 176 this.code = code; 177 this.reasonPhrase = reason; 178 } 179 180 // non-javadoc, see interface HttpResponse 181 @Override 182 public void setStatusCode(final int code) { 183 Args.notNegative(code, "Status code"); 184 this.statusline = null; 185 this.code = code; 186 this.reasonPhrase = null; 187 } 188 189 // non-javadoc, see interface HttpResponse 190 @Override 191 public void setReasonPhrase(final String reason) { 192 this.statusline = null; 193 this.reasonPhrase = reason; 194 } 195 196 // non-javadoc, see interface HttpResponse 197 @Override 198 public void setEntity(final HttpEntity entity) { 199 this.entity = entity; 200 } 201 202 @Override 203 public void setLocale(final Locale locale) { 204 this.locale = Args.notNull(locale, "Locale"); 205 this.statusline = null; 206 } 207 208 /** 209 * Looks up a reason phrase. 210 * This method evaluates the currently set catalog and locale. 211 * It also handles a missing catalog. 212 * 213 * @param code the status code for which to look up the reason 214 * 215 * @return the reason phrase, or {@code null} if there is none 216 */ 217 protected String getReason(final int code) { 218 return this.reasonCatalog != null ? this.reasonCatalog.getReason(code, 219 this.locale != null ? this.locale : Locale.getDefault()) : null; 220 } 221 222 @Override 223 public String toString() { 224 final StringBuilder sb = new StringBuilder(); 225 sb.append(getStatusLine()); 226 sb.append(' '); 227 sb.append(this.headergroup); 228 if (this.entity != null) { 229 sb.append(' '); 230 sb.append(this.entity); 231 } 232 return sb.toString(); 233 } 234 235}