• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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.compatibility.common.util;
18 
19 import com.android.tradefed.command.remote.DeviceDescriptor;
20 import com.android.tradefed.log.LogUtil.CLog;
21 import com.android.tradefed.targetprep.TargetSetupError;
22 
23 import com.google.common.annotations.VisibleForTesting;
24 
25 import org.xmlpull.v1.XmlPullParser;
26 import org.xmlpull.v1.XmlPullParserException;
27 import org.xmlpull.v1.XmlPullParserFactory;
28 
29 import java.io.File;
30 import java.io.FileInputStream;
31 import java.io.IOException;
32 import java.io.InputStream;
33 import java.io.InputStreamReader;
34 import java.net.URISyntaxException;
35 import java.security.CodeSource;
36 import java.util.HashMap;
37 import java.util.Map;
38 
39 /**
40  * Reads URL replacement configurations from the config file UrlReplacement.xml in the
41  * android-cts/tools directory (if it exists), or from the file path set in the env variable
42  * URL_REPLACEMENT_PATH.
43  *
44  * <p>Example usage: UrlReplacement.init(); // MUST be the first call to this class. String
45  * dynamicConfigUrl = UrlReplacement.getDynamicConfigServerUrl(); ...
46  * UrlReplacement.getUrlReplacementMap();
47  */
48 public final class UrlReplacement {
49     private static final String NS = null;
50     private static final String DYNAMIC_CONFIG_URL_TAG = "dynamicConfigUrl";
51     private static final String URL_REPLACEMENT_TAG = "urlReplacement";
52     private static final String ENTRY_TAG = "entry";
53     private static final String REPLACEMENT_TAG = "replacement";
54     private static final String URL_ATTR = "url";
55     private static final String URL_REPLACEMENT_FILENAME = "UrlReplacement.xml";
56 
57     private static final String URL_REPLACEMENT_PATH_ENV = "URL_REPLACEMENT_PATH";
58 
59     private static String dynamicConfigServerUrl = null;
60     private static Map<String, String> urlReplacementMap = new HashMap<>();
61 
62     @VisibleForTesting static Boolean initialized = false;
63 
64     /** Initializes the Dynamic Config Server URL and URL replacements from the xml file. */
init()65     public static void init() throws TargetSetupError {
66         init(getUrlReplacementConfigFile());
67     }
68 
69     /** Gets the URL for the DynamicConfigServer. Must be called after init(). */
getDynamicConfigServerUrl()70     public static String getDynamicConfigServerUrl() {
71         return dynamicConfigServerUrl;
72     }
73 
74     /** Gets the URL replacement map. Must be called after init(). */
getUrlReplacementMap()75     public static Map<String, String> getUrlReplacementMap() {
76         return new HashMap<>(urlReplacementMap);
77     }
78 
79     @VisibleForTesting
init(File urlReplacementConfigFile)80     static void init(File urlReplacementConfigFile) throws TargetSetupError {
81         if (initialized) {
82             return;
83         }
84         synchronized (UrlReplacement.class) {
85             if (initialized) {
86                 return;
87             }
88             try {
89                 if (urlReplacementConfigFile.exists()) {
90                     InputStream inputStream = new FileInputStream(urlReplacementConfigFile);
91                     XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser();
92                     parser.setInput(new InputStreamReader(inputStream));
93                     parser.nextTag();
94 
95                     parser.require(XmlPullParser.START_TAG, NS, URL_REPLACEMENT_TAG);
96                     parser.nextTag();
97 
98                     parser.require(XmlPullParser.START_TAG, NS, DYNAMIC_CONFIG_URL_TAG);
99                     dynamicConfigServerUrl = parser.nextText();
100                     parser.require(XmlPullParser.END_TAG, NS, DYNAMIC_CONFIG_URL_TAG);
101 
102                     while (parser.nextTag() == XmlPullParser.START_TAG) {
103                         parser.require(XmlPullParser.START_TAG, NS, ENTRY_TAG);
104                         String key = parser.getAttributeValue(NS, URL_ATTR);
105                         parser.nextTag();
106                         parser.require(XmlPullParser.START_TAG, NS, REPLACEMENT_TAG);
107                         String value = parser.nextText();
108                         parser.require(XmlPullParser.END_TAG, NS, REPLACEMENT_TAG);
109                         parser.nextTag();
110                         parser.require(XmlPullParser.END_TAG, NS, ENTRY_TAG);
111                         if (key != null && value != null) {
112                             urlReplacementMap.put(key, value);
113                         }
114                     }
115 
116                     parser.require(XmlPullParser.END_TAG, NS, URL_REPLACEMENT_TAG);
117                 } else {
118                     CLog.i(
119                             "UrlReplacement file [%s] does not exist",
120                             urlReplacementConfigFile.getAbsolutePath());
121                 }
122                 initialized = true;
123             } catch (XmlPullParserException | IOException e) {
124                 throw new TargetSetupError(
125                         "Failed to parse URL replacement config", e, (DeviceDescriptor) null);
126             }
127         }
128     }
129 
130     @VisibleForTesting
getUrlReplacementConfigFile()131     static File getUrlReplacementConfigFile() throws TargetSetupError {
132         // Try to get the config file from the .jar directory.
133         CodeSource codeSource = UrlReplacement.class.getProtectionDomain().getCodeSource();
134         String toolDirectory;
135         try {
136             toolDirectory = new File(codeSource.getLocation().toURI()).getParent();
137         } catch (URISyntaxException e) {
138             throw new TargetSetupError(
139                     "Failed to locate urlReplacement.xml file", e, (DeviceDescriptor) null);
140         }
141         File file = new File(toolDirectory + File.separator + URL_REPLACEMENT_FILENAME);
142 
143         // Try to get the config file from environment variable.
144         if (!file.exists()) {
145             String urlReplacementPathEnv = System.getenv(URL_REPLACEMENT_PATH_ENV);
146             if (urlReplacementPathEnv != null) {
147                 return new File(urlReplacementPathEnv);
148             }
149         }
150         return file;
151     }
152 
UrlReplacement()153     private UrlReplacement() {}
154 }
155