• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2018, OpenCensus Authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package io.opencensus.internal;
18 
19 import java.util.List;
20 
21 /*>>>
22 import org.checkerframework.checker.nullness.qual.NonNull;
23 */
24 
25 /** General internal utility methods. */
26 public final class Utils {
27 
Utils()28   private Utils() {}
29 
30   /**
31    * Throws an {@link IllegalArgumentException} if the argument is false. This method is similar to
32    * {@code Preconditions.checkArgument(boolean, Object)} from Guava.
33    *
34    * @param isValid whether the argument check passed.
35    * @param errorMessage the message to use for the exception. Will be converted to a string using
36    *     {@link String#valueOf(Object)}.
37    */
checkArgument( boolean isValid, @javax.annotation.Nullable Object errorMessage)38   public static void checkArgument(
39       boolean isValid, @javax.annotation.Nullable Object errorMessage) {
40     if (!isValid) {
41       throw new IllegalArgumentException(String.valueOf(errorMessage));
42     }
43   }
44 
45   /**
46    * Throws an {@link IllegalArgumentException} if the argument is false. This method is similar to
47    * {@code Preconditions.checkArgument(boolean, Object)} from Guava.
48    *
49    * @param expression a boolean expression
50    * @param errorMessageTemplate a template for the exception message should the check fail. The
51    *     message is formed by replacing each {@code %s} placeholder in the template with an
52    *     argument. These are matched by position - the first {@code %s} gets {@code
53    *     errorMessageArgs[0]}, etc. Unmatched arguments will be appended to the formatted message in
54    *     square braces. Unmatched placeholders will be left as-is.
55    * @param errorMessageArgs the arguments to be substituted into the message template. Arguments
56    *     are converted to strings using {@link String#valueOf(Object)}.
57    * @throws IllegalArgumentException if {@code expression} is false
58    * @throws NullPointerException if the check fails and either {@code errorMessageTemplate} or
59    *     {@code errorMessageArgs} is null (don't let this happen)
60    */
checkArgument( boolean expression, String errorMessageTemplate, @javax.annotation.Nullable Object... errorMessageArgs)61   public static void checkArgument(
62       boolean expression,
63       String errorMessageTemplate,
64       @javax.annotation.Nullable Object... errorMessageArgs) {
65     if (!expression) {
66       throw new IllegalArgumentException(format(errorMessageTemplate, errorMessageArgs));
67     }
68   }
69 
70   /**
71    * Throws an {@link IllegalStateException} if the argument is false. This method is similar to
72    * {@code Preconditions.checkState(boolean, Object)} from Guava.
73    *
74    * @param isValid whether the state check passed.
75    * @param errorMessage the message to use for the exception. Will be converted to a string using
76    *     {@link String#valueOf(Object)}.
77    */
checkState(boolean isValid, @javax.annotation.Nullable Object errorMessage)78   public static void checkState(boolean isValid, @javax.annotation.Nullable Object errorMessage) {
79     if (!isValid) {
80       throw new IllegalStateException(String.valueOf(errorMessage));
81     }
82   }
83 
84   /**
85    * Validates an index in an array or other container. This method throws an {@link
86    * IllegalArgumentException} if the size is negative and throws an {@link
87    * IndexOutOfBoundsException} if the index is negative or greater than or equal to the size. This
88    * method is similar to {@code Preconditions.checkElementIndex(int, int)} from Guava.
89    *
90    * @param index the index to validate.
91    * @param size the size of the array or container.
92    */
checkIndex(int index, int size)93   public static void checkIndex(int index, int size) {
94     if (size < 0) {
95       throw new IllegalArgumentException("Negative size: " + size);
96     }
97     if (index < 0 || index >= size) {
98       throw new IndexOutOfBoundsException("Index out of bounds: size=" + size + ", index=" + index);
99     }
100   }
101 
102   /**
103    * Throws a {@link NullPointerException} if the argument is null. This method is similar to {@code
104    * Preconditions.checkNotNull(Object, Object)} from Guava.
105    *
106    * @param arg the argument to check for null.
107    * @param errorMessage the message to use for the exception. Will be converted to a string using
108    *     {@link String#valueOf(Object)}.
109    * @return the argument, if it passes the null check.
110    */
checkNotNull( T arg, @javax.annotation.Nullable Object errorMessage)111   public static <T /*>>> extends @NonNull Object*/> T checkNotNull(
112       T arg, @javax.annotation.Nullable Object errorMessage) {
113     if (arg == null) {
114       throw new NullPointerException(String.valueOf(errorMessage));
115     }
116     return arg;
117   }
118 
119   /**
120    * Throws a {@link NullPointerException} if any of the list elements is null.
121    *
122    * @param list the argument list to check for null.
123    * @param errorMessage the message to use for the exception. Will be converted to a string using
124    *     {@link String#valueOf(Object)}.
125    */
checkListElementNotNull( List<T> list, @javax.annotation.Nullable Object errorMessage)126   public static <T /*>>> extends @NonNull Object*/> void checkListElementNotNull(
127       List<T> list, @javax.annotation.Nullable Object errorMessage) {
128     for (T element : list) {
129       if (element == null) {
130         throw new NullPointerException(String.valueOf(errorMessage));
131       }
132     }
133   }
134 
135   /**
136    * Compares two Objects for equality. This functionality is provided by {@code
137    * Objects.equal(Object, Object)} in Java 7.
138    */
equalsObjects( @avax.annotation.Nullable Object x, @javax.annotation.Nullable Object y)139   public static boolean equalsObjects(
140       @javax.annotation.Nullable Object x, @javax.annotation.Nullable Object y) {
141     return x == null ? y == null : x.equals(y);
142   }
143 
144   /**
145    * Substitutes each {@code %s} in {@code template} with an argument. These are matched by
146    * position: the first {@code %s} gets {@code args[0]}, etc. If there are more arguments than
147    * placeholders, the unmatched arguments will be appended to the end of the formatted message in
148    * square braces.
149    *
150    * <p>Copied from {@code Preconditions.format(String, Object...)} from Guava
151    *
152    * @param template a non-null string containing 0 or more {@code %s} placeholders.
153    * @param args the arguments to be substituted into the message template. Arguments are converted
154    *     to strings using {@link String#valueOf(Object)}. Arguments can be null.
155    */
156   // Note that this is somewhat-improperly used from Verify.java as well.
format(String template, @javax.annotation.Nullable Object... args)157   private static String format(String template, @javax.annotation.Nullable Object... args) {
158     // If no arguments return the template.
159     if (args == null) {
160       return template;
161     }
162 
163     // start substituting the arguments into the '%s' placeholders
164     StringBuilder builder = new StringBuilder(template.length() + 16 * args.length);
165     int templateStart = 0;
166     int i = 0;
167     while (i < args.length) {
168       int placeholderStart = template.indexOf("%s", templateStart);
169       if (placeholderStart == -1) {
170         break;
171       }
172       builder.append(template, templateStart, placeholderStart);
173       builder.append(args[i++]);
174       templateStart = placeholderStart + 2;
175     }
176     builder.append(template, templateStart, template.length());
177 
178     // if we run out of placeholders, append the extra args in square braces
179     if (i < args.length) {
180       builder.append(" [");
181       builder.append(args[i++]);
182       while (i < args.length) {
183         builder.append(", ");
184         builder.append(args[i++]);
185       }
186       builder.append(']');
187     }
188 
189     return builder.toString();
190   }
191 }
192