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

box / box-java-sdk / #4866

17 Sep 2025 03:03PM UTC coverage: 37.127% (-0.004%) from 37.131%
#4866

push

github

web-flow
chore: release version 10.0.0 (#1430)

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

10 existing lines in 7 files now uncovered.

18455 of 49708 relevant lines covered (37.13%)

0.37 hits per line

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

75.78
/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.DateTimeParseException;
27
import java.util.Arrays;
28
import java.util.Base64;
29
import java.util.HashMap;
30
import java.util.Iterator;
31
import java.util.List;
32
import java.util.Locale;
33
import java.util.Map;
34
import java.util.Objects;
35
import java.util.Set;
36
import java.util.UUID;
37
import java.util.function.BiFunction;
38
import java.util.stream.Collectors;
39
import javax.crypto.Mac;
40
import javax.crypto.spec.SecretKeySpec;
41
import org.jose4j.jws.JsonWebSignature;
42
import org.jose4j.jwt.JwtClaims;
43
import org.jose4j.jwt.NumericDate;
44
import org.jose4j.lang.JoseException;
45

46
public class UtilsManager {
×
47
  private static final int BUFFER_SIZE = 8192;
48

49
  private static final DateTimeFormatter OFFSET_DATE_TIME_FORMAT =
1✔
50
      DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssXXX");
1✔
51
  private static final DateTimeFormatter OFFSET_DATE_TIME_FORMAT_WITH_MILLIS =
1✔
52
      DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
1✔
53
  private static final DateTimeFormatter OFFSET_DATE_TIME_FORMAT_WITH_MICROS =
1✔
54
      DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSSSSX");
1✔
55
  private static final DateTimeFormatter OFFSET_DATE_FORMAT =
1✔
56
      DateTimeFormatter.ofPattern("yyyy-MM-dd");
1✔
57

58
  public static <K, V> Map<K, V> mapOf(Entry<K, V>... entries) {
59
    return Arrays.stream(entries)
1✔
60
        .collect(
1✔
61
            HashMap::new,
62
            (map, entry) -> map.put(entry.getKey(), entry.getValue()),
1✔
63
            HashMap::putAll);
64
  }
65

66
  public static <V> Set<V> setOf(V... values) {
67
    return Arrays.stream(values).collect(Collectors.toSet());
×
68
  }
69

70
  public static <K, V> Entry<K, V> entryOf(K key, V value) {
71
    return Entry.of(key, value);
1✔
72
  }
73

74
  public static <K, V> Map<K, V> mergeMaps(Map<K, V> map1, Map<K, V> map2) {
75
    Map<K, V> mergedMap = new HashMap<>();
1✔
76
    if (map1 != null) {
1✔
77
      mergedMap.putAll(map1);
1✔
78
    }
79
    if (map2 != null) {
1✔
80
      mergedMap.putAll(map2);
1✔
81
    }
82
    return mergedMap;
1✔
83
  }
84

85
  public static Map<String, String> prepareParams(Map<String, String> map) {
86
    map.values().removeIf(Objects::isNull);
1✔
87
    return map;
1✔
88
  }
89

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

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

141
  public static String getUuid() {
142
    return UUID.randomUUID().toString();
1✔
143
  }
144

145
  public static byte[] generateByteBuffer(int size) {
146
    byte[] bytes = new byte[size];
1✔
147
    Arrays.fill(bytes, (byte) 0);
1✔
148
    return bytes;
1✔
149
  }
150

151
  public static InputStream generateByteStream(int size) {
152
    byte[] bytes = generateByteBuffer(size);
1✔
153
    return new ByteArrayInputStream(bytes);
1✔
154
  }
155

156
  public static InputStream generateByteStreamFromBuffer(byte[] buffer) {
157
    return new ByteArrayInputStream(buffer);
1✔
158
  }
159

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

178
    return buffer.toByteArray();
1✔
179
  }
180

181
  public static boolean bufferEquals(byte[] buffer1, byte[] buffer2) {
182
    return Arrays.equals(buffer1, buffer2);
1✔
183
  }
184

185
  public static int bufferLength(byte[] buffer) {
186
    return buffer.length;
1✔
187
  }
188

189
  public static InputStream decodeBase64ByteStream(String value) {
190
    return new ByteArrayInputStream(Base64.getDecoder().decode(value));
1✔
191
  }
192

193
  public static String decodeBase64(String value) {
194
    return new String(Base64.getDecoder().decode(value));
1✔
195
  }
196

197
  public static InputStream stringToByteStream(String value) {
198
    return new ByteArrayInputStream(value.getBytes());
1✔
199
  }
200

201
  public static OutputStream getFileOutputStream(String filePath) {
202
    try {
203
      return new FileOutputStream(filePath);
1✔
204
    } catch (FileNotFoundException e) {
×
205
      throw new RuntimeException(e);
×
206
    }
207
  }
208

209
  public static void closeFileOutputStream(OutputStream outputStream) {
210
    try {
211
      outputStream.close();
1✔
212
    } catch (IOException e) {
×
213
      throw new RuntimeException(e);
×
214
    }
1✔
215
  }
1✔
216

217
  public static byte[] readBufferFromFile(String filePath) {
218
    try {
219
      InputStream inputStream = Files.newInputStream(Paths.get(filePath));
1✔
220
      return readByteStream(inputStream);
1✔
221
    } catch (IOException e) {
×
222
      throw new RuntimeException(e);
×
223
    }
224
  }
225

226
  public static String getEnvVar(String envVar) {
227
    return System.getenv(envVar);
1✔
228
  }
229

230
  public static void delayInSeconds(int seconds) {
231
    try {
232
      Thread.sleep(seconds * 1000L);
1✔
233
    } catch (InterruptedException e) {
×
234
      throw new RuntimeException(e);
×
235
    }
1✔
236
  }
1✔
237

238
  public static String readTextFromFile(String filePath) {
239
    try {
240
      return new String(Files.readAllBytes(Paths.get(filePath)));
×
241
    } catch (IOException e) {
×
242
      throw new RuntimeException(e);
×
243
    }
244
  }
245

246
  public static boolean isBrowser() {
247
    return false;
1✔
248
  }
249

250
  public static long getEpochTimeInSeconds() {
251
    return System.currentTimeMillis() / 1000;
1✔
252
  }
253

254
  public static String createJwtAssertion(
255
      Map<String, Object> claims, JwtKey jwtKey, JwtSignOptions jwtOptions) {
256
    JwtClaims jwtClaims = new JwtClaims();
1✔
257
    jwtClaims.setIssuer(jwtOptions.getIssuer());
1✔
258
    jwtClaims.setAudience(jwtOptions.getAudience());
1✔
259
    jwtClaims.setExpirationTime(NumericDate.fromSeconds((Long) claims.get("exp")));
1✔
260

261
    jwtClaims.setSubject(jwtOptions.getSubject());
1✔
262
    jwtClaims.setClaim("box_sub_type", claims.get("box_sub_type"));
1✔
263
    jwtClaims.setGeneratedJwtId(64);
1✔
264

265
    JsonWebSignature jws = new JsonWebSignature();
1✔
266
    jws.setPayload(jwtClaims.toJson());
1✔
267
    jws.setKey(
1✔
268
        jwtOptions.privateKeyDecryptor.decryptPrivateKey(jwtKey.getKey(), jwtKey.getPassphrase()));
1✔
269
    jws.setAlgorithmHeaderValue(jwtOptions.getAlgorithm().getValue());
1✔
270
    jws.setHeader("typ", "JWT");
1✔
271
    if ((jwtOptions.getKeyid() != null) && !jwtOptions.getKeyid().isEmpty()) {
1✔
272
      jws.setHeader("kid", jwtOptions.getKeyid());
1✔
273
    }
274

275
    String assertion;
276

277
    try {
278
      assertion = jws.getCompactSerialization();
1✔
279
    } catch (JoseException e) {
×
280
      throw new BoxSDKError("Error serializing JSON Web Token assertion.", e);
×
281
    }
1✔
282

283
    return assertion;
1✔
284
  }
285

286
  public static JsonNode getValueFromObjectRawData(SerializableObject obj, String key) {
287
    JsonNode value = obj.getRawData();
1✔
288
    for (String k : key.split("\\.")) {
1✔
289
      if (value == null || !value.has(k)) {
1✔
290
        return null;
×
291
      }
292
      value = value.get(k);
1✔
293
    }
294

295
    return value;
1✔
296
  }
297

298
  public static double random(double min, double max) {
299
    return Math.random() * (max - min) + min;
1✔
300
  }
301

302
  public static String hexToBase64(String hex) {
303
    return Base64.getEncoder().encodeToString(new BigInteger(hex, 16).toByteArray());
1✔
304
  }
305

306
  public static Iterator<InputStream> iterateChunks(
307
      InputStream stream, long chunkSize, long fileSize) {
308
    return new Iterator<InputStream>() {
1✔
309
      private boolean streamIsFinished = false;
1✔
310

311
      @Override
312
      public boolean hasNext() {
313
        return !streamIsFinished;
1✔
314
      }
315

316
      @Override
317
      public InputStream next() {
318
        try {
319
          byte[] buffer = new byte[(int) chunkSize];
1✔
320
          int bytesRead = 0;
1✔
321

322
          while (bytesRead < chunkSize) {
1✔
323
            int read = stream.read(buffer, bytesRead, (int) (chunkSize - bytesRead));
1✔
324
            if (read == -1) {
1✔
325
              // End of stream
326
              streamIsFinished = true;
1✔
327
              break;
1✔
328
            }
329
            bytesRead += read;
1✔
330
          }
1✔
331

332
          if (bytesRead == 0) {
1✔
333
            // No more data to yield
334
            streamIsFinished = true;
×
335
            return null;
×
336
          }
337

338
          // Return the chunk as a ByteArrayInputStream
339
          return new ByteArrayInputStream(buffer, 0, bytesRead);
1✔
340
        } catch (Exception e) {
×
341
          throw new RuntimeException("Error reading from stream", e);
×
342
        }
343
      }
344
    };
345
  }
346

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

363
    while (iterator.hasNext()) {
1✔
364
      T item = iterator.next();
1✔
365
      result = reducer.apply(result, item);
1✔
366
    }
1✔
367

368
    return result;
1✔
369
  }
