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.classic.response;
018
019import static org.apache.juneau.commons.utils.Shorts.*;
020import static org.apache.juneau.http.classic.response.Found.*;
021
022import org.apache.http.*;
023import org.apache.juneau.commons.*;
024import org.apache.juneau.http.*;
025import org.apache.juneau.http.classic.*;
026
027/**
028 * Represents an <c>HTTP 302 Found</c> response.
029 *
030 * <p>
031 * Tells the client to look at (browse to) another url. 302 has been superseded by 303 and 307.
032 * This is an example of industry practice contradicting the standard.
033 * The HTTP/1.0 specification (RFC 1945) required the client to perform a temporary redirect (the original describing phrase was "Moved Temporarily"), but popular browsers implemented 302 with the functionality of a 303 See Other.
034 * Therefore, HTTP/1.1 added status codes 303 and 307 to distinguish between the two behaviours.
035 * However, some Web applications and frameworks use the 302 status code as if it were the 303.
036 *
037 * <h5 class='section'>See Also:</h5><ul>
038 *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauRestCommon">juneau-rest-common</a>
039 * </ul>
040 */
041@Response
042@StatusCode(STATUS_CODE)
043@Schema(description = REASON_PHRASE)
044public class Found extends BasicHttpResponse<Found> {
045
046   /** HTTP status code */
047   public static final int STATUS_CODE = 302;
048
049   /** Default message */
050   public static final String REASON_PHRASE = "Found";
051
052   /** Default status line */
053   private static final BasicStatusLine STATUS_LINE = BasicStatusLine.create(STATUS_CODE, REASON_PHRASE);
054
055   /** Default unmodifiable instance */
056   public static final Found INSTANCE = new Found().unmodifiable();
057
058   /**
059    * Constructor.
060    */
061   public Found() {
062      super(STATUS_LINE);
063   }
064
065   /**
066    * Copy constructor.
067    *
068    * @param copyFrom The bean to copy from.  Must not be <jk>null</jk>.
069    */
070   public Found(Found copyFrom) {
071      super(copyFrom);
072   }
073
074   /**
075    * Constructor.
076    *
077    * <p>
078    * This is the constructor used when parsing an HTTP response.
079    *
080    * @param response The HTTP response to copy from.  Must not be <jk>null</jk>.
081    * @throws IllegalArgumentException If HTTP response status code does not match what was expected.
082    */
083   public Found(HttpResponse response) {
084      super(requireStatus(response, STATUS_CODE));
085   }
086
087   /**
088    * Creates a builder for this class initialized with the contents of this bean.
089    *
090    * @return A new builder bean.
091    */
092   public Found copy() {
093      return new Found(this);
094   }
095
096   @Override /* Overridden from BasicHttpResponse */
097   public Found unmodifiable() {
098      return this instanceof UnmodifiableBean ? this : new Unmodifiable(this);
099   }
100
101   /**
102    * Unmodifiable point-in-time snapshot of the enclosing {@link Found} response.
103    *
104    * <p>
105    * Its only behavioral override is {@link #modify(Runnable)}, which throws — because all mutation is funneled through
106    * {@code modify(...)}, this single override freezes the entire mutation surface.
107    */
108   public static class Unmodifiable extends Found implements UnmodifiableBean {
109
110      /**
111       * Constructor.
112       *
113       * @param copyFrom The response to snapshot.  Must not be <jk>null</jk>.
114       */
115      @SuppressWarnings({
116         "java:S1699" // Paradigm intentionally calls the overridable freeze() from the ctor to deep-freeze sub-beans.
117      })
118      protected Unmodifiable(Found copyFrom) {
119         super(copyFrom);
120         freeze();
121      }
122
123      @Override /* Overridden from BasicHttpResponse */
124      protected Found modify(Runnable mutation) {
125         throw uoex("Bean is unmodifiable.");
126      }
127   }
128}