• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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 com.android.annotationvisitor;
18 
19 import com.google.common.base.Preconditions;
20 
21 import org.apache.bcel.classfile.AnnotationElementValue;
22 import org.apache.bcel.classfile.AnnotationEntry;
23 import org.apache.bcel.classfile.ArrayElementValue;
24 import org.apache.bcel.classfile.ElementValue;
25 import org.apache.bcel.classfile.ElementValuePair;
26 
27 /**
28  * Handles a repeated annotation container.
29  *
30  * <p>The enclosed annotations are passed to the {@link #mWrappedHandler}.
31  */
32 public class RepeatedAnnotationHandler extends AnnotationHandler {
33 
34     private static final String VALUE = "value";
35 
36     private final AnnotationHandler mWrappedHandler;
37     private final String mInnerAnnotationName;
38 
RepeatedAnnotationHandler(String innerAnnotationName, AnnotationHandler wrappedHandler)39     public RepeatedAnnotationHandler(String innerAnnotationName, AnnotationHandler wrappedHandler) {
40         mWrappedHandler = wrappedHandler;
41         mInnerAnnotationName = innerAnnotationName;
42     }
43 
44     @Override
handleAnnotation(AnnotationEntry annotation, AnnotationContext context)45     public void handleAnnotation(AnnotationEntry annotation, AnnotationContext context) {
46         // Verify that the annotation has the form we expect
47         ElementValuePair value = findValue(annotation);
48         if (value == null) {
49             context.reportError("No value found on %s", annotation.getAnnotationType());
50             return;
51         }
52         Preconditions.checkArgument(value.getValue() instanceof ArrayElementValue);
53         ArrayElementValue array = (ArrayElementValue) value.getValue();
54 
55         // call wrapped handler on each enclosed annotation:
56         for (ElementValue v : array.getElementValuesArray()) {
57             Preconditions.checkArgument(v instanceof AnnotationElementValue);
58             AnnotationElementValue aev = (AnnotationElementValue) v;
59             Preconditions.checkArgument(
60                     aev.getAnnotationEntry().getAnnotationType().equals(mInnerAnnotationName));
61             mWrappedHandler.handleAnnotation(aev.getAnnotationEntry(), context);
62         }
63     }
64 
findValue(AnnotationEntry a)65     private ElementValuePair findValue(AnnotationEntry a) {
66         for (ElementValuePair property : a.getElementValuePairs()) {
67             if (property.getNameString().equals(VALUE)) {
68                 return property;
69             }
70         }
71         // not found
72         return null;
73     }
74 }
75