1 /*
2  * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 package ohos;
17 
18 import java.util.AbstractMap;
19 import java.util.HashMap;
20 import java.util.Map;
21 import java.util.function.Function;
22 
23 /**
24  * command parser.
25  *
26  */
27 public class CommandParser {
28     /**
29      * Parses and returns the hap list that supports the device type.
30      */
31     public static final String PARSE_MODE_HAPLIST = "hap-list";
32 
33     /**
34      * Parses and returns the information about the hap.
35      */
36     public static final String PARSE_MODE_HAPINFO = "hap-info";
37 
38     private static final String CMD_MODE = "--mode";
39     private static final String CMD_JSON_PATH = "--json-path";
40     private static final String CMD_PROFILE_PATH = "--profile-path";
41     private static final String CMD_INDEX_PATH = "--index-path";
42     private static final String CMD_JS_PATH = "--js-path";
43     private static final String CMD_ETS_PATH = "--ets-path";
44     private static final String CMD_HNP_PATH = "--hnp-path";
45     private static final String CMD_RPCID_PATH = "--rpcid-path";
46     private static final String CMD_RPCID = "--rpcid";
47     private static final String CMD_SO_PATH = "--maple-so-path";
48     private static final String CMD_SO_DIR = "--maple-so-dir";
49     private static final String CMD_ABILITY_SO_PATH = "--ability-so-path";
50     private static final String CMD_DEX_PATH = "--dex-path";
51     private static final String CMD_ABC_PATH = "--abc-path";
52     private static final String CMD_FILE_PATH = "--file-path";
53     private static final String CMD_LIB_PATH = "--lib-path";
54     private static final String CMD_RES_PATH = "--res-path";
55     private static final String CMD_RESOURCES_PATH = "--resources-path";
56     private static final String CMD_ASSETS_PATH = "--assets-path";
57     private static final String CMD_APK_PATH = "--shell-apk-path";
58     private static final String CMD_HAP_PATH = "--hap-path";
59     private static final String CMD_APP_PATH = "--app-path";
60     private static final String CMD_SIGNATURE_PATH = "--signature-path";
61     private static final String CMD_CERTIFICATE_PATH = "--certificate-path";
62     private static final String CMD_FORCE = "--force";
63     private static final String CMD_OUT_PATH = "--out-path";
64     private static final String CMD_PACK_INFO_PATH = "--pack-info-path";
65     private static final String CMD_ENCRYPT_PATH = "--encrypt-path";
66     private static final String CMD_BIN_PATH = "--bin-path";
67     private static final String CMD_JAR_PATH = "--jar-path";
68     private static final String CMD_TXT_PATH = "--txt-path";
69     private static final String CMD_HAR_PATH = "--har-path";
70     private static final String CMD_HSP_PATH = "--hsp-path";
71     private static final String CMD_PARSE_MODE = "--p";
72     private static final String CMD_PACK_RES_PATH = "--pack-res-path";
73     private static final String CMD_UNPACKAPK = "--unpackapk";
74     private static final String CMD_UNPACK_CUT_ENTRY_APK = "--unpack-cut_entry";
75     private static final String CMD_SHAREDLIBS_PATH = "--shared-libs-path";
76     private static final String CMD_ENTRYCARD_PATH = "--entrycard-path";
77     private static final String CMD_HAP_LIST = "--hap-list";
78     private static final String CMD_HSP_LIST = "--hsp-list";
79     private static final String CMD_APP_LIST = "--app-list";
80     private static final String CMD_DIR_LIST = "--dir-list";
81     private static final String CMD_HQF_LIST = "--hqf-list";
82     private static final String CMD_APPQF_PATH = "--appqf-path";
83     private static final String CMD_AN_PATH = "--an-path";
84     private static final String CMD_AP_PATH = "--ap-path";
85     private static final String MAIN_MODULE_LIMIT = "--main-module-limit";
86     private static final String NORMAL_MODULE_LIMIT = "--normal-module-limit";
87     private static final String TOTAL_LIMIT = "--total-limit";
88     private static final String VERSION_CODE = "--version-code";
89     private static final String VERSION_NAME = "--version-name";
90     private static final String INPUT_LIST = "--input-list";
91     private static final String INPUT = "--input";
92     private static final String STAT_DUPLICATE = "--stat-duplicate";
93     private static final String STAT_SUFFIX = "--stat-suffix";
94     private static final String STAT_FILE_SIZE = "--stat-file-size";
95     private static final String CMD_COMPRESS_LEVEL = "--compress-level";
96     private static final String CMD_PKG_CONTEXT_PATH = "--pkg-context-path";
97     private static final String CMD_BUNDLE_NAME = "--bundle-name";
98     private static final String PARSER_STAT_DUPLICATE_ERROR = "code:9132600 " +
99             "error:statDuplicate is invalid! Must be true or false.";
100     private static final String PARSER_STAT_SUFFIX_ERROR = "code:9132601 " +
101             "error:statSuffix is invalid! Must be true or false.";
102     private static final int PARSE_MODE_VALUE_LENGTH = 2;
103     private static final Log LOG = new Log(CommandParser.class.toString());
104     private static final Map<String, Function<Map.Entry<Utility, String>, Boolean>> commandFuncs = new HashMap<>();
105 
106     static {
107         initCommandFuncs();
108     }
109 
initCommandFuncs()110     private static void initCommandFuncs() {
111         commandFuncs.put(CMD_MODE, entry -> {
112             entry.getKey().setMode(entry.getValue());
113             return true;
114         });
115         commandFuncs.put(CMD_JSON_PATH, entry -> {
116             entry.getKey().setJsonPath(entry.getValue());
117             return true;
118         });
119         commandFuncs.put(CMD_PROFILE_PATH, entry -> {
120             entry.getKey().setProfilePath(entry.getValue());
121             return true;
122         });
123         commandFuncs.put(CMD_INDEX_PATH, entry -> {
124             entry.getKey().setIndexPath(entry.getValue());
125             return true;
126         });
127         commandFuncs.put(CMD_JS_PATH, entry -> {
128             entry.getKey().setJsPath(entry.getValue());
129             return true;
130         });
131         commandFuncs.put(CMD_ETS_PATH, entry -> {
132             entry.getKey().setEtsPath(entry.getValue());
133             return true;
134         });
135         commandFuncs.put(CMD_HNP_PATH, entry -> {
136             entry.getKey().setHnpPath(entry.getValue());
137             return true;
138         });
139         commandFuncs.put(CMD_RPCID_PATH, entry -> {
140             entry.getKey().setRpcidPath(entry.getValue());
141             return true;
142         });
143         commandFuncs.put(CMD_RPCID, entry -> {
144             entry.getKey().setRpcid(entry.getValue());
145             return true;
146         });
147         commandFuncs.put(CMD_SO_PATH, entry -> {
148             entry.getKey().setSoPath(entry.getValue());
149             return true;
150         });
151         commandFuncs.put(CMD_SO_DIR, entry -> {
152             entry.getKey().setSoDir(entry.getValue());
153             return true;
154         });
155         commandFuncs.put(CMD_ABILITY_SO_PATH, entry -> {
156             entry.getKey().setAbilitySoPath(entry.getValue());
157             return true;
158         });
159         commandFuncs.put(CMD_DEX_PATH, entry -> {
160             entry.getKey().setDexPath(entry.getValue());
161             return true;
162         });
163         commandFuncs.put(CMD_ABC_PATH, entry -> {
164             entry.getKey().setAbcPath(entry.getValue());
165             return true;
166         });
167         commandFuncs.put(CMD_FILE_PATH, entry -> {
168             entry.getKey().setFilePath(entry.getValue());
169             return true;
170         });
171         commandFuncs.put(CMD_LIB_PATH, entry -> {
172             entry.getKey().setLibPath(entry.getValue());
173             return true;
174         });
175         commandFuncs.put(CMD_RES_PATH, entry -> {
176             entry.getKey().setResPath(entry.getValue());
177             return true;
178         });
179         commandFuncs.put(CMD_RESOURCES_PATH, entry -> {
180             entry.getKey().setResourcesPath(entry.getValue());
181             return true;
182         });
183         commandFuncs.put(CMD_ASSETS_PATH, entry -> {
184             entry.getKey().setAssetsPath(entry.getValue());
185             return true;
186         });
187         commandFuncs.put(CMD_APK_PATH, entry -> {
188             entry.getKey().setApkPath(entry.getValue());
189             return true;
190         });
191         commandFuncs.put(CMD_HAP_PATH, entry -> {
192             entry.getKey().setHapPath(entry.getValue());
193             return true;
194         });
195         commandFuncs.put(CMD_APP_PATH, entry -> {
196             entry.getKey().setAppPath(entry.getValue());
197             return true;
198         });
199         commandFuncs.put(CMD_SIGNATURE_PATH, entry -> {
200             entry.getKey().setSignaturePath(entry.getValue());
201             return true;
202         });
203         commandFuncs.put(CMD_CERTIFICATE_PATH, entry -> {
204             entry.getKey().setCertificatePath(entry.getValue());
205             return true;
206         });
207         commandFuncs.put(CMD_FORCE, entry -> {
208             entry.getKey().setForceRewrite(entry.getValue());
209             return true;
210         });
211         commandFuncs.put(CMD_OUT_PATH, entry -> {
212             entry.getKey().setOutPath(entry.getValue());
213             return true;
214         });
215         commandFuncs.put(CMD_PACK_INFO_PATH, entry -> {
216             entry.getKey().setPackInfoPath(entry.getValue());
217             return true;
218         });
219         commandFuncs.put(CMD_ENCRYPT_PATH, entry -> {
220             entry.getKey().setEncryptPath(entry.getValue());
221             return true;
222         });
223         commandFuncs.put(CMD_BIN_PATH, entry -> {
224             entry.getKey().setBinPath(entry.getValue());
225             return true;
226         });
227         commandFuncs.put(CMD_JAR_PATH, entry -> {
228             entry.getKey().setJarPath(entry.getValue());
229             return true;
230         });
231         commandFuncs.put(CMD_TXT_PATH, entry -> {
232             entry.getKey().setTxtPath(entry.getValue());
233             return true;
234         });
235         commandFuncs.put(CMD_HAR_PATH, entry -> {
236             entry.getKey().setHarPath(entry.getValue());
237             return true;
238         });
239         commandFuncs.put(CMD_HSP_PATH, entry -> {
240             entry.getKey().setHspPath(entry.getValue());
241             return true;
242         });
243         commandFuncs.put(CMD_PACK_RES_PATH, entry -> {
244             entry.getKey().setPackResPath(entry.getValue());
245             return true;
246         });
247         commandFuncs.put(CMD_UNPACKAPK, entry -> {
248             entry.getKey().setUnpackApk(entry.getValue());
249             return true;
250         });
251         commandFuncs.put(CMD_UNPACK_CUT_ENTRY_APK, entry -> {
252             entry.getKey().setUnpackCutEntryApk(entry.getValue());
253             return true;
254         });
255         commandFuncs.put(CMD_SHAREDLIBS_PATH, entry -> {
256             entry.getKey().setSharedLibsPath(entry.getValue());
257             return true;
258         });
259         commandFuncs.put(CMD_ENTRYCARD_PATH, entry -> {
260             entry.getKey().setEntryCardPath(entry.getValue());
261             return true;
262         });
263         commandFuncs.put(CMD_HAP_LIST, entry -> {
264             entry.getKey().setHapList(entry.getValue());
265             return true;
266         });
267         commandFuncs.put(CMD_HSP_LIST, entry -> {
268             entry.getKey().setHspList(entry.getValue());
269             return true;
270         });
271         commandFuncs.put(CMD_APP_LIST, entry -> {
272             entry.getKey().setAppList(entry.getValue());
273             return true;
274         });
275         commandFuncs.put(CMD_DIR_LIST, entry -> {
276             entry.getKey().setDirList(entry.getValue());
277             return true;
278         });
279         commandFuncs.put(CMD_HQF_LIST, entry -> {
280             entry.getKey().setHqfList(entry.getValue());
281             return true;
282         });
283         commandFuncs.put(CMD_APPQF_PATH, entry -> {
284             entry.getKey().setAPPQFPath(entry.getValue());
285             return true;
286         });
287         commandFuncs.put(CMD_AN_PATH, entry -> {
288             entry.getKey().setANPath(entry.getValue());
289             return true;
290         });
291         commandFuncs.put(CMD_AP_PATH, entry -> {
292             entry.getKey().setAPPath(entry.getValue());
293             return true;
294         });
295         commandFuncs.put(MAIN_MODULE_LIMIT, entry -> {
296             entry.getKey().setMainModuleLimit(entry.getValue());
297             return true;
298         });
299         commandFuncs.put(NORMAL_MODULE_LIMIT, entry -> {
300             entry.getKey().setNormalModuleLimit(entry.getValue());
301             return true;
302         });
303         commandFuncs.put(TOTAL_LIMIT, entry -> {
304             entry.getKey().setTotalLimit(entry.getValue());
305             return true;
306         });
307         commandFuncs.put(VERSION_CODE, entry -> {
308             try {
309                 entry.getKey().setVersionCode(Integer.parseInt(entry.getValue()));
310             } catch (NumberFormatException ignored) {
311                 LOG.error("CommandParser::--version-code value must be number.");
312                 return false;
313             }
314             return true;
315         });
316         commandFuncs.put(VERSION_NAME, entry -> {
317             entry.getKey().setVersionName(entry.getValue());
318             return true;
319         });
320         commandFuncs.put(INPUT_LIST, entry -> {
321             entry.getKey().setInputList(entry.getValue());
322             return true;
323         });
324         commandFuncs.put(INPUT, entry -> {
325             entry.getKey().setInput(entry.getValue());
326             return true;
327         });
328         commandFuncs.put(STAT_DUPLICATE, entry -> {
329             if (Boolean.TRUE.toString().equals(entry.getValue()) || Boolean.FALSE.toString().equals(entry.getValue())) {
330                 entry.getKey().setStatDuplicate(Boolean.parseBoolean(entry.getValue()));
331                 return true;
332             } else {
333                 LOG.error(PARSER_STAT_DUPLICATE_ERROR);
334                 return false;
335             }
336         });
337         commandFuncs.put(STAT_SUFFIX, entry -> {
338             if (Boolean.TRUE.toString().equals(entry.getValue()) || Boolean.FALSE.toString().equals(entry.getValue())) {
339                 entry.getKey().setStatSuffix(Boolean.parseBoolean(entry.getValue()));
340                 return true;
341             } else {
342                 LOG.error(PARSER_STAT_SUFFIX_ERROR);
343                 return false;
344             }
345         });
346         commandFuncs.put(STAT_FILE_SIZE, entry -> {
347             entry.getKey().setStatFileSize(entry.getValue());
348             return true;
349         });
350         commandFuncs.put(CMD_COMPRESS_LEVEL, entry -> {
351             String level = entry.getValue();
352             try {
353                 int compressLevel = Integer.parseInt(level);
354                 if (compressLevel < 1 || compressLevel > 9) {
355                     LOG.error("CommandParser::--compress-level value must be number between 1-9");
356                     return false;
357                 } else {
358                     entry.getKey().setCompressLevel(compressLevel);
359                     return true;
360                 }
361             } catch (NumberFormatException ex) {
362                 LOG.error("CommandParser::--compress-level value must be number between 1-9");
363                 return false;
364             }
365         });
366         commandFuncs.put(CMD_PKG_CONTEXT_PATH, entry -> {
367             entry.getKey().setPkgContextPath(entry.getValue());
368             return true;
369         });
370         commandFuncs.put(CMD_BUNDLE_NAME, entry -> {
371             entry.getKey().setBundleName(entry.getValue());
372             return true;
373         });
374     }
375 
376 
377     /**
378      * judge args is null and enter parser.
379      *
380      * @param utility common data
381      * @param args command line
382      * @return commandParser if input valid
383      */
commandParser(Utility utility, String[] args)384     public static boolean commandParser(Utility utility, String[] args) {
385         if (args == null) {
386             LOG.error("CommandParser::commandParser args is null!");
387             return false;
388         }
389         for (int i = 0; i < args.length - 1; ++i) {
390             String key = args[i];
391             String value = args[i + 1];
392             Map.Entry<Utility, String> entry = new AbstractMap.SimpleEntry<>(utility, value);
393             if (commandFuncs.get(key) != null) {
394                 commandFuncs.get(key).apply(entry);
395                 ++i;
396             } else if (CMD_PARSE_MODE.equals(key)) {
397                 if (i + PARSE_MODE_VALUE_LENGTH >= args.length) {
398                     LOG.error("input wrong number value for --p command");
399                     return false;
400                 }
401                 utility.setParseMode(args[i + 1]);
402                 if (PARSE_MODE_HAPLIST.equals(utility.getParseMode())) {
403                     utility.setDeviceType(args[i + PARSE_MODE_VALUE_LENGTH]);
404                 } else if (PARSE_MODE_HAPINFO.equals(utility.getParseMode())) {
405                     utility.setHapName(args[i + PARSE_MODE_VALUE_LENGTH]);
406                 }
407                 i += PARSE_MODE_VALUE_LENGTH;
408             } else {
409                 LOG.warning(key + " is invalid!");
410             }
411         }
412         return true;
413     }
414 }
415