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.response;
018
019import static org.apache.juneau.commons.utils.Shorts.*;
020
021import org.apache.juneau.http.*;
022
023/**
024 * Represents an <c>HTTP 403 Forbidden</c> error response.
025 *
026 * <p>
027 * The request was valid, but the server is refusing action.
028 *
029 * <h5 class='section'>See Also:</h5><ul>
030 *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/NextGenRestClient">Next-Generation REST Client</a>
031 * </ul>
032 *
033 * @since 9.2.1
034 */
035@SuppressWarnings({
036   "java:S110" // intentional — mirrors the HTTP status-code response hierarchy
037})
038public class Forbidden extends BasicHttpException {
039
040   private static final long serialVersionUID = 1L;
041
042   /** HTTP status code */
043   public static final int STATUS_CODE = 403;
044
045   /** Reason phrase */
046   public static final String REASON_PHRASE = "Forbidden";
047
048   /**
049    * Constructor with no message.
050    */
051   public Forbidden() {
052      super(STATUS_CODE, REASON_PHRASE);
053   }
054
055   /**
056    * Constructor with a {@link String#format(String, Object...) String.format}-style message.
057    *
058    * @param msg The detail message. May be <jk>null</jk>.
059    *    Treated as a {@link String#format(String, Object...) String.format}-style format string (<c>%s</c> placeholders) when {@code args} is non-empty.
060    * @param args Optional message arguments.
061    */
062   public Forbidden(String msg, Object...args) {
063      super(STATUS_CODE, REASON_PHRASE, msg, args);
064   }
065
066   /**
067    * Constructor with a cause.
068    *
069    * @param cause The cause. May be <jk>null</jk>.
070    */
071   public Forbidden(Throwable cause) {
072      super(STATUS_CODE, REASON_PHRASE, cause, cause != null ? cause.getMessage() : null);
073   }
074
075   /**
076    * Constructor with a cause and a {@link String#format(String, Object...) String.format}-style message.
077    *
078    * @param cause The cause. May be <jk>null</jk>.
079    * @param msg The detail message. May be <jk>null</jk>.
080    *    Treated as a {@link String#format(String, Object...) String.format}-style format string (<c>%s</c> placeholders) when {@code args} is non-empty.
081    * @param args Optional message arguments.
082    */
083   public Forbidden(Throwable cause, String msg, Object...args) {
084      super(STATUS_CODE, REASON_PHRASE, cause, msg, args);
085   }
086
087   /**
088    * Copy constructor.
089    *
090    * @param copyFrom The instance to copy. Must not be <jk>null</jk>.
091    */
092   public Forbidden(Forbidden copyFrom) {
093      super(copyFrom);
094   }
095
096   @Override /* Overridden from BasicHttpException */
097   public Forbidden unmodifiable() {
098      return this instanceof UnmodifiableBean ? this : new Unmodifiable(this);
099   }
100
101   /**
102    * Unmodifiable point-in-time snapshot of the enclosing {@link Forbidden} exception.
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 Forbidden implements UnmodifiableBean {
109
110      private static final long serialVersionUID = 1L;
111
112      /**
113       * Constructor.
114       *
115       * @param copyFrom The exception to snapshot.  Must not be <jk>null</jk>.
116       */
117      @SuppressWarnings({
118         "java:S1699" // Paradigm intentionally calls the overridable freeze() from the ctor to deep-freeze sub-beans.
119      })
120      protected Unmodifiable(Forbidden copyFrom) {
121         super(copyFrom);
122         freeze();
123      }
124
125      @Override /* Overridden from BasicHttpException */
126      protected BasicHttpException modify(Runnable mutation) {
127         throw uoex("Bean is unmodifiable.");
128      }
129   }
130}