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 (the 006 * "License"); you may not use this file except in compliance with the 007 * 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; 018import static org.apache.juneau.commons.utils.Shorts.*; 019 020import java.util.*; 021import java.util.function.*; 022 023import org.apache.juneau.commons.utils.*; 024 025/** 026 * Base for boolean headers. 027 * 028 * @since 9.2.1 029 */ 030@SuppressWarnings({ 031 "java:S2160", // equals() on HttpHeaderBean uses name + getValue(); typed state is reflected in getValue() 032 "java:S9149", // Public Juneau DSL factory; hiding parent of()/create() is intentional. 033 "unchecked" // Supplier<?> branches cast to typed suppliers after lazy-mode check 034}) 035public class HttpBooleanHeader extends HttpHeaderBean { 036 037 public static final int LAZY_WIRE_STRING = 0; 038 public static final int LAZY_BOOLEAN = 1; 039 040 private final Boolean value; 041 private final Supplier<?> lazySupplier; 042 private final int lazyMode; 043 044 /** 045 * Creates an {@link HttpBooleanHeader} by parsing the given wire-format value. 046 * 047 * @param name Header name. Must not be {@code null}. 048 * @param wireValue Wire value (e.g. {@code "true"}). May be {@code null}. 049 * @return A new instance. Never {@code null}. 050 */ 051 public static HttpBooleanHeader of(String name, String wireValue) { 052 return new HttpBooleanHeader(name, wireValue); 053 } 054 055 /** 056 * Creates an {@link HttpBooleanHeader} with the given typed value. 057 * 058 * @param name Header name. Must not be {@code null}. 059 * @param typedValue The boolean value. May be {@code null}. 060 * @return A new instance. Never {@code null}. 061 */ 062 public static HttpBooleanHeader of(String name, Boolean typedValue) { 063 return new HttpBooleanHeader(name, typedValue); 064 } 065 066 /** 067 * Constructor. 068 * 069 * @param name Header name. Must not be <jk>null</jk>. 070 * @param wireValue Wire value (e.g. {@code "true"}). Can be <jk>null</jk> or empty, in which case the parsed value is <jk>null</jk>. 071 */ 072 protected HttpBooleanHeader(String name, String wireValue) { 073 super(name, wireValue); 074 this.value = ie(wireValue) ? null : Boolean.valueOf(b(wireValue)); 075 this.lazySupplier = null; 076 this.lazyMode = -1; 077 } 078 079 /** 080 * Constructor. 081 * 082 * @param name Header name. Must not be <jk>null</jk>. 083 * @param typedValue The boolean value. Can be <jk>null</jk>, in which case the parsed value is <jk>null</jk>. 084 */ 085 protected HttpBooleanHeader(String name, Boolean typedValue) { 086 super(name, s(typedValue)); 087 this.value = typedValue; 088 this.lazySupplier = null; 089 this.lazyMode = -1; 090 } 091 092 /** 093 * Constructor with lazy value supplier. 094 * 095 * @param name Header name. Must not be <jk>null</jk>. 096 * @param supplier The lazy value supplier. Must not be <jk>null</jk>. 097 * @param lazyMode Either {@link #LAZY_WIRE_STRING} or {@link #LAZY_BOOLEAN}. 098 */ 099 protected HttpBooleanHeader(String name, Supplier<?> supplier, int lazyMode) { 100 super(name, lazyMode == LAZY_WIRE_STRING 101 ? ((Supplier<String>) supplier)::get 102 : () -> s(((Supplier<Boolean>) supplier).get())); 103 this.value = null; 104 this.lazySupplier = supplier; 105 this.lazyMode = lazyMode; 106 } 107 108 public Optional<Boolean> asBoolean() { 109 return o(toBoolean()); 110 } 111 112 /** 113 * Returns the wire-format value of this header. 114 * 115 * @return The wire value, or <jk>null</jk> if the value is unset. 116 */ 117 @Override 118 public String getValue() { 119 return s(toBoolean()); 120 } 121 122 /** 123 * Returns <jk>true</jk> if the parsed value is <jk>true</jk>. 124 * 125 * @return <jk>true</jk> if the parsed value is <jk>true</jk>; <jk>false</jk> if it is <jk>false</jk> or unset. 126 */ 127 public boolean isTrue() { 128 return ObjectUtils.isTrue(toBoolean()); 129 } 130 131 /** 132 * Returns the parsed value of this header, or the specified default if unset. 133 * 134 * @param other The default value. Can be <jk>null</jk> to allow a <jk>null</jk> result when the header is unset. 135 * @return The parsed value, or <c>other</c> if the value is unset. Can be <jk>null</jk> if <c>other</c> is <jk>null</jk>. 136 */ 137 public Boolean orElse(Boolean other) { 138 var x = toBoolean(); 139 return nn(x) ? x : other; 140 } 141 142 /** 143 * Returns the parsed value of this header. 144 * 145 * @return The parsed value, or <jk>null</jk> if the value is unset. 146 */ 147 public Boolean toBoolean() { 148 if (lazyMode == LAZY_BOOLEAN) 149 return ((Supplier<Boolean>) lazySupplier).get(); 150 if (value != null) 151 return value; 152 var v = super.getValue(); 153 return ie(v) ? null : Boolean.valueOf(b(v)); 154 } 155}