• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 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 package com.android.car.internal.util;
17 
18 import android.annotation.AppIdInt;
19 import android.annotation.ColorInt;
20 import android.annotation.FloatRange;
21 import android.annotation.IntRange;
22 import android.annotation.NonNull;
23 import android.annotation.Size;
24 import android.annotation.UserIdInt;
25 import android.car.builtin.util.ValidationHelper;
26 
27 import java.lang.annotation.Annotation;
28 
29 /**
30  * Validations for common annotations, e.g. {@link IntRange}, {@link UserIdInt}, etc.
31  *
32  * For usability from generated {@link DataClass} code, all validations are overloads of
33  * {@link #validate} with the following shape:
34  * {@code
35  *      <A extends Annotation> void validate(
36  *              Class<A> cls, A ignored, Object value[, (String, Object)... annotationParams])
37  * }
38  * The ignored {@link Annotation} parameter is used to differentiate between overloads that would
39  * otherwise have the same jvm signature. It's usually null at runtime.
40  */
41 public final class AnnotationValidations {
AnnotationValidations()42     private AnnotationValidations() {
43     }
44 
45     /** Check class javadoc. */
validate(Class<UserIdInt> annotation, UserIdInt ignored, int value)46     public static void validate(Class<UserIdInt> annotation, UserIdInt ignored, int value) {
47         if (!ValidationHelper.isUserIdValid(value)) {
48             invalid(annotation, value);
49         }
50     }
51 
52     /** Check class javadoc. */
validate(Class<AppIdInt> annotation, AppIdInt ignored, int value)53     public static void validate(Class<AppIdInt> annotation, AppIdInt ignored, int value) {
54         if (!ValidationHelper.isAppIdValid(value)) {
55             invalid(annotation, value);
56         }
57     }
58 
59     /** Check class javadoc. */
validate(Class<IntRange> annotation, IntRange ignored, int value, String paramName1, long param1, String paramName2, long param2)60     public static void validate(Class<IntRange> annotation, IntRange ignored, int value,
61             String paramName1, long param1, String paramName2, long param2) {
62         validate(annotation, ignored, value, paramName1, param1);
63         validate(annotation, ignored, value, paramName2, param2);
64     }
65 
66     /** Check class javadoc. */
validate(Class<IntRange> annotation, IntRange ignored, int value, String paramName, long param)67     public static void validate(Class<IntRange> annotation, IntRange ignored, int value,
68             String paramName, long param) {
69         switch (paramName) {
70             case "from":
71                 if (value < param) {
72                     invalid(annotation, value, paramName, param);
73                 }
74                 break;
75             case "to":
76                 if (value > param) {
77                     invalid(annotation, value, paramName, param);
78                 }
79                 break;
80             default:
81                 break;
82         }
83     }
84 
85     /**
86      * Validate a long value with two parameters.
87      */
validate(Class<IntRange> annotation, IntRange ignored, long value, String paramName1, long param1, String paramName2, long param2)88     public static void validate(Class<IntRange> annotation, IntRange ignored, long value,
89             String paramName1, long param1, String paramName2, long param2) {
90         validate(annotation, ignored, value, paramName1, param1);
91         validate(annotation, ignored, value, paramName2, param2);
92     }
93 
94     /**
95      * Validate a long value with one parameter.
96      */
validate(Class<IntRange> annotation, IntRange ignored, long value, String paramName, long param)97     public static void validate(Class<IntRange> annotation, IntRange ignored, long value,
98             String paramName, long param) {
99         switch (paramName) {
100             case "from":
101                 if (value < param) {
102                     invalid(annotation, value, paramName, param);
103                 }
104                 break;
105             case "to":
106                 if (value > param) {
107                     invalid(annotation, value, paramName, param);
108                 }
109                 break;
110             default:
111                 break;
112         }
113     }
114 
115     /** Check class javadoc. */
validate(Class<FloatRange> annotation, FloatRange ignored, float value, String paramName1, float param1, String paramName2, float param2)116     public static void validate(Class<FloatRange> annotation, FloatRange ignored, float value,
117             String paramName1, float param1, String paramName2, float param2) {
118         validate(annotation, ignored, value, paramName1, param1);
119         validate(annotation, ignored, value, paramName2, param2);
120     }
121 
122     /** Check class javadoc. */
validate(Class<FloatRange> annotation, FloatRange ignored, float value, String paramName, float param)123     public static void validate(Class<FloatRange> annotation, FloatRange ignored, float value,
124             String paramName, float param) {
125         switch (paramName) {
126             case "from":
127                 if (value < param) invalid(annotation, value, paramName, param);
128                 break;
129             case "to":
130                 if (value > param) invalid(annotation, value, paramName, param);
131                 break;
132             default:
133                 break;
134         }
135     }
136 
137     /** Check class javadoc. */
validate(Class<NonNull> annotation, NonNull ignored, Object value)138     public static void validate(Class<NonNull> annotation, NonNull ignored, Object value) {
139         if (value == null) {
140             throw new NullPointerException();
141         }
142     }
143 
144     /** Check class javadoc. */
validate(Class<Size> annotation, Size ignored, int value, String paramName1, int param1, String paramName2, int param2)145     public static void validate(Class<Size> annotation, Size ignored, int value,
146             String paramName1, int param1, String paramName2, int param2) {
147         validate(annotation, ignored, value, paramName1, param1);
148         validate(annotation, ignored, value, paramName2, param2);
149     }
150 
151     /** Check class javadoc. */
validate(Class<Size> annotation, Size ignored, int value, String paramName, int param)152     public static void validate(Class<Size> annotation, Size ignored, int value,
153             String paramName, int param) {
154         switch (paramName) {
155             case "value": {
156                 if (param != -1 && value != param) invalid(annotation, value, paramName, param);
157             }
158             break;
159             case "min": {
160                 if (value < param) invalid(annotation, value, paramName, param);
161             }
162             break;
163             case "max": {
164                 if (value > param) invalid(annotation, value, paramName, param);
165             }
166             break;
167             case "multiple": {
168                 if (value % param != 0) invalid(annotation, value, paramName, param);
169             }
170             break;
171             default:
172                 break;
173         }
174     }
175 
176     /** @deprecated Use other versions. */
177     @Deprecated
validate(Class<? extends Annotation> annotation, Annotation ignored, Object value, Object... params)178     public static void validate(Class<? extends Annotation> annotation,
179             Annotation ignored, Object value, Object... params) {
180     }
181 
182     /** @deprecated Use other versions. */
183     @Deprecated
validate(Class<? extends Annotation> annotation, Annotation ignored, Object value)184     public static void validate(Class<? extends Annotation> annotation,
185             Annotation ignored, Object value) {
186     }
187 
188     /** @deprecated Use other versions. */
189     @Deprecated
validate(Class<? extends Annotation> annotation, Annotation ignored, int value, Object... params)190     public static void validate(Class<? extends Annotation> annotation,
191             Annotation ignored, int value, Object... params) {
192     }
193 
194     /** Check class javadoc. */
validate(Class<? extends Annotation> annotation, Annotation ignored, int value)195     public static void validate(Class<? extends Annotation> annotation,
196             Annotation ignored, int value) {
197         if (("android.annotation".equals(annotation.getPackageName())
198                 && annotation.getSimpleName().endsWith("Res"))
199                 || ColorInt.class.equals(annotation)) {
200             if (value < 0) {
201                 invalid(annotation, value);
202             }
203         }
204     }
205 
206     /** Check class javadoc. */
validate(Class<? extends Annotation> annotation, Annotation ignored, long value)207     public static void validate(Class<? extends Annotation> annotation,
208             Annotation ignored, long value) {
209         if ("android.annotation".equals(annotation.getPackageName())
210                 && annotation.getSimpleName().endsWith("Long")) {
211             if (value < 0L) {
212                 invalid(annotation, value);
213             }
214         }
215     }
216 
invalid(Class<? extends Annotation> annotation, Object value)217     private static void invalid(Class<? extends Annotation> annotation, Object value) {
218         invalid("@" + annotation.getSimpleName(), value);
219     }
220 
invalid(Class<? extends Annotation> annotation, Object value, String paramName, Object param)221     private static void invalid(Class<? extends Annotation> annotation, Object value,
222             String paramName, Object param) {
223         String paramPrefix = "value".equals(paramName) ? "" : paramName + " = ";
224         invalid("@" + annotation.getSimpleName() + "(" + paramPrefix + param + ")", value);
225     }
226 
invalid(String valueKind, Object value)227     private static void invalid(String valueKind, Object value) {
228         throw new IllegalStateException("Invalid " + valueKind + ": " + value);
229     }
230 }
231