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; 014 015import static org.apache.juneau.internal.ObjectUtils.*; 016 017import java.util.*; 018import java.util.function.*; 019 020import org.apache.http.*; 021import org.apache.juneau.collections.*; 022import org.apache.juneau.internal.*; 023import org.apache.juneau.http.header.*; 024import org.apache.juneau.http.header.ContentType; 025 026/** 027 * An extension of an {@link HttpEntity} with support for arbitrary headers. 028 * 029 * Provides the following features: 030 * <ul class='spaced-list'> 031 * <li> 032 * Default support for various streams and readers. 033 * <li> 034 * Content from {@link Supplier Suppliers}. 035 * <li> 036 * Caching. 037 * <li> 038 * Fluent setters. 039 * <li> 040 * Fluent assertions. 041 * </ul> 042 */ 043public class BasicHttpResource extends BasicHttpEntity implements HttpResource { 044 045 private final List<Header> headers = AList.of(); 046 047 /** 048 * Creator. 049 * 050 * @param content 051 * The content. 052 * <br>Can be any of the following: 053 * <ul> 054 * <li><c>InputStream</c> 055 * <li><c>Reader</c> - Converted to UTF-8 bytes. 056 * <li><c>File</c> 057 * <li><c>CharSequence</c> - Converted to UTF-8 bytes. 058 * <li><c><jk>byte</jk>[]</c>. 059 * <li>A {@link Supplier} of anything on this list. 060 * </ul> 061 * </ul> 062 * @return A new empty {@link BasicHttpResource} object. 063 */ 064 public static BasicHttpResource of(Object content) { 065 return new BasicHttpResource(content); 066 } 067 068 /** 069 * Creator. 070 * 071 * @param content 072 * The content. 073 * <br>Can be any of the following: 074 * <ul> 075 * <li><c>InputStream</c> 076 * <li><c>Reader</c> - Converted to UTF-8 bytes. 077 * <li><c>File</c> 078 * <li><c>CharSequence</c> - Converted to UTF-8 bytes. 079 * <li><c><jk>byte</jk>[]</c>. 080 * <li>A {@link Supplier} of anything on this list. 081 * </ul> 082 * </ul> 083 * @return A new empty {@link BasicHttpResource} object. 084 */ 085 public static BasicHttpResource of(Supplier<?> content) { 086 return new BasicHttpResource(content); 087 } 088 089 /** 090 * Constructor. 091 * 092 * @param content 093 * The content. 094 * <br>Can be any of the following: 095 * <ul> 096 * <li><c>InputStream</c> 097 * <li><c>Reader</c> - Converted to UTF-8 bytes. 098 * <li><c>File</c> 099 * <li><c>CharSequence</c> - Converted to UTF-8 bytes. 100 * <li><c><jk>byte</jk>[]</c>. 101 * <li>A {@link Supplier} of anything on this list. 102 * </ul> 103 * </ul> 104 */ 105 public BasicHttpResource(Object content) { 106 super(content); 107 } 108 109 /** 110 * Constructor. 111 * 112 * @param content 113 * The content. 114 * <br>Can be any of the following: 115 * <ul> 116 * <li><c>InputStream</c> 117 * <li><c>Reader</c> - Converted to UTF-8 bytes. 118 * <li><c>File</c> 119 * <li><c>CharSequence</c> - Converted to UTF-8 bytes. 120 * <li><c><jk>byte</jk>[]</c>. 121 * <li>A {@link Supplier} of anything on this list. 122 * </ul> 123 * </ul> 124 * @param contentType 125 * The content type of the contents. 126 * <br>Can be <jk>null</jk>. 127 * @param contentEncoding 128 * The content encoding of the contents. 129 * <br>Can be <jk>null</jk>. 130 */ 131 public BasicHttpResource(Object content, ContentType contentType, ContentEncoding contentEncoding) { 132 super(content, contentType, contentEncoding); 133 } 134 135 /** 136 * Adds an arbitrary header to this resource. 137 * 138 * <p> 139 * Header is not added if name or value is null. 140 * 141 * @param name The header name. 142 * @param val The header value. 143 * @return This object (for method chaining). 144 */ 145 @FluentSetter 146 public BasicHttpResource header(String name, Object val) { 147 if (name != null && val != null) 148 headers.add(BasicHeader.of(name, val)); 149 return this; 150 } 151 152 /** 153 * Adds an arbitrary header to this resource. 154 * 155 * @param value The header. 156 * @return This object (for method chaining). 157 */ 158 @FluentSetter 159 public BasicHttpResource header(Header value) { 160 headers.add(value); 161 return this; 162 } 163 164 /** 165 * Adds an arbitrary collection of headers to this resource. 166 * 167 * @param headers The headers to add to this resource. 168 * @return This object (for method chaining). 169 */ 170 @FluentSetter 171 public BasicHttpResource headers(List<Header> headers) { 172 this.headers.addAll(headers); 173 return this; 174 } 175 176 /** 177 * Adds an arbitrary collection of headers to this resource. 178 * 179 * @param headers The headers to add to this resource. 180 * @return This object (for method chaining). 181 */ 182 @FluentSetter 183 public BasicHttpResource headers(Header...headers) { 184 this.headers.addAll(Arrays.asList(headers)); 185 return this; 186 } 187 188 /** 189 * Returns the first header with the specified name as a string. 190 * 191 * @param name The header name. 192 * @return The header value or <jk>null</jk> if header was not found. 193 */ 194 public String getStringHeader(String name) { 195 Header h = getLastHeader(name); 196 return h == null ? null : h.getValue(); 197 } 198 199 /** 200 * Returns the first header with the specified name as a string. 201 * 202 * @param name The header name. 203 * @return The header or <jk>null</jk> if header was not found. 204 */ 205 public Header getFirstHeader(String name) { 206 for (Header h : headers) 207 if (h != null && eq(name, h.getName())) 208 return h; 209 return null; 210 } 211 212 /** 213 * Returns the last header with the specified name as a string. 214 * 215 * @param name The header name. 216 * @return The header or <jk>null</jk> if header was not found. 217 */ 218 public Header getLastHeader(String name) { 219 for (ListIterator<Header> li = headers.listIterator(headers.size()); li.hasPrevious();) { 220 Header h = li.previous(); 221 if (h != null && eq(name, h.getName())) 222 return h; 223 } 224 return null; 225 } 226 227 @Override /* Resource */ 228 public List<Header> getHeaders() { 229 return Collections.unmodifiableList(headers); 230 } 231 232 // <FluentSetters> 233 234 @Override /* GENERATED - BasicHttpEntity */ 235 public BasicHttpResource cache() { 236 super.cache(); 237 return this; 238 } 239 240 @Override /* GENERATED - BasicHttpEntity */ 241 public BasicHttpResource cache(boolean value) { 242 super.cache(value); 243 return this; 244 } 245 246 @Override /* GENERATED - BasicHttpEntity */ 247 public BasicHttpResource chunked() { 248 super.chunked(); 249 return this; 250 } 251 252 @Override /* GENERATED - BasicHttpEntity */ 253 public BasicHttpResource chunked(boolean value) { 254 super.chunked(value); 255 return this; 256 } 257 258 @Override /* GENERATED - BasicHttpEntity */ 259 public BasicHttpResource contentEncoding(String value) { 260 super.contentEncoding(value); 261 return this; 262 } 263 264 @Override /* GENERATED - BasicHttpEntity */ 265 public BasicHttpResource contentEncoding(Header value) { 266 super.contentEncoding(value); 267 return this; 268 } 269 270 @Override /* GENERATED - BasicHttpEntity */ 271 public BasicHttpResource contentLength(long value) { 272 super.contentLength(value); 273 return this; 274 } 275 276 @Override /* GENERATED - BasicHttpEntity */ 277 public BasicHttpResource contentType(String value) { 278 super.contentType(value); 279 return this; 280 } 281 282 @Override /* GENERATED - BasicHttpEntity */ 283 public BasicHttpResource contentType(Header value) { 284 super.contentType(value); 285 return this; 286 } 287 288 // </FluentSetters> 289}