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.Shorts.*; 020 021import java.util.*; 022import java.util.function.*; 023 024import org.apache.juneau.http.*; 025 026/** 027 * Root concrete implementation of {@link HttpHeader}. 028 * 029 * <p> 030 * Holds a name/value pair where the value may be supplied eagerly (as a {@link String}) or lazily 031 * (via a {@link Supplier}). A lazy supplier returning {@code null} signals that the header should 032 * be omitted from the request. 033 * 034 * <p> 035 * Create instances via the static factory methods: 036 * <p class='bjava'> 037 * <jc>// Eager</jc> 038 * HttpHeader <jv>h1</jv> = HttpHeaderBean.<jsm>of</jsm>(<js>"X-My-Header"</js>, <js>"my-value"</js>); 039 * 040 * <jc>// Lazy — evaluated at request-send time</jc> 041 * HttpHeader <jv>h2</jv> = HttpHeaderBean.<jsm>of</jsm>(<js>"Authorization"</js>, () -> tokenSupplier.get()); 042 * </p> 043 * 044 * <h5 class='section'>See Also:</h5><ul> 045 * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/NextGenRestClient">Next-Generation REST Client</a> 046 * </ul> 047 * 048 * @since 9.2.1 049 */ 050public class HttpHeaderBean implements HttpHeader { 051 052 private final String name; 053 private final Supplier<String> valueSupplier; 054 055 /** 056 * Constructor. 057 * 058 * @param name The header name. Must not be <jk>null</jk>. 059 * @param value The header value. May be <jk>null</jk>. 060 */ 061 protected HttpHeaderBean(String name, String value) { 062 this.name = reqnn("name", name); 063 this.valueSupplier = () -> value; 064 } 065 066 /** 067 * Constructor with lazy value supplier. 068 * 069 * @param name The header name. Must not be <jk>null</jk>. 070 * @param valueSupplier Supplier that provides the header value at request time. Must not be <jk>null</jk>. 071 */ 072 protected HttpHeaderBean(String name, Supplier<String> valueSupplier) { 073 this.name = reqnn("name", name); 074 this.valueSupplier = reqnn("valueSupplier", valueSupplier); 075 } 076 077 /** 078 * Creates an {@link HttpHeaderBean} with an eager string value. 079 * 080 * @param name The header name. Must not be <jk>null</jk>. 081 * @param value The header value. May be <jk>null</jk> to indicate the header should be omitted. 082 * @return A new instance. Never <jk>null</jk>. 083 */ 084 public static HttpHeaderBean of(String name, String value) { 085 return new HttpHeaderBean(name, value); 086 } 087 088 /** 089 * Creates an {@link HttpHeaderBean} with a lazy value supplier. 090 * 091 * <p> 092 * The supplier is evaluated at request-send time; if it returns {@code null} the header is omitted. 093 * 094 * @param name The header name. Must not be <jk>null</jk>. 095 * @param valueSupplier Supplier for the header value. Must not be <jk>null</jk>. 096 * @return A new instance. Never <jk>null</jk>. 097 */ 098 public static HttpHeaderBean of(String name, Supplier<String> valueSupplier) { 099 return new HttpHeaderBean(name, valueSupplier); 100 } 101 102 @Override /* HttpHeader */ 103 public String getName() { 104 return name; 105 } 106 107 @Override /* HttpHeader */ 108 public String getValue() { 109 return valueSupplier.get(); 110 } 111 112 /** 113 * Returns {@code true} if the header value is equal to the given value, ignoring case. 114 * 115 * @param other The value to compare against. May be <jk>null</jk>. 116 * @return {@code true} if the value is equal, ignoring case. 117 */ 118 public boolean equalsIgnoreCase(String other) { 119 return eqic(getValue(), other); 120 } 121 122 @Override /* Object */ 123 public String toString() { 124 return name + ": " + getValue(); 125 } 126 127 @Override /* Object */ 128 public boolean equals(Object obj) { 129 return (obj instanceof HttpHeaderBean o2) && eq(this, o2, (x, y) -> eqic(x.name, y.name) && eq(x.getValue(), y.getValue())); 130 } 131 132 @Override /* Object */ 133 public int hashCode() { 134 return h(name.toLowerCase(Locale.ROOT), getValue()); 135 } 136}