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.common.internal.StringUtils.*; 016import static org.apache.juneau.internal.CollectionUtils.*; 017 018import java.util.*; 019import java.util.function.*; 020 021import org.apache.http.*; 022import org.apache.juneau.assertions.*; 023 024/** 025 * Category of headers that consist of a single string value. 026 * 027 * <p> 028 * <h5 class='figure'>Example</h5> 029 * <p class='bcode'> 030 * Host: www.myhost.com:8080 031 * </p> 032 * 033 * <h5 class='section'>See Also:</h5><ul> 034 * <li class='link'><a class="doclink" href="../../../../../index.html#juneau-rest-common">juneau-rest-common</a> 035 * <li class='extlink'><a class="doclink" href="https://www.w3.org/Protocols/rfc2616/rfc2616.html">Hypertext Transfer Protocol -- HTTP/1.1</a> 036 * </ul> 037 * 038 * @serial exclude 039 */ 040public class BasicStringHeader extends BasicHeader { 041 042 //----------------------------------------------------------------------------------------------------------------- 043 // Static 044 //----------------------------------------------------------------------------------------------------------------- 045 046 private static final long serialVersionUID = 1L; 047 048 /** 049 * Static creator. 050 * 051 * @param name The header name. 052 * @param value 053 * The header value. 054 * <br>Can be <jk>null</jk>. 055 * @return A new header bean, or <jk>null</jk> if the value is <jk>null</jk>. 056 * @throws IllegalArgumentException If name is <jk>null</jk> or empty. 057 */ 058 public static BasicStringHeader of(String name, String value) { 059 return value == null ? null : new BasicStringHeader(name, value); 060 } 061 062 /** 063 * Static creator with delayed value. 064 * 065 * <p> 066 * Header value is re-evaluated on each call to {@link #getValue()}. 067 * 068 * @param name The header name. 069 * @param value 070 * The supplier of the header value. 071 * <br>Can be <jk>null</jk>. 072 * @return A new header bean, or <jk>null</jk> if the value is <jk>null</jk>. 073 * @throws IllegalArgumentException If name is <jk>null</jk> or empty. 074 */ 075 public static BasicStringHeader of(String name, Supplier<String> value) { 076 return value == null ? null : new BasicStringHeader(name, value); 077 } 078 079 /** 080 * Creates a {@link Header} from a name/value pair string (e.g. <js>"Foo: bar"</js>) 081 * 082 * @param pair The pair string. 083 * @return A new header bean. 084 */ 085 public static BasicStringHeader ofPair(String pair) { 086 if (pair == null) 087 return null; 088 int i = pair.indexOf(':'); 089 if (i == -1) 090 i = pair.indexOf('='); 091 if (i == -1) 092 return of(pair, ""); 093 return of(pair.substring(0,i).trim(), pair.substring(i+1).trim()); 094 } 095 096 //----------------------------------------------------------------------------------------------------------------- 097 // Instance 098 //----------------------------------------------------------------------------------------------------------------- 099 100 private final String value; 101 private final Supplier<String> supplier; 102 103 /** 104 * Constructor. 105 * 106 * @param name The header name. 107 * @param value 108 * The header value. 109 * <br>Can be <jk>null</jk>. 110 * @throws IllegalArgumentException If name is <jk>null</jk> or empty. 111 */ 112 public BasicStringHeader(String name, String value) { 113 super(name, value); 114 this.value = value; 115 this.supplier = null; 116 } 117 118 /** 119 * Constructor with delayed value. 120 * 121 * <p> 122 * Header value is re-evaluated on each call to {@link #getValue()}. 123 * 124 * @param name The header name. 125 * @param value 126 * The supplier of the header value. 127 * <br>Can be <jk>null</jk>. 128 * @throws IllegalArgumentException If name is <jk>null</jk> or empty. 129 */ 130 public BasicStringHeader(String name, Supplier<String> value) { 131 super(name, null); 132 this.value = null; 133 this.supplier = value; 134 } 135 136 @Override /* Header */ 137 public String getValue() { 138 return stringify(value()); 139 } 140 141 @Override /* BasicHeader */ 142 public Optional<String> asString() { 143 return optional(value()); 144 } 145 146 /** 147 * Provides the ability to perform fluent-style assertions on this header. 148 * 149 * <h5 class='section'>Examples:</h5> 150 * <p class='bjava'> 151 * <jc>// Validates the content type header is provided.</jc> 152 * <jv>client</jv> 153 * .get(<jsf>URL</jsf>) 154 * .run() 155 * .getHeader(<js>"Content-Type"</js>).assertString().exists(); 156 * </p> 157 * 158 * @return A new fluent assertion object. 159 * @throws AssertionError If assertion failed. 160 */ 161 public FluentStringAssertion<BasicStringHeader> assertString() { 162 return new FluentStringAssertion<>(value(), this); 163 } 164 165 166 /** 167 * Return the value if present, otherwise return <c>other</c>. 168 * 169 * <p> 170 * This is a shortened form for calling <c>asString().orElse(<jv>other</jv>)</c>. 171 * 172 * @param other The value to be returned if there is no value present, can be <jk>null</jk>. 173 * @return The value, if present, otherwise <c>other</c>. 174 */ 175 @Override 176 public String orElse(String other) { 177 String x = value(); 178 return x != null ? x : other; 179 } 180 181 private String value() { 182 if (supplier != null) 183 return supplier.get(); 184 return value; 185 } 186}