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