370

371
  public static Map<String, String> sanitizeMap(
372
      Map<String, String> dictionary, Map<String, String> keysToSanitize) {
373
    return dictionary.entrySet().stream()
×
374
        .collect(
×
375
            Collectors.toMap(
×
376
                Map.Entry::getKey,
377
                entry ->
378
                    keysToSanitize.containsKey(entry.getKey().toLowerCase(Locale.ROOT))
×
379
                        ? JsonManager.sanitizedValue()
×
380
                        : entry.getValue()));
×
381
  }
382

383
  public static OffsetDateTime dateTimeFromString(String dateString) {
384
    DateTimeFormatter[] formatters = {
1✔
385
      OFFSET_DATE_TIME_FORMAT,
386
      OFFSET_DATE_TIME_FORMAT_WITH_MILLIS,
387
      OFFSET_DATE_TIME_FORMAT_WITH_MICROS
388
    };
389

390
    for (DateTimeFormatter formatter : formatters) {
1✔
391
      try {
392
        return OffsetDateTime.parse(dateString, formatter);
1✔
393
      } catch (DateTimeParseException e) {
1✔
394
        // Ignore and try the next format
395
      }
396
    }
UNCOV
397
    return null;
×
398
  }
399

400
  public static String dateTimeToString(OffsetDateTime dateTime) {
401
    return dateTime.format(OFFSET_DATE_TIME_FORMAT_WITH_MILLIS);
1✔
402
  }
