1 /*
2  * Copyright (C) 2024 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 
18 package com.android.cts.ctsprofiles;
19 
20 import java.util.ArrayList;
21 import java.util.HashMap;
22 import java.util.HashSet;
23 import java.util.List;
24 import java.util.Map;
25 import java.util.Set;
26 
27 /** A class to manage annotations marked on the CTS class/method. */
28 public final class AnnotationManagement {
29 
30     private static final String TEST_METADATA_ERROR_MSG = "Not allowed to add new test metadata";
31 
32     // A list of annotations marked on the CTS class/method.
33     private final List<ClassProfile> mAnnotations = new ArrayList<>();
34 
35     // A map to store useful annotation values. For example, values collected from @ApiTest,
36     // @CddTest annotations. This values are indicating what the class/method is testing.
37     private final Map<String, Set<String>> mTestMetadata = new HashMap<>();
38 
39     private boolean mTestMetadataMerged = false;
40 
41     /** Gets all xTS annotation values mapped to the class/method. */
getAnnotations()42     public List<ClassProfile> getAnnotations() {
43         return mAnnotations;
44     }
45 
46     /** Gets all test metadata mapped to the class/method. */
getTestMetadata()47     public Map<String, Set<String>> getTestMetadata() {
48         if (!mTestMetadataMerged) {
49             resolveNestedTestMetadata();
50         }
51         return mTestMetadata;
52     }
53 
54     /** Adds a test metadata. */
addTestMetadata(String type, String value)55     public void addTestMetadata(String type, String value) {
56         if (mTestMetadataMerged) {
57             throw new RuntimeException(TEST_METADATA_ERROR_MSG);
58         }
59         mTestMetadata.putIfAbsent(type, new HashSet<>());
60         mTestMetadata.get(type).add(value);
61     }
62 
63     /** Adds an annotation marked on the class/method. */
addAnnotation(ClassProfile classProfile)64     public void addAnnotation(ClassProfile classProfile) {
65         mAnnotations.add(classProfile);
66     }
67 
68     /**
69      * Merges nested test metadata. For example, a customized annotation @MyAnnotation could be
70      * annotated by @ApiTest.
71      */
resolveNestedTestMetadata()72     private void resolveNestedTestMetadata() {
73         for (ClassProfile annotation : mAnnotations) {
74             annotation.annotationManagement.getTestMetadata().forEach((key, value) -> {
75                 mTestMetadata.putIfAbsent(key, new HashSet<>());
76                 mTestMetadata.get(key).addAll(value);
77             });
78         }
79         mTestMetadataMerged = true;
80     }
81 }
82