001// ***************************************************************************************************************************
002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
003// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
005// * with the License.  You may obtain a copy of the License at                                                              *
006// *                                                                                                                         *
007// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
008// *                                                                                                                         *
009// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
011// * specific language governing permissions and limitations under the License.                                              *
012// ***************************************************************************************************************************
013package org.apache.juneau.http;
014
015import static org.apache.juneau.internal.ObjectUtils.*;
016
017import java.util.*;
018
019import org.apache.http.*;
020import org.apache.http.impl.*;
021import org.apache.http.message.*;
022import org.apache.juneau.http.BasicStatusLine;
023import org.apache.juneau.internal.*;
024
025/**
026 * A basic implementation of the {@link StatusLine} interface.
027 *
028 * <h5 class='section'>See Also:</h5><ul>
029 *    <li class='link'><a class="doclink" href="../../../../index.html#juneau-rest-common">juneau-rest-common</a>
030 * </ul>
031 */
032@FluentSetters
033public class BasicStatusLine implements StatusLine {
034
035   //-----------------------------------------------------------------------------------------------------------------
036   // Static
037   //-----------------------------------------------------------------------------------------------------------------
038
039   /**
040    * Instantiates a new instance of this bean.
041    *
042    * @return A new bean.
043    */
044   public static BasicStatusLine create() {
045      return new BasicStatusLine();
046   }
047
048   /**
049    * Instantiates a new instance of this bean.
050    *
051    * @param statusCode The initial status code.
052    * @param reasonPhrase The initial reason phrase.
053    * @return A new bean.
054    */
055   public static BasicStatusLine create(int statusCode, String reasonPhrase) {
056      return new BasicStatusLine().setStatusCode(statusCode).setReasonPhrase(reasonPhrase);
057   }
058
059   //-----------------------------------------------------------------------------------------------------------------
060   // Instance
061   //-----------------------------------------------------------------------------------------------------------------
062
063   private ProtocolVersion DEFAULT_PROTOCOL_VERSION = new ProtocolVersion("HTTP", 1, 1);
064
065   private ProtocolVersion protocolVersion = DEFAULT_PROTOCOL_VERSION;
066   private int statusCode = 0;
067   private String reasonPhrase;
068   private ReasonPhraseCatalog reasonPhraseCatalog;
069   private Locale locale = Locale.getDefault();
070   private boolean unmodifiable;
071
072   /**
073    * Constructor.
074    */
075   public BasicStatusLine() {
076   }
077
078   /**
079    * Copy constructor.
080    *
081    * @param copyFrom The status line being copied.
082    */
083   protected BasicStatusLine(BasicStatusLine copyFrom) {
084      this.protocolVersion = copyFrom.protocolVersion;
085      this.statusCode = copyFrom.statusCode;
086      this.reasonPhrase = copyFrom.reasonPhrase;
087      this.locale = copyFrom.locale;
088   }
089
090   /**
091    * Returns a copy of this bean.
092    *
093    * @return A copy of this bean.
094    */
095   public BasicStatusLine copy() {
096      return new BasicStatusLine(this);
097   }
098
099   //-----------------------------------------------------------------------------------------------------------------
100   // Properties
101   //-----------------------------------------------------------------------------------------------------------------
102
103   /**
104    * Specifies whether this bean should be unmodifiable.
105    * <p>
106    * When enabled, attempting to set any properties on this bean will cause an {@link UnsupportedOperationException}.
107    *
108    * @return This object.
109    */
110   @FluentSetter
111   public BasicStatusLine setUnmodifiable() {
112      unmodifiable = true;
113      return this;
114   }
115
116   /**
117    * Throws an {@link UnsupportedOperationException} if the unmodifiable flag is set on this bean.
118    */
119   protected final void assertModifiable() {
120      if (unmodifiable)
121         throw new UnsupportedOperationException("Bean is read-only");
122   }
123
124   @Override /* StatusLine */
125   public ProtocolVersion getProtocolVersion() {
126      return protocolVersion;
127   }
128
129   /**
130    * Sets the protocol version on the status line.
131    *
132    * <p>
133    * If not specified, <js>"HTTP/1.1"</js> will be used.
134    *
135    * @param value The new value.
136    * @return This object.
137    */
138   @FluentSetter
139   public BasicStatusLine setProtocolVersion(ProtocolVersion value) {
140      assertModifiable();
141      this.protocolVersion = value;
142      return this;
143   }
144
145   @Override /* StatusLine */
146   public int getStatusCode() {
147      return statusCode;
148   }
149
150   /**
151    * Sets the status code on the status line.
152    *
153    * <p>
154    * If not specified, <c>0</c> will be used.
155    *
156    * @param value The new value.
157    * @return This object.
158    */
159   @FluentSetter
160   public BasicStatusLine setStatusCode(int value) {
161      assertModifiable();
162      this.statusCode = value;
163      return this;
164   }
165
166   @Override /* StatusLine */
167   public String getReasonPhrase() {
168      if (reasonPhrase == null) {
169         ReasonPhraseCatalog rfc = firstNonNull(reasonPhraseCatalog, EnglishReasonPhraseCatalog.INSTANCE);
170         return rfc.getReason(statusCode, locale);
171      }
172      return reasonPhrase;
173   }
174
175   /**
176    * Sets the reason phrase on the status line.
177    *
178    * <p>
179    * If not specified, the reason phrase will be retrieved from the reason phrase catalog
180    * using the locale on this bean.
181    *
182    * @param value The new value.
183    * @return This object.
184    */
185   @FluentSetter
186   public BasicStatusLine setReasonPhrase(String value) {
187      assertModifiable();
188      this.reasonPhrase = value;
189      return this;
190   }
191
192   /**
193    * Sets the reason phrase catalog used to retrieve reason phrases.
194    *
195    * <p>
196    * If not specified, uses {@link EnglishReasonPhraseCatalog}.
197    *
198    * @param value The new value.
199    * @return This object.
200    */
201   @FluentSetter
202   public BasicStatusLine setReasonPhraseCatalog(ReasonPhraseCatalog value) {
203      assertModifiable();
204      this.reasonPhraseCatalog = value;
205      return this;
206   }
207
208   /**
209    * Returns the locale of this status line.
210    *
211    * @return The locale of this status line.
212    */
213   public Locale getLocale() {
214      return locale;
215   }
216
217   /**
218    * Sets the locale used to retrieve reason phrases.
219    *
220    * <p>
221    * If not specified, uses {@link Locale#getDefault()}.
222    *
223    * @param value The new value.
224    * @return This object.
225    */
226   @FluentSetter
227   public BasicStatusLine setLocale(Locale value) {
228      assertModifiable();
229      this.locale = value;
230      return this;
231   }
232
233   @Override /* Object */
234   public String toString() {
235      return BasicLineFormatter.INSTANCE.formatStatusLine(null, this).toString();
236   }
237
238   // <FluentSetters>
239
240   // </FluentSetters>
241}