403

404
  public static OffsetDateTime dateFromString(String dateString) {
405
    try {
406
      // For date-only strings, parse as date and convert to OffsetDateTime at start of day UTC
407
      if (dateString.matches("\\d{4}-\\d{2}-\\d{2}")) {
1✔
408
        return OffsetDateTime.parse(dateString + "T00:00:00Z");
1✔
409
      }
410
      // Otherwise try to parse as full OffsetDateTime
411
      DateTimeFormatter[] formatters = {
×
412
        OFFSET_DATE_TIME_FORMAT,
413
        OFFSET_DATE_TIME_FORMAT_WITH_MILLIS,
414
        OFFSET_DATE_TIME_FORMAT_WITH_MICROS
415
      };
416
      for (DateTimeFormatter formatter : formatters) {
×
417
        try {
418
          return OffsetDateTime.parse(dateString, formatter);
×
419
        } catch (DateTimeParseException e) {
×
420
          // Ignore and try the next format
421
        }
422
      }
423
      return null;
×
424
    } catch (DateTimeParseException e) {
×
425
      return null;
×
426
    }
427
  }
428

429
  public static String dateToString(OffsetDateTime date) {
430
    return date.format(OFFSET_DATE_FORMAT);
1✔
431
  }
432

433
  public static String escapeUnicode(String value) {
434
    if (value == null) {
1✔
435
      return null;
×
436
    }
437

438
    StringBuilder result = new StringBuilder();
1✔
439
    for (int i = 0; i < value.length(); i++) {
1✔
440
      char ch = value.charAt(i);
1✔
441
      if (ch >= 0x007F) {
1✔
442
        result.append(String.format("\\u%04x", (int) ch));
1✔
443
      } else if (ch == '\\') {
1✔
444
        result.append("\\\\");
1✔
445
      } else if (ch == '\n') {
1✔
446
        result.append("\\n");
×
447
      } else if (ch == '\r') {
1✔
448
        result.append("\\r");
1✔
449
      } else if (ch == '\t') {
1✔
450
        result.append("\\t");
×
451
      } else if (ch == '/') {
1✔
452
        if (i == 0 || value.charAt(i - 1) != '\\') {
1✔
453
          result.append("\\/");
1✔
454
        } else {
455
          result.append(ch);
×
456
        }
457
      } else {
458
        result.append(ch);
1✔
459
      }
460
    }
461
    return result.toString();
1✔
462
  }
