• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

box / box-java-sdk / #5925

17 Dec 2025 05:03PM UTC coverage: 35.453% (-0.1%) from 35.558%
#5925

push

github

web-flow
fix: add taxonomy to Metadata Field (read) definition (box/box-openapi#572) (#1644)

Co-authored-by: box-sdk-build <box-sdk-build@box.com>

2 of 2 new or added lines in 1 file covered. (100.0%)

62 existing lines in 13 files now uncovered.

18901 of 53313 relevant lines covered (35.45%)

0.35 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

73.18
/src/main/java/com/box/sdkgen/internal/utils/UtilsManager.java
1
package com.box.sdkgen.internal.utils;
2

3
import com.box.sdkgen.box.errors.BoxSDKError;
4
import com.box.sdkgen.internal.SerializableObject;
5
import com.box.sdkgen.serialization.json.EnumWrapper;
6
import com.box.sdkgen.serialization.json.JsonManager;
7
import com.box.sdkgen.serialization.json.Valuable;
8
import com.fasterxml.jackson.databind.JsonNode;
9
import com.fasterxml.jackson.databind.ObjectMapper;
10
import com.fasterxml.jackson.databind.node.ArrayNode;
11
import java.io.ByteArrayInputStream;
12
import java.io.ByteArrayOutputStream;
13
import java.io.FileNotFoundException;
14
import java.io.FileOutputStream;
15
import java.io.IOException;
16
import java.io.InputStream;
17
import java.io.OutputStream;
18
import java.math.BigInteger;
19
import java.nio.charset.StandardCharsets;
20
import java.nio.file.Files;
21
import java.nio.file.Paths;
22
import java.security.MessageDigest;
23
import java.time.OffsetDateTime;
24
import java.time.ZoneOffset;
25
import java.time.format.DateTimeFormatter;
26
import java.time.format.DateTimeFormatterBuilder;
27
import java.time.format.DateTimeParseException;
28
import java.time.temporal.ChronoField;
29
import java.util.Arrays;
30
import java.util.Base64;
31
import java.util.HashMap;
32
import java.util.Iterator;
33
import java.util.List;
34
import java.util.Locale;
35
import java.util.Map;
36
import java.util.Objects;
37
import java.util.Set;
38
import java.util.UUID;
39
import java.util.function.BiFunction;
40
import java.util.stream.Collectors;
41
import javax.crypto.Mac;
42
import javax.crypto.spec.SecretKeySpec;
43
import org.jose4j.jws.JsonWebSignature;
44
import org.jose4j.jwt.JwtClaims;
45
import org.jose4j.jwt.NumericDate;
46
import org.jose4j.lang.JoseException;
47

48
public class UtilsManager {
×
49
  private static final int BUFFER_SIZE = 8192;
50

51
  private static final DateTimeFormatter OFFSET_DATE_TIME_FORMAT =
1✔
52
      new DateTimeFormatterBuilder()
53
          .appendPattern("yyyy-MM-dd'T'HH:mm:ss")
1✔
54
          .optionalStart()
1✔
55
          .appendFraction(ChronoField.NANO_OF_SECOND, 0, 9, true)
1✔
56
          .optionalEnd()
1✔
57
          .appendOffsetId()
1✔
58
          .toFormatter();
1✔
59
  private static final DateTimeFormatter OFFSET_DATE_TIME_FORMAT_WITH_MILLIS =
1✔
60
      DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
1✔
61
  private static final DateTimeFormatter OFFSET_DATE_FORMAT =
1✔
62
      DateTimeFormatter.ofPattern("yyyy-MM-dd");
1✔
63

64
  public static <K, V> Map<K, V> mapOf(Entry<K, V>... entries) {
65
    return Arrays.stream(entries)
1✔
66
        .collect(
1✔
67
            HashMap::new,
68
            (map, entry) -> map.put(entry.getKey(), entry.getValue()),
1✔
69
            HashMap::putAll);
70
  }
71

72
  public static <V> Set<V> setOf(V... values) {
73
    return Arrays.stream(values).collect(Collectors.toSet());
×
74
  }
75

76
  public static <K, V> Entry<K, V> entryOf(K key, V value) {
77
    return Entry.of(key, value);
1✔
78
  }
79

80
  public static <K, V> Map<K, V> mergeMaps(Map<K, V> map1, Map<K, V> map2) {
81
    Map<K, V> mergedMap = new HashMap<>();
1✔
82
    if (map1 != null) {
1✔
83
      mergedMap.putAll(map1);
1✔
84
    }
85
    if (map2 != null) {
1✔
86
      mergedMap.putAll(map2);
1✔
87
    }
88
    return mergedMap;
1✔
89
  }
90

91
  public static Map<String, String> prepareParams(Map<String, String> map) {
92
    map.values().removeIf(Objects::isNull);
1✔
93
    return map;
1✔
94
  }
95

96
  public static String convertToString(Object value) {
97
    if (value == null) {
1✔
98
      return null;
1✔
99
    }
100
    if (value instanceof EnumWrapper) {
1✔
101
      return ((EnumWrapper<?>) value).getStringValue();
1✔
102
    }
103
    if (value instanceof Valuable) {
1✔
104
      return ((Valuable) value).getValue();
1✔
105
    }
106
    if (value instanceof List) {
1✔
107
      List<?> list = (List<?>) value;
1✔
108
      if (!list.isEmpty() && list.get(0) instanceof SerializableObject) {
1✔
109
        return JsonManager.serialize(value).toString();
1✔
110
      } else {
111
        return ((List<?>) value)
1✔
112
            .stream().map(UtilsManager::convertToString).collect(Collectors.joining(","));
1✔
113
      }
114
    }
115
    if (value instanceof ArrayNode) {
1✔
116
      return convertToString(new ObjectMapper().convertValue(value, List.class));
×
117
    }
118
    if (value instanceof JsonNode) {
1✔
119
      return ((JsonNode) value).asText();
×
120
    }
121
    if (value instanceof SerializableObject) {
1✔
122
      return JsonManager.serialize(value).toString();
×
123
    }
124
    return value.toString();
1✔
125
  }
126

127
  public static void writeInputStreamToOutputStream(InputStream input, OutputStream output) {
128
    try {
129
      byte[] buffer = new byte[BUFFER_SIZE];
1✔
130
      int n = input.read(buffer);
1✔
131
      while (n != -1) {
1✔
132
        output.write(buffer, 0, n);
1✔
133
        n = input.read(buffer);
1✔
134
      }
135
    } catch (IOException e) {
×
136
      throw new RuntimeException(e);
×
137
    } finally {
138
      try {
139
        input.close();
1✔
140
        output.close();
1✔
141
      } catch (IOException e) {
×
142
        throw new RuntimeException(e);
×
143
      }
1✔
144
    }
145
  }
1✔
146

147
  public static String getUuid() {
148
    return UUID.randomUUID().toString();
1✔
149
  }
150

151
  public static byte[] generateByteBuffer(int size) {
152
    byte[] bytes = new byte[size];
1✔
153
    Arrays.fill(bytes, (byte) 0);
1✔
154
    return bytes;
1✔
155
  }
156

157
  public static InputStream generateByteStream(int size) {
158
    byte[] bytes = generateByteBuffer(size);
1✔
159
    return new ByteArrayInputStream(bytes);
1✔
160
  }
161

162
  public static InputStream generateByteStreamFromBuffer(byte[] buffer) {
163
    return new ByteArrayInputStream(buffer);
1✔
164
  }
165

166
  public static byte[] readByteStream(InputStream inputStream) {
167
    ByteArrayOutputStream buffer = new ByteArrayOutputStream();
1✔
168
    byte[] data = new byte[BUFFER_SIZE];
1✔
169
    int bytesRead;
170
    try {
171
      while ((bytesRead = inputStream.read(data, 0, data.length)) != -1) {
1✔
172
        buffer.write(data, 0, bytesRead);
1✔
173
      }
174
    } catch (IOException e) {
×
175
      throw new RuntimeException(e);
×
176
    } finally {
177
      try {
178
        inputStream.close();
1✔
179
      } catch (IOException e) {
×
180
        throw new RuntimeException(e);
×
181
      }
1✔
182
    }
183

184
    return buffer.toByteArray();
1✔
185
  }
186

187
  public static boolean bufferEquals(byte[] buffer1, byte[] buffer2) {
188
    return Arrays.equals(buffer1, buffer2);
1✔
189
  }
190

191
  public static int bufferLength(byte[] buffer) {
192
    return buffer.length;
1✔
193
  }
194

195
  public static InputStream decodeBase64ByteStream(String value) {
196
    return new ByteArrayInputStream(Base64.getDecoder().decode(value));
1✔
197
  }
198

199
  public static String decodeBase64(String value) {
200
    return new String(Base64.getDecoder().decode(value));
1✔
201
  }
202

203
  public static InputStream stringToByteStream(String value) {
204
    return new ByteArrayInputStream(value.getBytes());
1✔
205
  }
206

207
  public static OutputStream getFileOutputStream(String filePath) {
208
    try {
209
      return new FileOutputStream(filePath);
1✔
210
    } catch (FileNotFoundException e) {
×
211
      throw new RuntimeException(e);
×
212
    }
213
  }
214

215
  public static void closeFileOutputStream(OutputStream outputStream) {
216
    try {
217
      outputStream.close();
1✔
218
    } catch (IOException e) {
×
219
      throw new RuntimeException(e);
×
220
    }
1✔
221
  }
1✔
222

223
  public static byte[] readBufferFromFile(String filePath) {
224
    try {
225
      InputStream inputStream = Files.newInputStream(Paths.get(filePath));
1✔
226
      return readByteStream(inputStream);
1✔
227
    } catch (IOException e) {
×
228
      throw new RuntimeException(e);
×
229
    }
230
  }
231

232
  public static String getEnvVar(String envVar) {
233
    return System.getenv(envVar);
1✔
234
  }
235

236
  public static void delayInSeconds(int seconds) {
237
    try {
238
      Thread.sleep(seconds * 1000L);
1✔
239
    } catch (InterruptedException e) {
×
240
      throw new RuntimeException(e);
×
241
    }
1✔
242
  }
1✔
243

244
  public static String readTextFromFile(String filePath) {
245
    try {
246
      return new String(Files.readAllBytes(Paths.get(filePath)));
×
247
    } catch (IOException e) {
×
248
      throw new RuntimeException(e);
×
249
    }
250
  }
251

252
  public static boolean isBrowser() {
253
    return false;
1✔
254
  }
255

256
  public static long getEpochTimeInSeconds() {
257
    return System.currentTimeMillis() / 1000;
1✔
258
  }
259

260
  public static String createJwtAssertion(
261
      Map<String, Object> claims, JwtKey jwtKey, JwtSignOptions jwtOptions) {
262
    JwtClaims jwtClaims = new JwtClaims();
1✔
263
    jwtClaims.setIssuer(jwtOptions.getIssuer());
1✔
264
    jwtClaims.setAudience(jwtOptions.getAudience());
1✔
265
    jwtClaims.setExpirationTime(NumericDate.fromSeconds((Long) claims.get("exp")));
1✔
266

267
    jwtClaims.setSubject(jwtOptions.getSubject());
1✔
268
    jwtClaims.setClaim("box_sub_type", claims.get("box_sub_type"));
1✔
269
    jwtClaims.setGeneratedJwtId(64);
1✔
270

271
    JsonWebSignature jws = new JsonWebSignature();
1✔
272
    jws.setPayload(jwtClaims.toJson());
1✔
273
    jws.setKey(
1✔
274
        jwtOptions.privateKeyDecryptor.decryptPrivateKey(jwtKey.getKey(), jwtKey.getPassphrase()));
1✔
275
    jws.setAlgorithmHeaderValue(jwtOptions.getAlgorithm().getValue());
1✔
276
    jws.setHeader("typ", "JWT");
1✔
277
    if ((jwtOptions.getKeyid() != null) && !jwtOptions.getKeyid().isEmpty()) {
1✔
278
      jws.setHeader("kid", jwtOptions.getKeyid());
1✔
279
    }
280

281
    String assertion;
282

283
    try {
284
      assertion = jws.getCompactSerialization();
1✔
285
    } catch (JoseException e) {
×
286
      throw new BoxSDKError("Error serializing JSON Web Token assertion.", e);
×
287
    }
1✔
288

289
    return assertion;
1✔
290
  }
291

292
  public static JsonNode getValueFromObjectRawData(SerializableObject obj, String key) {
293
    JsonNode value = obj.getRawData();
×
294
    for (String k : key.split("\\.")) {
×
295
      if (value == null || !value.has(k)) {
×
296
        return null;
×
297
      }
298
      value = value.get(k);
×
299
    }
300

301
    return value;
×
302
  }
303

304
  public static double random(double min, double max) {
UNCOV
305
    return Math.random() * (max - min) + min;
×
306
  }
307

308
  public static String hexToBase64(String hex) {
309
    return Base64.getEncoder().encodeToString(new BigInteger(hex, 16).toByteArray());
1✔
310
  }
311

312
  public static Iterator<InputStream> iterateChunks(
313
      InputStream stream, long chunkSize, long fileSize) {
314
    return new Iterator<InputStream>() {
1✔
315
      private boolean streamIsFinished = false;
1✔
316

317
      @Override
318
      public boolean hasNext() {
319
        return !streamIsFinished;
1✔
320
      }
321

322
      @Override
323
      public InputStream next() {
324
        try {
325
          byte[] buffer = new byte[(int) chunkSize];
1✔
326
          int bytesRead = 0;
1✔
327

328
          while (bytesRead < chunkSize) {
1✔
329
            int read = stream.read(buffer, bytesRead, (int) (chunkSize - bytesRead));
1✔
330
            if (read == -1) {
1✔
331
              // End of stream
332
              streamIsFinished = true;
1✔
333
              break;
1✔
334
            }
335
            bytesRead += read;
1✔
336
          }
1✔
337

338
          if (bytesRead == 0) {
1✔
339
            // No more data to yield
340
            streamIsFinished = true;
×
341
            return null;
×
342
          }
343

344
          // Return the chunk as a ByteArrayInputStream
345
          return new ByteArrayInputStream(buffer, 0, bytesRead);
1✔
346
        } catch (Exception e) {
×
347
          throw new RuntimeException("Error reading from stream", e);
×
348
        }
349
      }
350
    };
351
  }
352

353
  /**
354
   * Reduces an iterator using a reducer function and an initial value.
355
   *
356
   * @param <Accumulator> The type of the accumulator (result)
357
   * @param <T> The type of the items in the iterator
358
   * @param iterator The iterator to process
359
   * @param reducer The reducer function
360
   * @param initialValue The initial value for the accumulator
361
   * @return The accumulated result
362
   */
363
  public static <Accumulator, T> Accumulator reduceIterator(
364
      Iterator<T> iterator,
365
      BiFunction<Accumulator, T, Accumulator> reducer,
366
      Accumulator initialValue) {
367
    Accumulator result = initialValue;
1✔
368

369
    while (iterator.hasNext()) {
1✔
370
      T item = iterator.next();
1✔
371
      result = reducer.apply(result, item);
1✔
372
    }
1✔
373

374
    return result;
1✔
375
  }
376

377
  public static Map<String, String> sanitizeMap(
378
      Map<String, String> dictionary, Map<String, String> keysToSanitize) {
UNCOV
379
    return dictionary.entrySet().stream()
×
UNCOV
380
        .collect(
×
UNCOV
381
            Collectors.toMap(
×
382
                Map.Entry::getKey,
383
                entry ->
UNCOV
384
                    keysToSanitize.containsKey(entry.getKey().toLowerCase(Locale.ROOT))
×
UNCOV
385
                        ? JsonManager.sanitizedValue()
×
UNCOV
386
                        : entry.getValue()));
×
387
  }
388

389
  public static OffsetDateTime dateTimeFromString(String dateString) {
390
    try {
391
      return OffsetDateTime.parse(dateString, OFFSET_DATE_TIME_FORMAT);
1✔
392
    } catch (DateTimeParseException e) {
×
393
      return null;
×
394
    }
395
  }
396

397
  public static String dateTimeToString(OffsetDateTime dateTime) {
398
    return dateTime.format(OFFSET_DATE_TIME_FORMAT_WITH_MILLIS);
1✔
399
  }
400

401
  public static OffsetDateTime dateFromString(String dateString) {
402
    try {
403
      // For date-only strings, parse as date and convert to OffsetDateTime at start of day UTC
404
      if (dateString.matches("\\d{4}-\\d{2}-\\d{2}")) {
1✔
405
        return OffsetDateTime.parse(dateString + "T00:00:00Z");
1✔
406
      }
407
      // Otherwise try to parse as full OffsetDateTime
408
      return dateTimeFromString(dateString);
×
409
    } catch (DateTimeParseException e) {
×
410
      return null;
×
411
    }
412
  }
413

414
  public static String dateToString(OffsetDateTime date) {
415
    return date.format(OFFSET_DATE_FORMAT);
1✔
416
  }
417

418
  public static String escapeUnicode(String value) {
419
    if (value == null) {
1✔
420
      return null;
×
421
    }
422

423
    StringBuilder result = new StringBuilder();
1✔
424
    for (int i = 0; i < value.length(); i++) {
1✔
425
      char ch = value.charAt(i);
1✔
426
      if (ch >= 0x007F) {
1✔
427
        result.append(String.format("\\u%04x", (int) ch));
1✔
428
      } else if (ch == '\\') {
1✔
429
        result.append("\\\\");
1✔
430
      } else if (ch == '\n') {
1✔
431
        result.append("\\n");
×
432
      } else if (ch == '\r') {
1✔
433
        result.append("\\r");
1✔
434
      } else if (ch == '\t') {
1✔
435
        result.append("\\t");
×
436
      } else if (ch == '/') {
1✔
437
        if (i == 0 || value.charAt(i - 1) != '\\') {
1✔
438
          result.append("\\/");
1✔
439
        } else {
440
          result.append(ch);
×
441
        }
442
      } else {
443
        result.append(ch);
1✔
444
      }
445
    }
446
    return result.toString();
1✔
447
  }
448

449
  public static OffsetDateTime epochSecondsToDateTime(long seconds) {
450
    return OffsetDateTime.ofInstant(java.time.Instant.ofEpochSecond(seconds), ZoneOffset.UTC);
1✔
451
  }
452

453
  public static long dateTimeToEpochSeconds(OffsetDateTime dateTime) {
454
    return dateTime.toEpochSecond();
1✔
455
  }
456

457
  public static boolean compareSignatures(String expectedSignature, String receivedSignature) {
458
    if (expectedSignature == null || receivedSignature == null) {
1✔
459
      return false;
×
460
    }
461
    byte[] expectedBytes = expectedSignature.getBytes(StandardCharsets.UTF_8);
1✔
462
    byte[] receivedBytes = receivedSignature.getBytes(StandardCharsets.UTF_8);
1✔
463
    return MessageDigest.isEqual(expectedBytes, receivedBytes);
1✔
464
  }
465

466
  public static String computeWebhookSignature(
467
      String body, Map<String, String> headers, String signatureKey, boolean escapeBody) {
468
    if (signatureKey == null) {
1✔
469
      return null;
×
470
    }
471
    if (!"1".equals(headers.get("box-signature-version"))) {
1✔
472
      return null;
×
473
    }
474
    if (!"HmacSHA256".equals(headers.get("box-signature-algorithm"))) {
1✔
475
      return null;
×
476
    }
477
    if (!headers.containsKey("box-delivery-timestamp")) {
1✔
478
      return null;
×
479
    }
480

481
    try {
482
      String escapedBody = escapeBody ? escapeUnicode(body) : body;
1✔
483
      byte[] encodedSignatureKey = signatureKey.getBytes("UTF-8");
1✔
484
      byte[] encodedBody = escapedBody.getBytes("UTF-8");
1✔
485
      byte[] encodedTimestamp = headers.get("box-delivery-timestamp").getBytes("UTF-8");
1✔
486
      Mac mac = Mac.getInstance("HmacSHA256");
1✔
487
      SecretKeySpec secretKeySpec = new SecretKeySpec(encodedSignatureKey, "HmacSHA256");
1✔
488
      mac.init(secretKeySpec);
1✔
489
      mac.update(encodedBody);
1✔
490
      mac.update(encodedTimestamp);
1✔
491
      byte[] hmacDigest = mac.doFinal();
1✔
492
      return Base64.getEncoder().encodeToString(hmacDigest);
1✔
493
    } catch (Exception e) {
×
494
      return null;
×
495
    }
496
  }
497
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc