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 java.util.*; 020import java.util.function.*; 021 022import org.apache.juneau.*; 023import org.apache.juneau.annotation.*; 024import org.apache.juneau.assertions.*; 025import org.apache.juneau.common.utils.*; 026import org.apache.juneau.http.annotation.*; 027 028/** 029 * Category of headers that consist of a single long value. 030 * 031 * <p> 032 * <h5 class='figure'>Example</h5> 033 * <p class='bcode'> 034 * Content-Length: 300 035 * </p> 036 * 037 * <h5 class='section'>See Also:</h5><ul> 038 * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauRestCommonBasics">juneau-rest-common Basics</a> 039 * <li class='extlink'><a class="doclink" href="https://www.w3.org/Protocols/rfc2616/rfc2616.html">Hypertext Transfer Protocol -- HTTP/1.1</a> 040 * </ul> 041 * 042 * @serial exclude 043 */ 044@Header 045@Schema(type="integer",format="int64") 046public class BasicLongHeader extends BasicHeader { 047 048 //----------------------------------------------------------------------------------------------------------------- 049 // Static 050 //----------------------------------------------------------------------------------------------------------------- 051 052 private static final long serialVersionUID = 1L; 053 054 /** 055 * Static creator. 056 * 057 * @param name The header name. 058 * @param value 059 * The header value. 060 * <br>Must be parsable by {@link Long#parseLong(String)}. 061 * <br>Can be <jk>null</jk>. 062 * @return A new header bean, or <jk>null</jk> if the value is <jk>null</jk>. 063 * @throws IllegalArgumentException If name is <jk>null</jk> or empty. 064 */ 065 public static BasicLongHeader of(String name, String value) { 066 return value == null ? null : new BasicLongHeader(name, value); 067 } 068 069 /** 070 * Static creator. 071 * 072 * @param name The header name. 073 * @param value 074 * The header value. 075 * <br>Must be parsable by {@link Long#parseLong(String)}. 076 * <br>Can be <jk>null</jk>. 077 * @return A new header bean, or <jk>null</jk> if the value is <jk>null</jk>. 078 * @throws IllegalArgumentException If name is <jk>null</jk> or empty. 079 */ 080 public static BasicLongHeader of(String name, Long value) { 081 return value == null ? null : new BasicLongHeader(name, value); 082 } 083 084 /** 085 * Static creator with delayed value. 086 * 087 * <p> 088 * Header value is re-evaluated on each call to {@link #getValue()}. 089 * 090 * @param name The header name. 091 * @param value 092 * The supplier of the header value. 093 * <br>Can be <jk>null</jk>. 094 * @return A new header bean, or <jk>null</jk> if the value is <jk>null</jk>. 095 * @throws IllegalArgumentException If name is <jk>null</jk> or empty. 096 */ 097 public static BasicLongHeader of(String name, Supplier<Long> value) { 098 return value == null ? null : new BasicLongHeader(name, value); 099 } 100 101 //----------------------------------------------------------------------------------------------------------------- 102 // Instance 103 //----------------------------------------------------------------------------------------------------------------- 104 105 private final Long value; 106 private final Supplier<Long> supplier; 107 108 /** 109 * Constructor. 110 * 111 * @param name The header name. 112 * @param value 113 * The header value. 114 * <br>Must be parsable by {@link Long#parseLong(String)}. 115 * <br>Can be <jk>null</jk>. 116 * @throws IllegalArgumentException If name is <jk>null</jk> or empty. 117 */ 118 public BasicLongHeader(String name, String value) { 119 super(name, value); 120 this.value = parse(value); 121 this.supplier = null; 122 } 123 124 /** 125 * Constructor. 126 * 127 * @param name The header name. 128 * @param value 129 * The header value. 130 * <br>Can be <jk>null</jk>. 131 * @throws IllegalArgumentException If name is <jk>null</jk> or empty. 132 */ 133 public BasicLongHeader(String name, Long value) { 134 super(name, value); 135 this.value = value; 136 this.supplier = null; 137 } 138 139 /** 140 * Constructor with delayed value. 141 * 142 * <p> 143 * Header value is re-evaluated on each call to {@link #getValue()}. 144 * 145 * @param name The header name. 146 * @param value 147 * The supplier of the header value. 148 * <br>Can be <jk>null</jk>. 149 * @throws IllegalArgumentException If name is <jk>null</jk> or empty. 150 */ 151 public BasicLongHeader(String name, Supplier<Long> value) { 152 super(name, null); 153 this.value = null; 154 this.supplier = value; 155 } 156 157 @Override /* Header */ 158 public String getValue() { 159 return Utils.s(value()); 160 } 161 162 /** 163 * Returns the header value as a {@link Long} wrapped in an {@link Optional}. 164 * 165 * @return The header value as a {@link Long} wrapped in an {@link Optional}. Never <jk>null</jk>. 166 */ 167 public Optional<Long> asLong() { 168 return Utils.opt(value()); 169 } 170 171 /** 172 * Returns the header value as a {@link Long}. 173 * 174 * @return The header value as a {@link Long}. Can be <jk>null</jk>. 175 */ 176 public Long toLong() { 177 return value(); 178 } 179 180 /** 181 * Provides the ability to perform fluent-style assertions on this header. 182 * 183 * <h5 class='section'>Examples:</h5> 184 * <p class='bjava'> 185 * <jc>// Validates the response body is not too large.</jc> 186 * <jv>client</jv> 187 * .get(<jsf>URL</jsf>) 188 * .run() 189 * .getHeader(<js>"Length"</js>).asLongHeader().assertLong().isLessThan(100000); 190 * </p> 191 * 192 * @return A new fluent assertion object. 193 * @throws AssertionError If assertion failed. 194 */ 195 public FluentLongAssertion<BasicLongHeader> assertLong() { 196 return new FluentLongAssertion<>(value(), this); 197 } 198 199 /** 200 * Return the value if present, otherwise return <c>other</c>. 201 * 202 * <p> 203 * This is a shortened form for calling <c>asLong().orElse(<jv>other</jv>)</c>. 204 * 205 * @param other The value to be returned if there is no value present, can be <jk>null</jk>. 206 * @return The value, if present, otherwise <c>other</c>. 207 */ 208 public Long orElse(Long other) { 209 Long x = value(); 210 return x != null ? x : other; 211 } 212 213 private Long parse(String value) { 214 try { 215 return value == null ? null : Long.parseLong(value); 216 } catch (NumberFormatException e) { 217 throw new BasicRuntimeException("Value ''{0}'' could not be parsed as a long.", value); 218 } 219 } 220 221 private Long value() { 222 if (supplier != null) 223 return supplier.get(); 224 return value; 225 } 226}