View Javadoc

1   package com.atlassian.vcache.internal.core;
2   
3   import com.atlassian.marshalling.api.MarshallingException;
4   import com.atlassian.marshalling.api.MarshallingPair;
5   import com.atlassian.vcache.ExternalCacheException;
6   
7   import javax.annotation.Nullable;
8   import java.time.Duration;
9   import java.util.Optional;
10  import java.util.concurrent.CompletableFuture;
11  import java.util.concurrent.CompletionStage;
12  import java.util.function.LongConsumer;
13  
14  import static com.atlassian.vcache.ExternalCacheException.Reason.MARSHALLER_FAILURE;
15  import static java.util.Objects.requireNonNull;
16  
17  /**
18   * Contains common implementation methods.
19   *
20   * @since 1.0.0
21   */
22  public class VCacheCoreUtils {
23      /**
24       * Returns a successfully completed {@link CompletionStage} with the specified result.
25       *
26       * @param value the result for the future
27       * @param <T>   the type of the result
28       * @return a successfully completed {@link CompletionStage} with the specified result.
29       */
30      public static <T> CompletionStage<T> successful(T value) {
31          return CompletableFuture.completedFuture(value);
32      }
33  
34      /**
35       * Returns a failed {@link CompletionStage} with the specified cause.
36       *
37       * @param cause the cause of the failure
38       * @param <T>   the type of the result
39       * @param result A CompletionStage containing the result.
40       *
41       * @return a failed {@link CompletionStage} with the specified cause.
42       */
43      public static <T> CompletionStage<T> failed(CompletionStage<T> result, Throwable cause) {
44          result.toCompletableFuture().completeExceptionally(cause);
45          return result;
46      }
47  
48      public static int roundUpToSeconds(Duration time) {
49          if (time.isNegative()) {
50              throw new IllegalArgumentException("duration cannot be negative: " + time);
51          }
52  
53          final long result = (time.getNano() > 0) ? time.getSeconds() + 1 : time.getSeconds();
54  
55          if (result > Integer.MAX_VALUE) {
56              throw new IllegalArgumentException("duration exceeds maximum number that can be held in an int");
57          }
58  
59          return (int) result;
60      }
61  
62      public static void whenPositive(long number, LongConsumer handler) {
63          if (number > 0) {
64              handler.accept(number);
65          }
66      }
67  
68      public static <V> byte[] marshall(V data, MarshallingPair<V> valueMarshalling) throws ExternalCacheException {
69          try {
70              return valueMarshalling.getMarshaller().marshallToBytes(requireNonNull(data));
71          } catch (MarshallingException e) {
72              throw new ExternalCacheException(MARSHALLER_FAILURE, e);
73          }
74      }
75  
76      public static <V> Optional<V> unmarshall(@Nullable byte[] data, MarshallingPair<V> valueMarshalling) throws ExternalCacheException {
77          if (data == null) {
78              return Optional.empty();
79          }
80  
81          try {
82              return Optional.of(valueMarshalling.getUnmarshaller().unmarshallFrom(data));
83          } catch (MarshallingException ex) {
84              throw new ExternalCacheException(MARSHALLER_FAILURE, ex);
85          }
86      }
87  
88      public static <K> boolean isEmpty(Iterable<K> iter) {
89          return !iter.iterator().hasNext();
90      }
91  }