001// ***************************************************************************************************************************
002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
003// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
005// * with the License.  You may obtain a copy of the License at                                                              *
006// *                                                                                                                         *
007// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
008// *                                                                                                                         *
009// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
011// * specific language governing permissions and limitations under the License.                                              *
012// ***************************************************************************************************************************
013package org.apache.juneau.http.header;
014
015import static org.apache.juneau.internal.StringUtils.*;
016
017import java.util.function.*;
018
019import org.apache.juneau.assertions.*;
020import org.apache.juneau.http.*;
021
022/**
023 * Category of headers that consist of a single string value.
024 *
025 * <p>
026 * <h5 class='figure'>Example</h5>
027 * <p class='bcode w800'>
028 *    Host: www.myhost.com:8080
029 * </p>
030 *
031 * <ul class='seealso'>
032 *    <li class='extlink'>{@doc ExtRFC2616}
033 * </ul>
034*/
035public class BasicStringHeader extends BasicHeader {
036
037   private static final long serialVersionUID = 1L;
038
039   /**
040    * Convenience creator.
041    *
042    * @param name The header name.
043    * @param value
044    *    The header value.
045    *    <br>Can be any of the following:
046    *    <ul>
047    *       <li>{@link String}
048    *       <li>Anything else - Converted to <c>String</c> then parsed.
049    *    </ul>
050    * @return A new {@link BasicStringHeader} object, or <jk>null</jk> if the name or value is <jk>null</jk>.
051    */
052   public static BasicStringHeader of(String name, Object value) {
053      if (isEmpty(name) || value == null)
054         return null;
055      return new BasicStringHeader(name, value);
056   }
057
058   /**
059    * Convenience creator using supplier.
060    *
061    * <p>
062    * Header value is re-evaluated on each call to {@link #getValue()}.
063    *
064    * @param name The header name.
065    * @param value
066    *    The header value supplier.
067    *    <br>Can be any of the following:
068    *    <ul>
069    *       <li>{@link String}
070    *       <li>Anything else - Converted to <c>String</c> then parsed.
071    *    </ul>
072    * @return A new {@link BasicStringHeader} object, or <jk>null</jk> if the name or value is <jk>null</jk>.
073    */
074   public static BasicStringHeader of(String name, Supplier<?> value) {
075      if (isEmpty(name) || value == null)
076         return null;
077      return new BasicStringHeader(name, value);
078   }
079
080   private String parsed;
081
082   /**
083    * Constructor
084    *
085    * @param name The header name.
086    * @param value
087    *    <br>Can be any of the following:
088    *    <ul>
089    *       <li>{@link String}
090    *       <li>Anything else - Converted to <c>String</c> then parsed.
091    *       <li>A {@link Supplier} of anything on this list.
092    *    </ul>
093    */
094   public BasicStringHeader(String name, Object value) {
095      super(name, value);
096      if (! isSupplier(value))
097         parsed = getParsedValue();
098   }
099
100   /**
101    * Provides the ability to perform fluent-style assertions on this header.
102    *
103    * <h5 class='section'>Examples:</h5>
104    * <p class='bcode w800'>
105    *    <jc>// Validates the content type header is provided.</jc>
106    *    client
107    *       .get(<jsf>URL</jsf>)
108    *       .run()
109    *       .getStringHeader(<js>"Content-Type"</js>).assertThat().exists();
110    * </p>
111    *
112    * @return A new fluent assertion object.
113    * @throws AssertionError If assertion failed.
114    */
115   public FluentStringAssertion<BasicStringHeader> assertString() {
116      return new FluentStringAssertion<>(getValue(), this);
117   }
118
119   @Override /* Header */
120   public String getValue() {
121      return getParsedValue();
122   }
123
124   private String getParsedValue() {
125      if (parsed != null)
126         return parsed;
127      return stringify(getRawValue());
128   }
129}