• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 The Dagger 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 dagger.internal;
18 
19 import org.jspecify.annotations.Nullable;
20 
21 /**
22  * An adaptation of Guava's {@code com.google.common.base.Preconditions} that is specially tailored
23  * to support checks applied in Dagger's generated code.
24  */
25 public final class Preconditions {
26   /**
27    * Ensures that an object reference passed as a parameter to the calling method is not null.
28    *
29    * @param reference an object reference
30    * @return the non-null reference that was validated
31    * @throws NullPointerException if {@code reference} is null
32    */
checkNotNull(@ullable T reference)33   public static <T> T checkNotNull(@Nullable T reference) {
34     if (reference == null) {
35       throw new NullPointerException();
36     }
37     return reference;
38   }
39 
40   /**
41    * Ensures that an object reference passed as a parameter to the calling method is not null.
42    *
43    * @param reference an object reference
44    * @param errorMessage the exception message to use if the check fails
45    * @return the non-null reference that was validated
46    * @throws NullPointerException if {@code reference} is null
47    */
checkNotNull(T reference, String errorMessage)48   public static <T> T checkNotNull(T reference, String errorMessage) {
49     if (reference == null) {
50       throw new NullPointerException(errorMessage);
51     }
52     return reference;
53   }
54 
55   /**
56    * Ensures that an object reference returned from a provides method is not null.
57    *
58    * @param reference an object reference
59    * @return the non-null reference that was validated
60    * @throws NullPointerException if {@code reference} is null
61    */
checkNotNullFromProvides(T reference)62   public static <T> T checkNotNullFromProvides(T reference) {
63     if (reference == null) {
64       throw new NullPointerException("Cannot return null from a non-@Nullable @Provides method");
65     }
66     return reference;
67   }
68 
69   /**
70    * Ensures that an object reference returned from a component method is not null.
71    *
72    * @param reference an object reference
73    * @return the non-null reference that was validated
74    * @throws NullPointerException if {@code reference} is null
75    */
checkNotNullFromComponent(T reference)76   public static <T> T checkNotNullFromComponent(T reference) {
77     if (reference == null) {
78       throw new NullPointerException("Cannot return null from a non-@Nullable component method");
79     }
80     return reference;
81   }
82 
83   /**
84    * Ensures that an object reference passed as a parameter to the calling method is not null.
85    *
86    * @param reference an object reference
87    * @param errorMessageTemplate a template for the exception message should the check fail. The
88    *     message is formed by replacing the single {@code %s} placeholder in the template with
89    *     {@code errorMessageArg}.
90    * @param errorMessageArg the argument to be substituted into the message template. Converted to a
91    *     string using {@link String#valueOf(Object)}, except for {@link Class} objects, which use
92    *     {@link Class#getCanonicalName()}.
93    * @return the non-null reference that was validated
94    * @throws NullPointerException if {@code reference} is null
95    * @throws IllegalArgumentException if {@code errorMessageTemplate} doesn't contain exactly one
96    *     "%s"
97    */
checkNotNull( T reference, String errorMessageTemplate, Object errorMessageArg)98   public static <T> T checkNotNull(
99       T reference, String errorMessageTemplate, Object errorMessageArg) {
100     if (reference == null) {
101       // Simple implementation of String.format, which is not GWT-compatible
102       if (!errorMessageTemplate.contains("%s")) {
103         throw new IllegalArgumentException("errorMessageTemplate has no format specifiers");
104       }
105       if (errorMessageTemplate.indexOf("%s") != errorMessageTemplate.lastIndexOf("%s")) {
106         throw new IllegalArgumentException(
107             "errorMessageTemplate has more than one format specifier");
108       }
109       String argString =
110           String.valueOf(
111               errorMessageArg instanceof Class
112                   ? ((Class) errorMessageArg).getCanonicalName()
113                   : errorMessageArg);
114       throw new NullPointerException(errorMessageTemplate.replace("%s", argString));
115     }
116     return reference;
117   }
118 
119   /**
120    * Checks that the component builder field {@code requirement} has been initialized.
121    *
122    * @throws IllegalStateException if {@code requirement is null}
123    */
checkBuilderRequirement(T requirement, Class<T> clazz)124   public static <T> void checkBuilderRequirement(T requirement, Class<T> clazz) {
125     if (requirement == null) {
126       throw new IllegalStateException(clazz.getCanonicalName() + " must be set");
127     }
128   }
129 
Preconditions()130   private Preconditions() {}
131 }
132