1 /* 2 * Copyright (C) 2022 The Android Open Source Project 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 android.safetycenter.config; 18 19 import static android.os.Build.VERSION_CODES.TIRAMISU; 20 21 import android.annotation.AnyRes; 22 import android.annotation.NonNull; 23 import android.annotation.Nullable; 24 import android.content.res.Resources; 25 26 import androidx.annotation.RequiresApi; 27 28 import java.util.Collection; 29 import java.util.Objects; 30 import java.util.regex.Pattern; 31 32 @RequiresApi(TIRAMISU) 33 final class BuilderUtils { 34 BuilderUtils()35 private BuilderUtils() {} 36 validateAttribute( @ullable Object attribute, @NonNull String name, boolean required, boolean prohibited, @Nullable Object defaultValue)37 private static void validateAttribute( 38 @Nullable Object attribute, 39 @NonNull String name, 40 boolean required, 41 boolean prohibited, 42 @Nullable Object defaultValue) { 43 if (attribute == null && required) { 44 throwRequiredAttributeMissing(name); 45 } 46 boolean nonDefaultValueProvided = !Objects.equals(attribute, defaultValue); 47 boolean checkProhibited = prohibited && nonDefaultValueProvided; 48 if (attribute != null && checkProhibited) { 49 throwProhibitedAttributePresent(name); 50 } 51 } 52 validateAttribute( @ullable Object attribute, @NonNull String name, boolean required, boolean prohibited)53 static void validateAttribute( 54 @Nullable Object attribute, 55 @NonNull String name, 56 boolean required, 57 boolean prohibited) { 58 validateAttribute(attribute, name, required, prohibited, null); 59 } 60 validateId( @ullable String id, @NonNull String name, boolean required, boolean prohibited)61 static void validateId( 62 @Nullable String id, 63 @NonNull String name, 64 boolean required, 65 boolean prohibited) { 66 validateAttribute(id, name, required, prohibited, null); 67 if (!Pattern.compile("[0-9a-zA-Z_]+").matcher(id).matches()) { 68 throw new IllegalStateException("Attribute " + name + " invalid"); 69 } 70 } 71 72 @AnyRes validateResId( @ullable @nyRes Integer value, @NonNull String name, boolean required, boolean prohibited)73 static int validateResId( 74 @Nullable @AnyRes Integer value, 75 @NonNull String name, 76 boolean required, 77 boolean prohibited) { 78 validateAttribute(value, name, required, prohibited, Resources.ID_NULL); 79 if (value == null) { 80 return Resources.ID_NULL; 81 } 82 if (required && value == Resources.ID_NULL) { 83 throwRequiredAttributeInvalid(name); 84 } 85 return value; 86 } 87 validateIntDef( @ullable Integer value, @NonNull String name, boolean required, boolean prohibited, int defaultValue, int... validValues)88 static int validateIntDef( 89 @Nullable Integer value, 90 @NonNull String name, 91 boolean required, 92 boolean prohibited, 93 int defaultValue, 94 int... validValues) { 95 validateAttribute(value, name, required, prohibited, defaultValue); 96 if (value == null) { 97 return defaultValue; 98 } 99 100 boolean found = false; 101 for (int i = 0; i < validValues.length; i++) { 102 found |= (value == validValues[i]); 103 } 104 if (!found) { 105 throw new IllegalStateException("Attribute " + name + " invalid"); 106 } 107 return value; 108 } 109 validateInteger( @ullable Integer value, @NonNull String name, boolean required, boolean prohibited, int defaultValue)110 static int validateInteger( 111 @Nullable Integer value, 112 @NonNull String name, 113 boolean required, 114 boolean prohibited, 115 int defaultValue) { 116 validateAttribute(value, name, required, prohibited, defaultValue); 117 if (value == null) { 118 return defaultValue; 119 } 120 return value; 121 } 122 validateBoolean( @ullable Boolean value, @NonNull String name, boolean required, boolean prohibited, boolean defaultValue)123 static boolean validateBoolean( 124 @Nullable Boolean value, 125 @NonNull String name, 126 boolean required, 127 boolean prohibited, 128 boolean defaultValue) { 129 validateAttribute(value, name, required, prohibited, defaultValue); 130 if (value == null) { 131 return defaultValue; 132 } 133 return value; 134 } 135 136 /** 137 * Validates a collection argument from a builder. 138 * 139 * <ul> 140 * <li>If {@code required}, a non-empty collection must be supplied. 141 * <li>If {@code prohibited}, an empty collection must be supplied. 142 * </ul> 143 */ validateCollection( @onNull Collection<T> value, @NonNull String name, boolean required, boolean prohibited)144 static <T> void validateCollection( 145 @NonNull Collection<T> value, 146 @NonNull String name, 147 boolean required, 148 boolean prohibited) { 149 if (value.isEmpty() && required) { 150 throwRequiredAttributeMissing(name); 151 } 152 if (!value.isEmpty() && prohibited) { 153 throwProhibitedAttributePresent(name); 154 } 155 } 156 throwRequiredAttributeMissing(@onNull String attribute)157 static void throwRequiredAttributeMissing(@NonNull String attribute) { 158 throw new IllegalStateException("Required attribute " + attribute + " missing"); 159 } 160 throwProhibitedAttributePresent(@onNull String attribute)161 static void throwProhibitedAttributePresent(@NonNull String attribute) { 162 throw new IllegalStateException("Prohibited attribute " + attribute + " present"); 163 } 164 throwRequiredAttributeInvalid(@onNull String attribute)165 static void throwRequiredAttributeInvalid(@NonNull String attribute) { 166 throw new IllegalStateException("Required attribute " + attribute + " invalid"); 167 } 168 } 169