1 /*
2  * Copyright (C) 2018 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.class2greylist;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 
21 import com.google.common.base.Joiner;
22 import com.google.common.collect.ImmutableMap;
23 import java.io.IOException;
24 import java.util.ArrayList;
25 import java.util.List;
26 import java.util.Map;
27 import org.apache.bcel.classfile.AnnotationEntry;
28 import org.junit.Before;
29 import org.junit.Test;
30 
31 public class RepeatedAnnotationHandlerTest extends AnnotationHandlerTestBase {
32 
33     @Before
setup()34     public void setup() {
35         // To keep the test simpler and more concise, we don't use a real annotation here, but use
36         // our own @Annotation and @Annotation.Multi that have the same relationship.
37         mJavac.addSource("annotation.Annotation", Joiner.on('\n').join(
38                 "package annotation;",
39                 "import static java.lang.annotation.RetentionPolicy.CLASS;",
40                 "import java.lang.annotation.Repeatable;",
41                 "import java.lang.annotation.Retention;",
42                 "@Repeatable(Annotation.Multi.class)",
43                 "@Retention(CLASS)",
44                 "public @interface Annotation {",
45                 "  Class<?> clazz();",
46                 "  @Retention(CLASS)",
47                 "  @interface Multi {",
48                 "    Annotation[] value();",
49                 "  }",
50                 "}"));
51     }
52 
53     @Test
testRepeated()54     public void testRepeated() throws IOException {
55         mJavac.addSource("a.b.Class", Joiner.on('\n').join(
56                 "package a.b;",
57                 "import annotation.Annotation;",
58                 "public class Class {",
59                 "  @Annotation(clazz=Integer.class)",
60                 "  @Annotation(clazz=Long.class)",
61                 "  public String method() {return null;}",
62                 "}"));
63         mJavac.compile();
64 
65         TestAnnotationHandler handler = new TestAnnotationHandler();
66         Map<String, AnnotationHandler> handlerMap =
67             ImmutableMap.of("Lannotation/Annotation$Multi;",
68                 new RepeatedAnnotationHandler("Lannotation/Annotation;", handler));
69         new AnnotationVisitor(mJavac.getCompiledClass("a.b.Class"), mStatus, handlerMap).visit();
70 
71         assertNoErrors();
72         assertThat(handler.getClasses()).containsExactly(
73                 "Ljava/lang/Integer;",
74                 "Ljava/lang/Long;");
75     }
76 
77     private static class TestAnnotationHandler extends AnnotationHandler {
78 
79         private final List<String> classes;
80 
TestAnnotationHandler()81         private TestAnnotationHandler() {
82             this.classes = new ArrayList<>();
83         }
84 
85         @Override
handleAnnotation(AnnotationEntry annotation, AnnotationContext context)86         void handleAnnotation(AnnotationEntry annotation,
87             AnnotationContext context) {
88             classes.add(annotation.getElementValuePairs()[0].getValue().stringifyValue());
89         }
90 
getClasses()91         private List<String> getClasses() {
92             return classes;
93         }
94     }
95 }
96