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 static org.apache.juneau.commons.utils.ThrowableUtils.*;
020import static org.apache.juneau.commons.utils.Utils.*;
021
022import java.util.*;
023
024import org.apache.http.*;
025import org.apache.http.impl.*;
026import org.apache.http.message.*;
027
028/**
029 * A basic implementation of the {@link StatusLine} interface.
030 *
031 * <h5 class='section'>See Also:</h5><ul>
032 *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauRestCommonBasics">juneau-rest-common Basics</a>
033 * </ul>
034 */
035public class BasicStatusLine implements StatusLine {
036   /**
037    * Instantiates a new instance of this bean.
038    *
039    * @return A new bean.
040    */
041   public static BasicStatusLine create() {
042      return new BasicStatusLine();
043   }
044
045   /**
046    * Instantiates a new instance of this bean.
047    *
048    * @param statusCode The initial status code.
049    * @param reasonPhrase The initial reason phrase.
050    * @return A new bean.
051    */
052   public static BasicStatusLine create(int statusCode, String reasonPhrase) {
053      return new BasicStatusLine().setStatusCode(statusCode).setReasonPhrase(reasonPhrase);
054   }
055
056   private ProtocolVersion DEFAULT_PROTOCOL_VERSION = new ProtocolVersion("HTTP", 1, 1);
057
058   private ProtocolVersion protocolVersion = DEFAULT_PROTOCOL_VERSION;
059   private int statusCode;
060   private String reasonPhrase;
061   private ReasonPhraseCatalog reasonPhraseCatalog;
062   private Locale locale = Locale.getDefault();
063   private boolean unmodifiable;
064
065   /**
066    * Constructor.
067    */
068   public BasicStatusLine() {}
069
070   /**
071    * Copy constructor.
072    *
073    * @param copyFrom The status line being copied.
074    */
075   protected BasicStatusLine(BasicStatusLine copyFrom) {
076      this.protocolVersion = copyFrom.protocolVersion;
077      this.statusCode = copyFrom.statusCode;
078      this.reasonPhrase = copyFrom.reasonPhrase;
079      this.locale = copyFrom.locale;
080   }
081
082   /**
083    * Returns a copy of this bean.
084    *
085    * @return A copy of this bean.
086    */
087   public BasicStatusLine copy() {
088      return new BasicStatusLine(this);
089   }
090
091   /**
092    * Returns the locale of this status line.
093    *
094    * @return The locale of this status line.
095    */
096   public Locale getLocale() { return locale; }
097
098   @Override /* Overridden from StatusLine */
099   public ProtocolVersion getProtocolVersion() { return protocolVersion; }
100
101   @Override /* Overridden from StatusLine */
102   public String getReasonPhrase() {
103      if (reasonPhrase == null) {
104         ReasonPhraseCatalog rfc = firstNonNull(reasonPhraseCatalog, EnglishReasonPhraseCatalog.INSTANCE);
105         return rfc.getReason(statusCode, locale);
106      }
107      return reasonPhrase;
108   }
109
110   @Override /* Overridden from StatusLine */
111   public int getStatusCode() { return statusCode; }
112
113   /**
114    * Sets the locale used to retrieve reason phrases.
115    *
116    * <p>
117    * If not specified, uses {@link Locale#getDefault()}.
118    *
119    * @param value The new value.
120    * @return This object.
121    */
122   public BasicStatusLine setLocale(Locale value) {
123      assertModifiable();
124      locale = value;
125      return this;
126   }
127
128   /**
129    * Sets the protocol version on the status line.
130    *
131    * <p>
132    * If not specified, <js>"HTTP/1.1"</js> will be used.
133    *
134    * @param value The new value.
135    * @return This object.
136    */
137   public BasicStatusLine setProtocolVersion(ProtocolVersion value) {
138      assertModifiable();
139      protocolVersion = value;
140      return this;
141   }
142
143   /**
144    * Sets the reason phrase on the status line.
145    *
146    * <p>
147    * If not specified, the reason phrase will be retrieved from the reason phrase catalog
148    * using the locale on this bean.
149    *
150    * @param value The new value.
151    * @return This object.
152    */
153   public BasicStatusLine setReasonPhrase(String value) {
154      assertModifiable();
155      reasonPhrase = value;
156      return this;
157   }
158
159   /**
160    * Sets the reason phrase catalog used to retrieve reason phrases.
161    *
162    * <p>
163    * If not specified, uses {@link EnglishReasonPhraseCatalog}.
164    *
165    * @param value The new value.
166    * @return This object.
167    */
168   public BasicStatusLine setReasonPhraseCatalog(ReasonPhraseCatalog value) {
169      assertModifiable();
170      reasonPhraseCatalog = value;
171      return this;
172   }
173
174   /**
175    * Sets the status code on the status line.
176    *
177    * <p>
178    * If not specified, <c>0</c> will be used.
179    *
180    * @param value The new value.
181    * @return This object.
182    */
183   public BasicStatusLine setStatusCode(int value) {
184      assertModifiable();
185      statusCode = value;
186      return this;
187   }
188
189   /**
190    * Specifies whether this bean should be unmodifiable.
191    * <p>
192    * When enabled, attempting to set any properties on this bean will cause an {@link UnsupportedOperationException}.
193    *
194    * @return This object.
195    */
196   public BasicStatusLine setUnmodifiable() {
197      unmodifiable = true;
198      return this;
199   }
200
201   @Override /* Overridden from Object */
202   public String toString() {
203      return BasicLineFormatter.INSTANCE.formatStatusLine(null, this).toString();
204   }
205
206   /**
207    * Throws an {@link UnsupportedOperationException} if the unmodifiable flag is set on this bean.
208    */
209   protected final void assertModifiable() {
210      if (unmodifiable)
211         throw unsupportedOp("Bean is read-only");
212   }
213}