1*f585d8a3SJacky Wang /* 2*f585d8a3SJacky Wang * Copyright (C) 2016 The Dagger Authors. 3*f585d8a3SJacky Wang * 4*f585d8a3SJacky Wang * Licensed under the Apache License, Version 2.0 (the "License"); 5*f585d8a3SJacky Wang * you may not use this file except in compliance with the License. 6*f585d8a3SJacky Wang * You may obtain a copy of the License at 7*f585d8a3SJacky Wang * 8*f585d8a3SJacky Wang * http://www.apache.org/licenses/LICENSE-2.0 9*f585d8a3SJacky Wang * 10*f585d8a3SJacky Wang * Unless required by applicable law or agreed to in writing, software 11*f585d8a3SJacky Wang * distributed under the License is distributed on an "AS IS" BASIS, 12*f585d8a3SJacky Wang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*f585d8a3SJacky Wang * See the License for the specific language governing permissions and 14*f585d8a3SJacky Wang * limitations under the License. 15*f585d8a3SJacky Wang */ 16*f585d8a3SJacky Wang 17*f585d8a3SJacky Wang package dagger.internal; 18*f585d8a3SJacky Wang 19*f585d8a3SJacky Wang 20*f585d8a3SJacky Wang /** 21*f585d8a3SJacky Wang * An adaptation of Guava's {@code com.google.common.base.Preconditions} that is specially tailored 22*f585d8a3SJacky Wang * to support checks applied in Dagger's generated code. 23*f585d8a3SJacky Wang */ 24*f585d8a3SJacky Wang public final class Preconditions { 25*f585d8a3SJacky Wang /** 26*f585d8a3SJacky Wang * Ensures that an object reference passed as a parameter to the calling method is not null. 27*f585d8a3SJacky Wang * 28*f585d8a3SJacky Wang * @param reference an object reference 29*f585d8a3SJacky Wang * @return the non-null reference that was validated 30*f585d8a3SJacky Wang * @throws NullPointerException if {@code reference} is null 31*f585d8a3SJacky Wang */ checkNotNull(T reference)32*f585d8a3SJacky Wang public static <T> T checkNotNull(T reference) { 33*f585d8a3SJacky Wang if (reference == null) { 34*f585d8a3SJacky Wang throw new NullPointerException(); 35*f585d8a3SJacky Wang } 36*f585d8a3SJacky Wang return reference; 37*f585d8a3SJacky Wang } 38*f585d8a3SJacky Wang 39*f585d8a3SJacky Wang /** 40*f585d8a3SJacky Wang * Ensures that an object reference passed as a parameter to the calling method is not null. 41*f585d8a3SJacky Wang * 42*f585d8a3SJacky Wang * @param reference an object reference 43*f585d8a3SJacky Wang * @param errorMessage the exception message to use if the check fails 44*f585d8a3SJacky Wang * @return the non-null reference that was validated 45*f585d8a3SJacky Wang * @throws NullPointerException if {@code reference} is null 46*f585d8a3SJacky Wang */ checkNotNull(T reference, String errorMessage)47*f585d8a3SJacky Wang public static <T> T checkNotNull(T reference, String errorMessage) { 48*f585d8a3SJacky Wang if (reference == null) { 49*f585d8a3SJacky Wang throw new NullPointerException(errorMessage); 50*f585d8a3SJacky Wang } 51*f585d8a3SJacky Wang return reference; 52*f585d8a3SJacky Wang } 53*f585d8a3SJacky Wang 54*f585d8a3SJacky Wang /** 55*f585d8a3SJacky Wang * Ensures that an object reference returned from a provides method is not null. 56*f585d8a3SJacky Wang * 57*f585d8a3SJacky Wang * @param reference an object reference 58*f585d8a3SJacky Wang * @return the non-null reference that was validated 59*f585d8a3SJacky Wang * @throws NullPointerException if {@code reference} is null 60*f585d8a3SJacky Wang */ checkNotNullFromProvides(T reference)61*f585d8a3SJacky Wang public static <T> T checkNotNullFromProvides(T reference) { 62*f585d8a3SJacky Wang if (reference == null) { 63*f585d8a3SJacky Wang throw new NullPointerException("Cannot return null from a non-@Nullable @Provides method"); 64*f585d8a3SJacky Wang } 65*f585d8a3SJacky Wang return reference; 66*f585d8a3SJacky Wang } 67*f585d8a3SJacky Wang 68*f585d8a3SJacky Wang /** 69*f585d8a3SJacky Wang * Ensures that an object reference returned from a component method is not null. 70*f585d8a3SJacky Wang * 71*f585d8a3SJacky Wang * @param reference an object reference 72*f585d8a3SJacky Wang * @return the non-null reference that was validated 73*f585d8a3SJacky Wang * @throws NullPointerException if {@code reference} is null 74*f585d8a3SJacky Wang */ checkNotNullFromComponent(T reference)75*f585d8a3SJacky Wang public static <T> T checkNotNullFromComponent(T reference) { 76*f585d8a3SJacky Wang if (reference == null) { 77*f585d8a3SJacky Wang throw new NullPointerException("Cannot return null from a non-@Nullable component method"); 78*f585d8a3SJacky Wang } 79*f585d8a3SJacky Wang return reference; 80*f585d8a3SJacky Wang } 81*f585d8a3SJacky Wang 82*f585d8a3SJacky Wang /** 83*f585d8a3SJacky Wang * Ensures that an object reference passed as a parameter to the calling method is not null. 84*f585d8a3SJacky Wang * 85*f585d8a3SJacky Wang * @param reference an object reference 86*f585d8a3SJacky Wang * @param errorMessageTemplate a template for the exception message should the check fail. The 87*f585d8a3SJacky Wang * message is formed by replacing the single {@code %s} placeholder in the template with 88*f585d8a3SJacky Wang * {@code errorMessageArg}. 89*f585d8a3SJacky Wang * @param errorMessageArg the argument to be substituted into the message template. Converted to a 90*f585d8a3SJacky Wang * string using {@link String#valueOf(Object)}, except for {@link Class} objects, which use 91*f585d8a3SJacky Wang * {@link Class#getCanonicalName()}. 92*f585d8a3SJacky Wang * @return the non-null reference that was validated 93*f585d8a3SJacky Wang * @throws NullPointerException if {@code reference} is null 94*f585d8a3SJacky Wang * @throws IllegalArgumentException if {@code errorMessageTemplate} doesn't contain exactly one 95*f585d8a3SJacky Wang * "%s" 96*f585d8a3SJacky Wang */ checkNotNull( T reference, String errorMessageTemplate, Object errorMessageArg)97*f585d8a3SJacky Wang public static <T> T checkNotNull( 98*f585d8a3SJacky Wang T reference, String errorMessageTemplate, Object errorMessageArg) { 99*f585d8a3SJacky Wang if (reference == null) { 100*f585d8a3SJacky Wang // Simple implementation of String.format, which is not GWT-compatible 101*f585d8a3SJacky Wang if (!errorMessageTemplate.contains("%s")) { 102*f585d8a3SJacky Wang throw new IllegalArgumentException("errorMessageTemplate has no format specifiers"); 103*f585d8a3SJacky Wang } 104*f585d8a3SJacky Wang if (errorMessageTemplate.indexOf("%s") != errorMessageTemplate.lastIndexOf("%s")) { 105*f585d8a3SJacky Wang throw new IllegalArgumentException( 106*f585d8a3SJacky Wang "errorMessageTemplate has more than one format specifier"); 107*f585d8a3SJacky Wang } 108*f585d8a3SJacky Wang String argString = 109*f585d8a3SJacky Wang errorMessageArg instanceof Class 110*f585d8a3SJacky Wang ? ((Class) errorMessageArg).getCanonicalName() 111*f585d8a3SJacky Wang : String.valueOf(errorMessageArg); 112*f585d8a3SJacky Wang throw new NullPointerException(errorMessageTemplate.replace("%s", argString)); 113*f585d8a3SJacky Wang } 114*f585d8a3SJacky Wang return reference; 115*f585d8a3SJacky Wang } 116*f585d8a3SJacky Wang 117*f585d8a3SJacky Wang /** 118*f585d8a3SJacky Wang * Checks that the component builder field {@code requirement} has been initialized. 119*f585d8a3SJacky Wang * 120*f585d8a3SJacky Wang * @throws IllegalStateException if {@code requirement is null} 121*f585d8a3SJacky Wang */ checkBuilderRequirement(T requirement, Class<T> clazz)122*f585d8a3SJacky Wang public static <T> void checkBuilderRequirement(T requirement, Class<T> clazz) { 123*f585d8a3SJacky Wang if (requirement == null) { 124*f585d8a3SJacky Wang throw new IllegalStateException(clazz.getCanonicalName() + " must be set"); 125*f585d8a3SJacky Wang } 126*f585d8a3SJacky Wang } 127*f585d8a3SJacky Wang Preconditions()128*f585d8a3SJacky Wang private Preconditions() {} 129*f585d8a3SJacky Wang } 130