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.header;
018
019import static org.apache.juneau.commons.utils.Utils.*;
020
021import java.net.*;
022import java.util.*;
023import java.util.function.*;
024
025/**
026 * Category of headers that consist of a single URL value.
027 *
028 * <p>
029 * <h5 class='figure'>Example</h5>
030 * <p class='bcode'>
031 *    Location: http://www.w3.org/pub/WWW/People.html
032 * </p>
033 *
034 * <h5 class='section'>See Also:</h5><ul>
035 *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauRestCommonBasics">juneau-rest-common Basics</a>
036 *    <li class='extlink'><a class="doclink" href="https://www.w3.org/Protocols/rfc2616/rfc2616.html">Hypertext Transfer Protocol -- HTTP/1.1</a>
037 * </ul>
038 *
039 * @serial exclude
040 */
041public class BasicUriHeader extends BasicHeader {
042   private static final long serialVersionUID = 1L;
043
044   /**
045    * Static creator.
046    *
047    * @param name The header name.
048    * @param value
049    *    The header value.
050    *    <br>Must be parsable by {@link URI#create(String)}.
051    *    <br>Can be <jk>null</jk>.
052    * @return A new header bean, or <jk>null</jk> if the value is <jk>null</jk>.
053    * @throws IllegalArgumentException If name is <jk>null</jk> or empty.
054    */
055   public static BasicUriHeader of(String name, String value) {
056      return value == null ? null : new BasicUriHeader(name, value);
057   }
058
059   /**
060    * Static creator with delayed value.
061    *
062    * <p>
063    * Header value is re-evaluated on each call to {@link #getValue()}.
064    *
065    * @param name The header name.
066    * @param value
067    *    The supplier of the header value.
068    *    <br>Can be <jk>null</jk>.
069    * @return A new header bean, or <jk>null</jk> if the value is <jk>null</jk>.
070    * @throws IllegalArgumentException If name is <jk>null</jk> or empty.
071    */
072   public static BasicUriHeader of(String name, Supplier<URI> value) {
073      return value == null ? null : new BasicUriHeader(name, value);
074   }
075
076   /**
077    * Static creator.
078    *
079    * @param name The header name.
080    * @param value
081    *    The header value.
082    *    <br>Can be <jk>null</jk>.
083    * @return A new header bean, or <jk>null</jk> if the value is <jk>null</jk>.
084    * @throws IllegalArgumentException If name is <jk>null</jk> or empty.
085    */
086   public static BasicUriHeader of(String name, URI value) {
087      return value == null ? null : new BasicUriHeader(name, value);
088   }
089
090   private final URI value;
091   private final Supplier<URI> supplier;
092
093   /**
094    * Constructor.
095    *
096    * @param name The header name.
097    * @param value
098    *    The header value.
099    *    <br>Must be parsable by {@link URI#create(String)}.
100    *    <br>Can be <jk>null</jk>.
101    * @throws IllegalArgumentException If name is <jk>null</jk> or empty.
102    */
103   public BasicUriHeader(String name, String value) {
104      super(name, value);
105      this.value = e(value) ? null : URI.create(value);
106      this.supplier = null;
107   }
108
109   /**
110    * Constructor with delayed value.
111    *
112    * <p>
113    * Header value is re-evaluated on each call to {@link #getValue()}.
114    *
115    * @param name The header name.
116    * @param value
117    *    The supplier of the header value.
118    *    <br>Can be <jk>null</jk>.
119    * @throws IllegalArgumentException If name is <jk>null</jk> or empty.
120    */
121   public BasicUriHeader(String name, Supplier<URI> value) {
122      super(name, null);
123      this.value = null;
124      supplier = value;
125   }
126
127   /**
128    * Constructor.
129    *
130    * @param name The header name.
131    * @param value
132    *    The header value.
133    *    <br>Can be <jk>null</jk>.
134    * @throws IllegalArgumentException If name is <jk>null</jk> or empty.
135    */
136   public BasicUriHeader(String name, URI value) {
137      super(name, s(value));
138      this.value = value;
139      this.supplier = null;
140   }
141
142   /**
143    * Returns the header value as a {@link URI} wrapped in an {@link Optional}.
144    *
145    * @return The header value as a {@link URI} wrapped in an {@link Optional}.  Never <jk>null</jk>.
146    */
147   public Optional<URI> asUri() {
148      return opt(value());
149   }
150
151   @Override /* Overridden from Header */
152   public String getValue() { return s(value()); }
153
154   /**
155    * Return the value if present, otherwise return <c>other</c>.
156    *
157    * <p>
158    * This is a shortened form for calling <c>asUri().orElse(<jv>other</jv>)</c>.
159    *
160    * @param other The value to be returned if there is no value present, can be <jk>null</jk>.
161    * @return The value, if present, otherwise <c>other</c>.
162    */
163   public URI orElse(URI other) {
164      URI x = value();
165      return nn(x) ? x : other;
166   }
167
168   /**
169    * Returns the header value as a {@link URI} wrapped in an {@link Optional}.
170    *
171    * @return The header value as a {@link URI} wrapped in an {@link Optional}.  Never <jk>null</jk>.
172    */
173   public URI toUri() {
174      return value();
175   }
176
177   private URI value() {
178      if (nn(supplier))
179         return supplier.get();
180      return value;
181   }
182}