001// Generated by delombok at Thu Aug 13 13:56:43 UTC 2026 002/* 003 * Copyright (c) 2010-2026 Mark Allen, Norbert Bartels. 004 * 005 * Permission is hereby granted, free of charge, to any person obtaining a copy 006 * of this software and associated documentation files (the "Software"), to deal 007 * in the Software without restriction, including without limitation the rights 008 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 009 * copies of the Software, and to permit persons to whom the Software is 010 * furnished to do so, subject to the following conditions: 011 * 012 * The above copyright notice and this permission notice shall be included in 013 * all copies or substantial portions of the Software. 014 * 015 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 016 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 017 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 018 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 019 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 020 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 021 * THE SOFTWARE. 022 */ 023package com.restfb; 024 025import static java.lang.String.format; 026import java.io.ByteArrayInputStream; 027import java.io.IOException; 028import java.io.InputStream; 029import java.net.URLConnection; 030import java.util.function.Supplier; 031import com.restfb.util.ObjectUtil; 032import com.restfb.util.ReflectionUtils; 033 034/** 035 * Represents a binary file that can be uploaded to Facebook. 036 * <p> 037 * Normally this would be a photo or video. 038 * 039 * @author <a href="http://restfb.com">Mark Allen</a> 040 * @author Marcel Stoer 041 * @since 1.6.5 042 */ 043public class BinaryAttachment { 044 private static final String FIELD_NAME_CANNOT_BE_NULL = "Field name cannot be null."; 045 private final String filename; 046 protected byte[] data; 047 private Supplier<InputStream> dataSupplier; 048 private String contentType; 049 private String fieldName; 050 051 protected BinaryAttachment() { 052 filename = "default"; 053 } 054 055 /** 056 * Creates a new binary attachment backed by a stream supplier. 057 * 058 * @param filename 059 * The attachment's filename. 060 * @param dataSupplier 061 * Provides a fresh {@link InputStream} for each access. 062 * @throws IllegalArgumentException 063 * If {@code dataSupplier} is {@code null} or {@code filename} is {@code null} or blank. 064 */ 065 protected BinaryAttachment(String filename, Supplier<InputStream> dataSupplier) { 066 ObjectUtil.requireNotEmpty(filename, "Binary attachment filename cannot be blank."); 067 ObjectUtil.verifyParameterPresence("dataSupplier", dataSupplier); 068 this.filename = filename; 069 this.dataSupplier = dataSupplier; 070 } 071 072 /** 073 * Creates a new binary attachment backed by a stream supplier. 074 * 075 * @param filename 076 * The attachment's filename. 077 * @param dataSupplier 078 * Provides a fresh {@link InputStream} for each access. 079 * @param fieldName 080 * The field name the binary belongs to 081 * @throws IllegalArgumentException 082 * If {@code dataSupplier} is {@code null} or {@code filename} is {@code null} or blank. 083 */ 084 protected BinaryAttachment(String fieldName, String filename, Supplier<InputStream> dataSupplier) { 085 this(filename, dataSupplier); 086 ObjectUtil.requireNotEmpty(fieldName, FIELD_NAME_CANNOT_BE_NULL); 087 this.fieldName = fieldName; 088 } 089 090 public boolean isFacebookReel() { 091 return false; 092 } 093 094 /** 095 * Creates a new binary attachment backed by a stream supplier. 096 * 097 * @param filename 098 * The attachment's filename. 099 * @param dataSupplier 100 * Provides a fresh {@link InputStream} for each access. 101 * @param contentType 102 * The attachment's contentType. 103 * @throws IllegalArgumentException 104 * If {@code dataSupplier} is {@code null}, {@code filename} is {@code null} or blank, or 105 * {@code contentType} is {@code null} or blank. 106 * @since 1.6.13 107 */ 108 protected BinaryAttachment(String filename, Supplier<InputStream> dataSupplier, String contentType) { 109 this(filename, dataSupplier); 110 ObjectUtil.requireNotEmpty(contentType, "ContentType cannot be null."); 111 this.contentType = contentType; 112 } 113 114 /** 115 * Creates a new binary attachment backed by a stream supplier. 116 * 117 * @param filename 118 * The attachment's filename. 119 * @param dataSupplier 120 * Provides a fresh {@link InputStream} for each access. 121 * @param contentType 122 * The attachment's contentType. 123 * @param fieldName 124 * The field name the binary belongs to 125 * @throws IllegalArgumentException 126 * If {@code dataSupplier} is {@code null}, {@code filename} is {@code null} or blank, or 127 * {@code contentType} is {@code null} or blank. 128 * @since 1.6.13 129 */ 130 protected BinaryAttachment(String fieldName, String filename, Supplier<InputStream> dataSupplier, String contentType) { 131 this(filename, dataSupplier, contentType); 132 ObjectUtil.requireNotEmpty(fieldName, FIELD_NAME_CANNOT_BE_NULL); 133 this.fieldName = fieldName; 134 } 135 136 /** 137 * Creates a new binary attachment. 138 * 139 * @param filename 140 * The attachment's filename. 141 * @param data 142 * The attachment's data. 143 * @throws IllegalArgumentException 144 * If {@code data} is {@code null} or {@code filename} is {@code null} or blank. 145 * @since 1.6.17 146 */ 147 protected BinaryAttachment(String filename, byte[] data) { 148 ObjectUtil.requireNotEmpty(filename, "Binary attachment filename cannot be blank."); 149 ObjectUtil.verifyParameterPresence("data", data); 150 this.filename = filename; 151 this.data = data; 152 } 153 154 /** 155 * Creates a new binary attachment. 156 * 157 * @param filename 158 * The attachment's filename. 159 * @param data 160 * The attachment's data. 161 * @param fieldName 162 * The field name the binary belongs to 163 * @throws IllegalArgumentException 164 * If {@code data} is {@code null} or {@code filename} is {@code null} or blank. 165 * @since 1.6.17 166 */ 167 protected BinaryAttachment(String fieldName, String filename, byte[] data) { 168 this(filename, data); 169 ObjectUtil.requireNotEmpty(fieldName, FIELD_NAME_CANNOT_BE_NULL); 170 this.fieldName = fieldName; 171 } 172 173 /** 174 * Creates a new binary attachment. 175 * 176 * @param filename 177 * The attachment's filename. 178 * @param data 179 * The attachment's data. 180 * @param contentType 181 * The attachment's contentType. 182 * @throws IllegalArgumentException 183 * If {@code data} is {@code null}, {@code filename} is {@code null} or blank, or {@code contentType} is 184 * {@code null} or blank. 185 * @since 1.6.17 186 */ 187 protected BinaryAttachment(String filename, byte[] data, String contentType) { 188 this(filename, data); 189 ObjectUtil.requireNotEmpty(contentType, "ContentType cannot be null."); 190 this.contentType = contentType; 191 } 192 193 /** 194 * Creates a new binary attachment. 195 * 196 * @param filename 197 * The attachment's filename. 198 * @param data 199 * The attachment's data. 200 * @param contentType 201 * The attachment's contentType. 202 * @param fieldName 203 * The field name the binary belongs to 204 * @throws IllegalArgumentException 205 * If {@code data} is {@code null}, {@code filename} is {@code null} or blank, or {@code contentType} is 206 * {@code null} or blank. 207 * @since 1.6.17 208 */ 209 protected BinaryAttachment(String fieldName, String filename, byte[] data, String contentType) { 210 this(filename, data, contentType); 211 ObjectUtil.requireNotEmpty(fieldName, FIELD_NAME_CANNOT_BE_NULL); 212 this.fieldName = fieldName; 213 } 214 215 /** 216 * Creates a binary attachment backed by a stream supplier. 217 * 218 * @param filename 219 * The attachment's filename. 220 * @param dataSupplier 221 * Provides a fresh {@link InputStream} for each access. 222 * @return A binary attachment. 223 * @throws IllegalArgumentException 224 * If {@code dataSupplier} is {@code null} or {@code filename} is {@code null} or blank. 225 */ 226 public static BinaryAttachment with(String filename, Supplier<InputStream> dataSupplier) { 227 return new BinaryAttachment(filename, dataSupplier); 228 } 229 230 /** 231 * Creates a binary attachment backed by a stream supplier. 232 * 233 * @param filename 234 * The attachment's filename. 235 * @param dataSupplier 236 * Provides a fresh {@link InputStream} for each access. 237 * @param fieldName 238 * The field name the binary belongs to 239 * @return A binary attachment. 240 * @throws IllegalArgumentException 241 * If {@code dataSupplier} is {@code null} or {@code filename} is {@code null} or blank. 242 */ 243 public static BinaryAttachment with(String fieldName, String filename, Supplier<InputStream> dataSupplier) { 244 return new BinaryAttachment(fieldName, filename, dataSupplier); 245 } 246 247 /** 248 * Creates a binary attachment backed by a stream supplier. 249 * 250 * @param filename 251 * The attachment's filename. 252 * @param dataSupplier 253 * Provides a fresh {@link InputStream} for each access. 254 * @param contentType 255 * The attachment's contentType. 256 * @return A binary attachment. 257 * @throws IllegalArgumentException 258 * If {@code dataSupplier} is {@code null} or {@code filename} is {@code null} or blank. 259 */ 260 public static BinaryAttachment with(String filename, Supplier<InputStream> dataSupplier, String contentType) { 261 return new BinaryAttachment(filename, dataSupplier, contentType); 262 } 263 264 /** 265 * Creates a binary attachment backed by a stream supplier. 266 * 267 * @param filename 268 * The attachment's filename. 269 * @param dataSupplier 270 * Provides a fresh {@link InputStream} for each access. 271 * @param fieldName 272 * The field name the binary belongs to 273 * @param contentType 274 * The attachment's contentType. 275 * @return A binary attachment. 276 * @throws IllegalArgumentException 277 * If {@code dataSupplier} is {@code null} or {@code filename} is {@code null} or blank. 278 */ 279 public static BinaryAttachment with(String fieldName, String filename, Supplier<InputStream> dataSupplier, String contentType) { 280 return new BinaryAttachment(fieldName, filename, dataSupplier, contentType); 281 } 282 283 /** 284 * Creates a binary attachment. 285 * 286 * @param filename 287 * The attachment's filename. 288 * @param data 289 * The attachment's data. 290 * @return A binary attachment. 291 * @throws IllegalArgumentException 292 * If {@code data} is {@code null} or {@code filename} is {@code null} or blank. 293 * @since 1.6.17 294 */ 295 public static BinaryAttachment with(String filename, byte[] data) { 296 return new BinaryAttachment(filename, data); 297 } 298 299 /** 300 * Creates a binary attachment. 301 * 302 * @param filename 303 * The attachment's filename. 304 * @param data 305 * The attachment's data. 306 * @param fieldName 307 * The field name the binary belongs to 308 * @return A binary attachment. 309 * @throws IllegalArgumentException 310 * If {@code data} is {@code null} or {@code filename} is {@code null} or blank. 311 * @since 1.6.17 312 */ 313 public static BinaryAttachment with(String fieldName, String filename, byte[] data) { 314 return new BinaryAttachment(fieldName, filename, data); 315 } 316 317 /** 318 * Creates a binary attachment. 319 * 320 * @param filename 321 * The attachment's filename. 322 * @param data 323 * The attachment's data. 324 * @param contentType 325 * The attachment's contentType. 326 * @return A binary attachment. 327 * @throws IllegalArgumentException 328 * If {@code data} is {@code null} or {@code filename} is {@code null} or blank. 329 * @since 1.6.17 330 */ 331 public static BinaryAttachment with(String filename, byte[] data, String contentType) { 332 return new BinaryAttachment(filename, data, contentType); 333 } 334 335 /** 336 * Creates a binary attachment. 337 * 338 * @param filename 339 * The attachment's filename. 340 * @param data 341 * The attachment's data. 342 * @param contentType 343 * The attachment's contentType. 344 * @param fieldName 345 * The field name the binary belongs to 346 * @return A binary attachment. 347 * @throws IllegalArgumentException 348 * If {@code data} is {@code null} or {@code filename} is {@code null} or blank. 349 * @since 1.6.17 350 */ 351 public static BinaryAttachment with(String fieldName, String filename, byte[] data, String contentType) { 352 return new BinaryAttachment(fieldName, filename, data, contentType); 353 } 354 355 @Override 356 public int hashCode() { 357 return ReflectionUtils.hashCode(this); 358 } 359 360 @Override 361 public boolean equals(Object that) { 362 return ReflectionUtils.equals(this, that); 363 } 364 365 @Override 366 public String toString() { 367 return format("[filename=%s]", getFilename()); 368 } 369 370 /** 371 * The attachment's data. 372 * 373 * @return The attachment's data. 374 */ 375 public InputStream getData() { 376 if (data != null) { 377 return new ByteArrayInputStream(data); 378 } else if (dataSupplier != null) { 379 InputStream stream = dataSupplier.get(); 380 ObjectUtil.verifyParameterPresence("dataSupplier result", stream); 381 return stream; 382 } else { 383 throw new IllegalStateException("Either the byte[] or the stream mustn\'t be null at this point."); 384 } 385 } 386 387 /** 388 * return the given content type or try to guess from stream or file name. Depending of the available data. 389 * 390 * @return the content type 391 */ 392 public String getContentType() { 393 if (contentType != null) { 394 return contentType; 395 } 396 if (dataSupplier != null) { 397 try (InputStream stream = dataSupplier.get()) { 398 if (stream != null) { 399 contentType = URLConnection.guessContentTypeFromStream(stream); 400 } 401 } catch (IOException ioe) { 402 } 403 } 404 // ignore exception 405 if (data != null) { 406 contentType = URLConnection.getFileNameMap().getContentTypeFor(filename); 407 } 408 // fallback - if we have no contenttype and cannot detect one, use 'application/octet-stream' 409 if (contentType == null) { 410 contentType = "application/octet-stream"; 411 } 412 return contentType; 413 } 414 415 public boolean hasBinaryData() { 416 return data != null; 417 } 418 419 /** 420 * Returns the form field name used for multipart uploads. 421 * 422 * @return the explicit field name if set, otherwise the filename without its extension 423 */ 424 public String getFormFieldName() { 425 if (fieldName != null) { 426 return fieldName; 427 } 428 String name = getFilename(); 429 if (name == null) { 430 return null; 431 } 432 int dotIndex = name.lastIndexOf('.'); 433 return dotIndex > 0 ? name.substring(0, dotIndex) : name; 434 } 435 436 @java.lang.SuppressWarnings("all") 437 @lombok.Generated 438 public String getFilename() { 439 return this.filename; 440 } 441 442 @java.lang.SuppressWarnings("all") 443 @lombok.Generated 444 public String getFieldName() { 445 return this.fieldName; 446 } 447}