463

464
  public static OffsetDateTime epochSecondsToDateTime(long seconds) {
465
    return OffsetDateTime.ofInstant(java.time.Instant.ofEpochSecond(seconds), ZoneOffset.UTC);
1✔
466
  }
467

468
  public static long dateTimeToEpochSeconds(OffsetDateTime dateTime) {
469
    return dateTime.toEpochSecond();
1✔
470
  }
471

472
  public static boolean compareSignatures(String expectedSignature, String receivedSignature) {
473
    if (expectedSignature == null || receivedSignature == null) {
1✔
474
      return false;
×
475
    }
476
    byte[] expectedBytes = expectedSignature.getBytes(StandardCharsets.UTF_8);
1✔
477
    byte[] receivedBytes = receivedSignature.getBytes(StandardCharsets.UTF_8);
1✔
478
    return MessageDigest.isEqual(expectedBytes, receivedBytes);
1✔
479
  }
480

481
  public static String computeWebhookSignature(
482
      String body, Map<String, String> headers, String signatureKey, boolean escapeBody) {
483
    if (signatureKey == null) {
1✔
484
      return null;
×
485
    }
486
    if (!"1".equals(headers.get("box-signature-version"))) {
1✔
487
      return null;
×
488
    }
489
    if (!"HmacSHA256".equals(headers.get("box-signature-algorithm"))) {
1✔
490
      return null;
×
491
    }
492
    if (!headers.containsKey("box-delivery-timestamp")) {
1✔
493
      return null;
×
494
    }
495

496
    try {
497
      String escapedBody = escapeBody ? escapeUnicode(body) : body;
1✔
498
      byte[] encodedSignatureKey = signatureKey.getBytes("UTF-8");
1✔
499
      byte[] encodedBody = escapedBody.getBytes("UTF-8");
1✔
500
      byte[] encodedTimestamp = headers.get("box-delivery-timestamp").getBytes("UTF-8");
1✔
501
      Mac mac = Mac.getInstance("HmacSHA256");
1✔
502
      SecretKeySpec secretKeySpec = new SecretKeySpec(encodedSignatureKey, "HmacSHA256");
1✔
503
      mac.init(secretKeySpec);
1✔
504
      mac.update(encodedBody);
1✔
505
      mac.update(encodedTimestamp);
1✔
506
      byte[] hmacDigest = mac.doFinal();
1✔
507
      return Base64.getEncoder().encodeToString(hmacDigest);
1✔
508
    } catch (Exception e) {
×
509
      return null;
×
510
    }
511
  }
512
}
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

© 2026 Coveralls, Inc