1 /*
2  * Copyright (c) 2021 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 com.alibaba.fastjson.JSON;
19 import com.alibaba.fastjson.JSONObject;
20 import com.alibaba.fastjson.JSONArray;
21 import com.alibaba.fastjson.JSONException;
22 
23 import java.io.File;
24 import java.util.ArrayList;
25 import java.util.HashMap;
26 import java.util.List;
27 import java.util.Map;
28 
29 class ModuleJsonUtil {
30     private static final String APP = "app";
31     private static final String BUNDLE_TYPE = "bundleType";
32     private static final String ABILITIES = "abilities";
33     private static final String VERSIONCODE = "versionCode";
34     private static final String VERSIONNAME = "versionName";
35     private static final String MIN_COMPATIBLE_VERSION_CODE = "minCompatibleVersionCode";
36     private static final String API_VERSION = "apiVersion";
37     private static final String MIN_API_VERSION = "minAPIVersion";
38     private static final String TARGET_API_VERSION = "targetAPIVersion";
39     private static final String API_RELEASE_TYPE = "apiReleaseType";
40     private static final String DEBUG = "debug";
41     private static final String COMPATIBLE = "compatible";
42     private static final String RELEASE_TYPE = "releaseType";
43     private static final String TARGET = "target";
44     private static final String VERSION = "version";
45     private static final String CODE = "code";
46     private static final String NAME = "name";
47     private static final String SKILLS = "skills";
48     private static final String SKILLS_ENTITIES = "entities";
49     private static final String SKILLS_ACTIONS = "actions";
50     private static final String ACTION_SYSTEM_HOME = "action.system.home";
51     private static final String ENTITY_SYSTEM_HOME = "entity.system.home";
52     private static final String MODULE = "module";
53     private static final String MODULES = "modules";
54     private static final String MODULE_NAME = "moduleName";
55     private static final String MODULE_TYPE = "moduleType";
56     private static final String DISTRO = "distro";
57     private static final String PACKAGE = "package";
58     private static final String PACKAGES = "packages";
59     private static final String SUMMARY = "summary";
60     private static final String BUNDLE_NAME = "bundleName";
61     private static final String ENTRY = "entry";
62     private static final char DOT = '.';
63     private static final String CONFIG_JSON = "config.json";
64     private static final String MODULE_JSON = "module.json";
65     private static final String DEVICE_TYPE = "deviceType";
66     private static final String DEVICE_TYPES = "deviceTypes";
67     private static final String TYPE= "type";
68     private static final String VENDOR = "vendor";
69     private static final String METADATA = "metadata";
70     private static final String RESOURCE = "resource";
71     private static final String PROFILE = "$profile:";
72     private static final String VALUE = "value";
73     private static final String JSON_PERFIX = ".json";
74     private static final String DISTRO_FILTER = "distroFilter";
75     private static final String DISTRIBUTION_FILTER = "distributionFilter";
76     private static final String DEPENDENCIES = "dependencies";
77     private static final String EXTENSION_ABILITIES = "extensionAbilities";
78     private static final String INSTALLATION_FREE = "installationFree";
79     private static final String PATCH_JSON = "patch.json";
80     private static final String PATCH_VERSION_CODE = "patchVersionCode";
81     private static final String PATCH_VERSION_NAME = "patchVersionName";
82     private static final String ORIGINAL_MODULE_HASH = "originalModuleHash";
83     private static final String EMPTY_STRING = "";
84     private static final String COMPRESS_NATIVE_LIBS = "compressNativeLibs";
85     private static final String ASAN_ENABLED = "asanEnabled";
86     private static final String TSAN_ENABLED = "tsanEnabled";
87     private static final String GWP_ASAN_ENABLED = "GWPAsanEnabled";
88     private static final String HW_ASAN_ENABLED = "hwasanEnabled";
89     private static final String UB_SAN_ENABLED = "ubsanEnabled";
90     private static final String ATOMIC_SERVICE = "atomicService";
91     private static final String SPLIT = "split";
92     private static final String MAIN = "main";
93     private static final String PRELOADS = "preloads";
94     private static final String SHARED = "shared";
95     private static final String APP_SERVICE = "appService";
96     private static final String REQUEST_PERMISSIONS = "requestPermissions";
97     private static final String TARGET_MODULE_NAME = "targetModuleName";
98     private static final String TARGET_PRIORITY = "targetPriority";
99     private static final String TARGET_BUNDLE_NAME = "targetBundleName";
100     private static final String DEVICE_CONFIG = "deviceConfig";
101     private static final String DEFAULT = "default";
102     private static final String COMPILE_SDK_VERSION = "compileSdkVersion";
103     private static final String COMPILE_SDK_TYPE = "compileSdkType";
104     private static final String PROXY_DATAS = "proxyDatas";
105     private static final String PROXY_DATA = "proxyData";
106     private static final String PROXY_URI = "uri";
107     private static final String CONTINUE_TYPE = "continueType";
108     private static final String CONTINUE_BUNDLE_NAME = "continueBundleName";
109     private static final String MULTI_APP_MODE = "multiAppMode";
110     private static final String MULTI_APP_MODE_TYPE = "multiAppModeType";
111     private static final String MULTI_APP_MODE_NUMBER = "maxCount";
112     private static final String FORMS = "forms";
113     private static final String DEFAULTDIMENSION = "defaultDimension";
114     private static final String SUPPORTDIMENSIONS = "supportDimensions";
115 
116     private static final Log LOG = new Log(ModuleJsonUtil.class.toString());
117 
118     /**
119      * get the version from json file for stage module.
120      *
121      * @param jsonString uncompress json object
122      * @return the result
123      * @throws BundleException Throws this exception if the json is not standard.
124      */
parseStageVersion(String jsonString)125     public static Version parseStageVersion(String jsonString) throws BundleException {
126         Version version = new Version();
127         JSONObject appObj = getAppObj(jsonString);
128         if (appObj.containsKey(VERSIONCODE) && appObj.containsKey(VERSIONNAME)) {
129             version.versionCode = appObj.getIntValue(VERSIONCODE);
130             version.versionName = appObj.getString(VERSIONNAME);
131         } else {
132             String errMsg = "ModuleJsonUtil:parseStageVersion json file do not contain version.";
133             LOG.error(errMsg);
134             throw new BundleException(errMsg);
135         }
136         if (appObj.containsKey(MIN_COMPATIBLE_VERSION_CODE)) {
137             version.minCompatibleVersionCode = appObj.getIntValue(MIN_COMPATIBLE_VERSION_CODE);
138         } else {
139             version.minCompatibleVersionCode = version.versionCode;
140         }
141         return version;
142     }
143 
144     /**
145      * get the version from json file for fa module.
146      *
147      * @param jsonString uncompress json object
148      * @return the result
149      * @throws BundleException Throws this exception if the json is not standard.
150      */
parseFaVersion(String jsonString)151     public static Version parseFaVersion(String jsonString) throws BundleException {
152         JSONObject appObj = getAppObj(jsonString);
153         JSONObject versionObj = appObj.getJSONObject(VERSION);
154         if (versionObj == null) {
155             LOG.error("ModuleJsonUtil:parseFaVersion failed : json file do not version.");
156             throw new BundleException("ModuleJsonUtil:parseFaVersion failed : json file do not version.");
157         }
158         Version version = new Version();
159         if (versionObj.containsKey(CODE) && versionObj.containsKey(NAME)) {
160             version.versionName = versionObj.getString(NAME);
161             version.versionCode = versionObj.getIntValue(CODE);
162         } else {
163             LOG.error("ModuleJsonUtil:parseFaVersion failed : json file do not version name or version code.");
164             throw new BundleException(
165                     "ModuleJsonUtil:parseFaVersion failed : json file do not version name or version code.");
166         }
167         if (versionObj.containsKey(MIN_COMPATIBLE_VERSION_CODE)) {
168             version.minCompatibleVersionCode = versionObj.getIntValue(MIN_COMPATIBLE_VERSION_CODE);
169         } else {
170             version.minCompatibleVersionCode = version.versionCode;
171         }
172         return version;
173     }
174 
175     /**
176      * get the bundleType fa module.
177      *
178      * @param jsonString uncompress json object
179      * @return the result
180      * @throws BundleException Throws this exception if the json is not standard.
181      */
parseFaBundleType(String jsonString)182     public static String parseFaBundleType(String jsonString) throws BundleException {
183         boolean installationFree = parseFAInstallationFree(jsonString);
184         if (installationFree) {
185             return ATOMIC_SERVICE;
186         }
187         return APP;
188     }
189 
190     /**
191      * get the apiVersion from json file for stage module.
192      *
193      * @param jsonString uncompress json object
194      * @return the result
195      * @throws BundleException Throws this exception if the json is not standard.
196      */
parseStageModuleApiVersion(String jsonString)197     public static ModuleApiVersion parseStageModuleApiVersion(String jsonString) throws BundleException {
198         JSONObject appObj = getAppObj(jsonString);
199         ModuleApiVersion moduleApiVersion = new ModuleApiVersion();
200         if (appObj.containsKey(MIN_API_VERSION)) {
201             moduleApiVersion.setCompatibleApiVersion(appObj.getIntValue(MIN_API_VERSION));
202         }
203         if (appObj.containsKey(TARGET_API_VERSION)) {
204             moduleApiVersion.setTargetApiVersion(appObj.getIntValue(TARGET_API_VERSION));
205         }
206         if (appObj.containsKey(API_RELEASE_TYPE)) {
207             moduleApiVersion.setReleaseType(appObj.getString(API_RELEASE_TYPE));
208         }
209         return moduleApiVersion;
210     }
211 
212     /**
213      * get the apiVersion from json file for fa module.
214      *
215      * @param jsonString uncompress json object
216      * @return the result
217      * @throws BundleException Throws this exception if the json is not standard.
218      */
parseFAModuleApiVersion(String jsonString)219     public static ModuleApiVersion parseFAModuleApiVersion(String jsonString) throws BundleException {
220         JSONObject appObj = getAppObj(jsonString);
221         if (!appObj.containsKey(API_VERSION)) {
222             LOG.error("ModuleJsonUtil::parseFAAPIVersion json file do not contain apiVersion.");
223             throw new BundleException("ModuleJsonUtil::parseFAAPIVersion json file do not contain apiVersion.");
224         }
225         JSONObject apiVersionObj = appObj.getJSONObject(API_VERSION);
226         ModuleApiVersion moduleApiVersion = new ModuleApiVersion();
227         if (apiVersionObj.containsKey(COMPATIBLE)) {
228             moduleApiVersion.setCompatibleApiVersion(apiVersionObj.getIntValue(COMPATIBLE));
229         }
230         if (apiVersionObj.containsKey(RELEASE_TYPE)) {
231             moduleApiVersion.setReleaseType(apiVersionObj.getString(RELEASE_TYPE));
232         }
233         if (apiVersionObj.containsKey(TARGET)) {
234             moduleApiVersion.setTargetApiVersion(apiVersionObj.getIntValue(TARGET));
235         }
236         return moduleApiVersion;
237     }
238 
239     /**
240      * get the module name from json file for stage module.
241      *
242      * @param jsonString uncompress json object
243      * @return the result
244      * @throws BundleException Throws this exception if the json is not standard.
245      */
parseStageModuleName(String jsonString)246     public static String parseStageModuleName(String jsonString) throws BundleException {
247         JSONObject moduleObj = getModuleObj(jsonString);
248         String moduleName;
249         if (moduleObj.containsKey(NAME)) {
250             moduleName = moduleObj.getString(NAME);
251         } else {
252             LOG.error("ModuleJsonUtil:parseStageModuleName failed: json file do not contain module name.");
253             throw new BundleException("ModuleJsonUtil:parseStageModuleName failed: json file do not contain module name.");
254         }
255         return moduleName;
256     }
257 
258     /**
259      * get the moduleName from json file for stage module.
260      *
261      * @param jsonString uncompress json object
262      * @return the result
263      * @throws BundleException Throws this exception if the json is not standard.
264      */
parseFaModuleName(String jsonString)265     public static String parseFaModuleName(String jsonString) throws BundleException {
266         String moduleName;
267         JSONObject moduleObj = getModuleObj(jsonString);
268         JSONObject distroObj = moduleObj.getJSONObject(DISTRO);
269         if (distroObj == null) {
270             LOG.error("ModuleJsonUtil:parseFaModuleName failed: json file do not contain distro.");
271             throw new BundleException("ModuleJsonUtil:parseFaModuleName failed: json file do not contain distro.");
272         }
273         if (!distroObj.containsKey(MODULE_NAME)) {
274             LOG.error("ModuleJsonUtil:parseFaModuleName failed: json file do not contain moduleName.");
275             throw new BundleException(
276                     "ModuleJsonUtil:parseFaModuleName failed: json file do not contain moduleName.");
277         }
278         moduleName = distroObj.getString(MODULE_NAME);
279         return moduleName;
280     }
281 
282     /**
283      * get the moduleName from json file for hqf.
284      *
285      * @param jsonString uncompress json object
286      * @return the result
287      * @throws BundleException Throws this exception if the json is not standard.
288      */
parsePatchModuleName(String jsonString)289     public static String parsePatchModuleName(String jsonString) throws BundleException {
290         String moduleName;
291         JSONObject moduleObj = getModuleObj(jsonString);
292         if (!moduleObj.containsKey(NAME)) {
293             LOG.error("ModuleJsonUtil:parsePatchModuleName failed: json file do not contain moduleName.");
294             throw new BundleException(
295                     "ModuleJsonUtil:parsePatchModuleName failed: json file do not contain moduleName.");
296         }
297         moduleName = moduleObj.getString(NAME);
298         return moduleName;
299     }
300 
301     /**
302      * get the package from json file for stage module.
303      *
304      * @param jsonString uncompress json object
305      * @return the result
306      * @throws BundleException Throws this exception if the json is not standard.
307      */
parseFaPackageStr(String jsonString)308     public static String parseFaPackageStr(String jsonString) throws BundleException {
309         String packageStr = "";
310         JSONObject moduleObj = getModuleObj(jsonString);
311         if (moduleObj.containsKey(PACKAGE)) {
312             packageStr = moduleObj.getString(PACKAGE);
313         } else {
314             LOG.error("ModuleJsonUtil:parseFaPackageStr failed: json file do not contain package.");
315             throw new BundleException("ModuleJsonUtil:parseFaPackageStr failed: json file do not contain package.");
316         }
317         return packageStr;
318     }
319 
320     /**
321      * get the bundleName from json file.
322      *
323      * @param jsonString uncompress json object
324      * @return the result
325      * @throws BundleException Throws this exception if the json is not standard.
326      */
parseBundleName(String jsonString)327     public static String parseBundleName(String jsonString) throws BundleException {
328         JSONObject appObject = getAppObj(jsonString);
329         String bundleName = "";
330         if (appObject.containsKey(BUNDLE_NAME)) {
331             bundleName = appObject.getString(BUNDLE_NAME);
332         } else {
333             LOG.error("ModuleJsonUtil::parseStageBundleName json object do not contain bundleNames.");
334             throw new BundleException("ModuleJsonUtil::parseStageBundleName json object do not contain bundleNames.");
335         }
336         return bundleName;
337     }
338 
339     /**
340      * get the vendor from json file.
341      *
342      * @param jsonString uncompress json object
343      * @return the result
344      * @throws BundleException Throws this exception if the json is not standard.
345      */
parseVendor(String jsonString)346     public static String parseVendor(String jsonString) throws BundleException {
347         JSONObject appObject = getAppObj(jsonString);
348         String vendor = "";
349         if (appObject.containsKey(VENDOR)) {
350             vendor = appObject.getString(VENDOR);
351         }
352         return vendor;
353     }
354 
355     /**
356      * merge two pack.info file into one pack.info file.
357      *
358      * @param finalPackInfo is the final packInfo
359      * @param srcPackInfo is the packInfo to be merged
360      * @return the result
361      * @throws BundleException Throws this exception if the json is not standard.
362      */
mergeTwoPackInfo(String finalPackInfo, String srcPackInfo)363     public static String mergeTwoPackInfo(String finalPackInfo, String srcPackInfo) throws BundleException {
364         String desPackInfo = "";
365         JSONObject finalPackObj;
366         try {
367             finalPackObj = JSON.parseObject(finalPackInfo);
368             JSONObject srcPackObj = JSON.parseObject(srcPackInfo);
369             if (!verifyPackInfo(finalPackObj, srcPackObj)) {
370                 LOG.error("ModuleJsonUtil:mergeTwoPackInfo verify pack.info failed.");
371                 throw new BundleException("ModuleJsonUtil:mergeTwoPackInfo verify pack.info failed.");
372             }
373             desPackInfo = mergePackInfoObj(finalPackObj, srcPackObj);
374         } catch (BundleException | JSONException e) {
375             LOG.error("ModuleJsonUtil:mergeTwoPackInfo merge pack.info failed: " + e.getMessage());
376             throw new BundleException("ModuleJsonUtil:mergeTwoPackInfo merge pack.info failed.");
377         }
378         return desPackInfo;
379     }
380 
381     /**
382      * verify pack.info file.
383      *
384      * @param finalPackObj is the final pack.info object
385      * @param srcPackObj is the src pack.info object
386      * @return the result
387      */
verifyPackInfo(JSONObject finalPackObj, JSONObject srcPackObj)388     public static boolean verifyPackInfo(JSONObject finalPackObj, JSONObject srcPackObj) throws BundleException {
389         if (finalPackObj == null || srcPackObj == null) {
390             LOG.error("ModuleJsonUtil:verifyPackInfo fail to read pack.info.");
391             return false;
392         }
393         JSONObject finalSummaryObj = finalPackObj.getJSONObject(SUMMARY);
394         JSONObject srcSummaryObj = srcPackObj.getJSONObject(SUMMARY);
395         if (finalSummaryObj == null || srcSummaryObj == null) {
396             LOG.error("ModuleJsonUtil:verifyPackInfo pack.info do not contain summary.");
397             return false;
398         }
399         // check app info
400         JSONObject finalAppObj = finalSummaryObj.getJSONObject(APP);
401         JSONObject srcAppObj = srcSummaryObj.getJSONObject(APP);
402         if (finalAppObj == null || srcAppObj == null) {
403             LOG.error("ModuleJsonUtil:verifyPackInfo pack.info do not contain app.");
404             return false;
405         }
406         if (!verifyAppInPackInfo(finalAppObj, srcAppObj)) {
407             LOG.error("ModuleJsonUtil:verifyPackInfo verify app failed.");
408             return false;
409         }
410 
411         return true;
412     }
413 
414     /**
415      * verify app in pack.info file.
416      *
417      * @param finalAppObj is the final pack.info app object
418      * @param srcAppObj is the src pack.info app object
419      * @return the result
420      */
verifyAppInPackInfo(JSONObject finalAppObj, JSONObject srcAppObj)421     public static boolean verifyAppInPackInfo(JSONObject finalAppObj, JSONObject srcAppObj) {
422         if (finalAppObj == null || srcAppObj == null) {
423             LOG.error("ModuleJsonUtil:verifyAppInPackInfo input null json object.");
424             return false;
425         }
426         // check bundleName
427         String finalBundleName = finalAppObj.getString(BUNDLE_NAME);
428         String srcBundleName = srcAppObj.getString(BUNDLE_NAME);
429         if (!finalBundleName.equals(srcBundleName)) {
430             LOG.error("ModuleJsonUtil:verifyAppInPackInfo bundleName is different.");
431             return false;
432         }
433         // check bundleType
434         if (!checkBundleTypeInPackInfo(finalAppObj, srcAppObj)) {
435             LOG.error("ModuleJsonUtil:verifyAppInPackInfo bundleType is different.");
436             return false;
437         }
438         // check version
439         JSONObject finalVersionObj = finalAppObj.getJSONObject(VERSION);
440         JSONObject srcVersionObj = srcAppObj.getJSONObject(VERSION);
441         if (finalVersionObj == null || srcVersionObj == null) {
442             LOG.error("ModuleJsonUtil:verifyAppInPackInfo version object is empty.");
443             return false;
444         }
445         int finalVersionCode = finalVersionObj.getIntValue(CODE);
446         int srcVersionCode = srcVersionObj.getIntValue(CODE);
447         if (finalVersionCode != srcVersionCode) {
448             LOG.error("ModuleJsonUtil:verifyAppInPackInfo versionCode is different.");
449             return false;
450         }
451         return true;
452     }
453 
454     /**
455      * verify bundleType in pack.info file.
456      *
457      * @param finalAppObj is the final pack.info app objects
458      * @param srcAppObj is the src pack.info app objects
459      * @return the result
460      */
checkBundleTypeInPackInfo(JSONObject finalAppObj, JSONObject srcAppObj)461     public static boolean checkBundleTypeInPackInfo(JSONObject finalAppObj, JSONObject srcAppObj) {
462         if (finalAppObj.isEmpty() || srcAppObj.isEmpty()) {
463             LOG.error("ModuleJsonUtil:checkBundleTypeInPackInfo pack.info has empty module.");
464             return false;
465         }
466         String finalBundleType = "app";
467         String srcBundleType = "app";
468         if (finalAppObj.containsKey(BUNDLE_TYPE)) {
469             finalBundleType = getJsonString(finalAppObj, BUNDLE_TYPE);
470         }
471         if (srcAppObj.containsKey(BUNDLE_TYPE)) {
472             srcBundleType = getJsonString(srcAppObj, BUNDLE_TYPE);
473         }
474         if (!finalBundleType.equals(srcBundleType)) {
475             LOG.error("bundleType in pack.info is not same.");
476             return false;
477         }
478         return true;
479     }
480 
481     /**
482      * verify module in pack.info file.
483      *
484      * @param finalModuleObs is the final pack.info module objects
485      * @param srcModuleObs is the src pack.info module objects
486      * @return the result
487      */
verifyModuleInPackInfo(JSONArray finalModuleObs, JSONArray srcModuleObs)488     public static boolean verifyModuleInPackInfo(JSONArray finalModuleObs, JSONArray srcModuleObs)
489             throws BundleException {
490         if (finalModuleObs.isEmpty() || srcModuleObs.isEmpty()) {
491             LOG.error("ModuleJsonUtil:verifyModuleInPackInfo pack.info has empty module.");
492             throw new BundleException("ModuleJsonUtil:verifyModuleInPackInfo pack.info has empty module.");
493         }
494         List<String> moduleNames = new ArrayList<>();
495         for (int i = 0; i < finalModuleObs.size(); ++i) {
496             JSONObject finalModuleObj = finalModuleObs.getJSONObject(i);
497             String moduleName = parseDistroModuleName(finalModuleObj);
498             if (moduleNames.contains(moduleName)) {
499                 LOG.error("ModuleJsonUtil:verifyModuleInPackInfo duplicated moduleName.");
500                 return false;
501             } else {
502                 moduleNames.add(moduleName);
503             }
504         }
505         for (int i = 0; i < srcModuleObs.size(); ++i) {
506             JSONObject srcModuleObj = srcModuleObs.getJSONObject(i);
507             String moduleName = parseDistroModuleName(srcModuleObj);
508             if (moduleNames.contains(moduleName)) {
509                 LOG.error("ModuleJsonUtil:verifyModuleInPackInfo duplicated moduleName.");
510                 return false;
511             } else {
512                 moduleNames.add(moduleName);
513             }
514         }
515         return true;
516     }
517 
518 
519 
520     /**
521      * parse forms name in pack.info file.
522      *
523      * @param jsonString the pack.info json string
524      * @param formNameList the forms name in pack.info
525      * @param fullFormNameList the forms name and moduleName merged result in pack.info
526      */
parsePackInfoFormsName(String jsonString, List<String> formNameList, List<String> fullFormNameList)527     public static void parsePackInfoFormsName(String jsonString, List<String> formNameList, List<String> fullFormNameList)
528             throws BundleException {
529         JSONObject jsonObject = JSONObject.parseObject(jsonString);
530         if (jsonObject == null || !jsonObject.containsKey(SUMMARY)) {
531             LOG.error("ModuleJsonUtil::parsePackInfoFormsName error: summary is null.");
532             throw new BundleException("Parse pack info forms name failed, summary is null.");
533         }
534 
535         JSONObject summaryJson = jsonObject.getJSONObject(SUMMARY);
536         if (summaryJson == null || !summaryJson.containsKey("modules")) {
537             LOG.error("ModuleJsonUtil::parsePackInfoFormsName error: summary.modules is null.");
538             return;
539         }
540 
541         JSONArray moduleJsonList = summaryJson.getJSONArray("modules");
542         for (int i = 0; i < moduleJsonList.size(); i++) {
543             JSONObject moduleJson = moduleJsonList.getJSONObject(i);
544             if (moduleJson == null || !moduleJson.containsKey(DISTRO)) {
545                 LOG.error("ModuleJsonUtil::parsePackInfoFormsName error: summary.modules.distro is null.");
546                 continue;
547             }
548 
549             JSONObject distroObj = moduleJson.getJSONObject(DISTRO);
550             if (distroObj == null || !distroObj.containsKey(MODULE_NAME)) {
551                 LOG.error("ModuleJsonUtil::parsePackInfoFormsName error: summary.modules.distro.moduleName is null.");
552                 continue;
553             }
554 
555             String moduleName = distroObj.getString(MODULE_NAME);
556             parsePackInfoExtensionAbility(moduleName, moduleJson, formNameList, fullFormNameList);
557         }
558     }
559 
560     /**
561      * verify package name in pack.info file.
562      *
563      * @param finalPackageObs is the final pack.info objects
564      * @param srcPackageObs is the src pack.info objects
565      * @return the result
566      */
verifyPackageName(JSONArray finalPackageObs, JSONArray srcPackageObs)567     public static boolean verifyPackageName(JSONArray finalPackageObs, JSONArray srcPackageObs) {
568         if (finalPackageObs == null || finalPackageObs.isEmpty() || srcPackageObs == null || srcPackageObs.isEmpty()) {
569             LOG.error("ModuleJsonUtil:verifyPackageName pack.info has empty packages.");
570             return false;
571         }
572         List<String> packageNames = new ArrayList<>();
573         for (int i = 0; i < finalPackageObs.size(); ++i) {
574             JSONObject packageObj = finalPackageObs.getJSONObject(i);
575             String packageName = packageObj.getString(NAME);
576             if (packageNames.contains(packageName)) {
577                 LOG.error("ModuleJsonUtil:verifyPackageName duplicated package name.");
578                 return false;
579             } else {
580                 packageNames.add(packageName);
581             }
582         }
583         for (int i = 0; i < srcPackageObs.size(); ++i) {
584             JSONObject packageObj = srcPackageObs.getJSONObject(i);
585             String packageName = packageObj.getString(NAME);
586             if (packageNames.contains(packageName)) {
587                 LOG.error("ModuleJsonUtil:verifyPackageName duplicated package name.");
588                 return false;
589             } else {
590                 packageNames.add(packageName);
591             }
592         }
593         return true;
594     }
595 
596     /**
597      * parse moduleName in pack.info file.
598      *
599      * @param moduleObj is the final pack.info objects
600      * @return the result
601      */
parseDistroModuleName(JSONObject moduleObj)602     public static String parseDistroModuleName(JSONObject moduleObj) throws BundleException {
603         String moduleName = "";
604         try {
605             if (moduleObj == null) {
606                 LOG.error("ModuleJsonUtil:parseFaModuleName failed: json file do not contain module.");
607                 throw new BundleException("ModuleJsonUtil:parseFaModuleName failed: json file do not contain module.");
608             }
609             JSONObject distroObj = moduleObj.getJSONObject(DISTRO);
610             if (distroObj == null) {
611                 LOG.error("ModuleJsonUtil:parseFaModuleName failed: json file do not contain distro.");
612                 throw new BundleException("ModuleJsonUtil:parseFaModuleName failed: json file do not contain distro.");
613             }
614             if (!distroObj.containsKey(MODULE_NAME)) {
615                 LOG.error("ModuleJsonUtil:parseFaModuleName failed: json file do not contain moduleName.");
616                 throw new BundleException("ModuleJsonUtil:parseFaModuleName failed:" +
617                         "json file do not contain moduleName.");
618             }
619             moduleName = distroObj.getString(MODULE_NAME);
620         } catch (BundleException e) {
621             LOG.error("ModuleJsonUtil:parseFaModuleName failed.");
622             throw new BundleException("ModuleJsonUtil:parseFaModuleName failed.");
623         }
624         return moduleName;
625     }
626 
627     /**
628      * merge pack.info file.
629      *
630      * @param finalPackinfoObj is the final pack.info objects
631      * @param srcPackinfoObj is the final pack.info objects
632      * @return the result
633      */
mergePackInfoObj(JSONObject finalPackinfoObj, JSONObject srcPackinfoObj)634     public static String mergePackInfoObj(JSONObject finalPackinfoObj, JSONObject srcPackinfoObj) throws BundleException {
635         if (finalPackinfoObj == null || srcPackinfoObj == null) {
636             String errMsg = "ModuleJsonUtil:mergePackInfoObj input an invalid json object.";
637             LOG.error(errMsg);
638             throw new BundleException(errMsg);
639         }
640         JSONObject finalSummaryObj = finalPackinfoObj.getJSONObject(SUMMARY);
641         JSONObject srcSummaryObj = srcPackinfoObj.getJSONObject(SUMMARY);
642         if (finalSummaryObj == null || srcSummaryObj == null) {
643             String errMsg = "ModuleJsonUtil:mergePackInfoObj input json file has empty summary.";
644             LOG.error(errMsg);
645             throw new BundleException(errMsg);
646         }
647         // merge modules
648         JSONArray finalModuleObs = finalSummaryObj.getJSONArray(MODULES);
649         JSONArray srcModuleObs = srcSummaryObj.getJSONArray(MODULES);
650         if (finalModuleObs == null || srcModuleObs == null) {
651             String errMsg = "ModuleJsonUtil:mergePackInfoObj input json file has empty module.";
652             LOG.error(errMsg);
653             throw new BundleException(errMsg);
654         }
655         finalModuleObs.addAll(srcModuleObs);
656         // merge packages
657         JSONArray finalPackageObs = finalPackinfoObj.getJSONArray(PACKAGES);
658         JSONArray srcPackageObs = srcPackinfoObj.getJSONArray(PACKAGES);
659         if (finalPackageObs == null || srcPackageObs == null) {
660             String errMsg = "ModuleJsonUtil:mergePackInfoObj input json file has empty packages.";
661             LOG.error(errMsg);
662             throw new BundleException(errMsg);
663         }
664         finalPackageObs.addAll(srcPackageObs);
665         return finalPackinfoObj.toString();
666     }
667 
668     /**
669      * merge two pack.info file into one pack.info file by packagePair.
670      *
671      * @param finalPackInfo is the final packInfo
672      * @param srcPackInfo is the packInfo to be merged
673      * @param packagePair is the selected packageName-moduleName pair map
674      * @return the result
675      * @throws BundleException Throws this exception if the json is not standard.
676      */
mergeTwoPackInfoByPackagePair(String finalPackInfo, String srcPackInfo, HashMap<String, String> packagePair)677     public static String mergeTwoPackInfoByPackagePair(String finalPackInfo, String srcPackInfo,
678                                                        HashMap<String, String> packagePair) throws BundleException {
679         JSONObject finalPackObj;
680         JSONObject srcPackObj;
681         try {
682             finalPackObj = JSON.parseObject(finalPackInfo);
683             srcPackObj = JSON.parseObject(srcPackInfo);
684         } catch (JSONException exception) {
685             String errMsg = "parse JSONObject failed: " + exception.getMessage();
686             LOG.error(errMsg);
687             throw new BundleException(errMsg);
688         }
689         // verify app in pack.info
690         JSONObject finalSummaryObj = finalPackObj.getJSONObject(SUMMARY);
691         JSONObject finalAppObj = finalSummaryObj.getJSONObject(APP);
692         JSONObject srcSummaryObj = srcPackObj.getJSONObject(SUMMARY);
693         JSONObject srcAppObj = srcSummaryObj.getJSONObject(APP);
694         if (!verifyAppInPackInfo(finalAppObj, srcAppObj)) {
695             String errMsg = "verify pack.info failed, different version, bundleType or bundleName.";
696             LOG.error(errMsg);
697             throw new BundleException(errMsg);
698         }
699         for (HashMap.Entry<String, String> entry : packagePair.entrySet()) {
700             String packageName = entry.getKey().substring(0, entry.getKey().lastIndexOf(DOT));
701             mergeTwoPackInfoObjByPackagePair(finalPackObj, srcPackObj, packageName, entry.getValue());
702         }
703         return finalPackObj.toString();
704     }
705 
706     /**
707      * merge two pack.info file into one pack.info file by packagePair.
708      *
709      * @param finalPackObj is the final packInfo
710      * @param srcPackObj is the packInfo to be merged
711      * @param packageName is the selected packageName
712      * @param moduleName is the selected moduleName
713      * @throws BundleException Throws this exception if the json is not standard.
714      */
mergeTwoPackInfoObjByPackagePair(JSONObject finalPackObj, JSONObject srcPackObj, String packageName, String moduleName)715     public static void mergeTwoPackInfoObjByPackagePair(JSONObject finalPackObj, JSONObject srcPackObj,
716                                                         String packageName, String moduleName) throws BundleException {
717         if (finalPackObj == null || srcPackObj == null) {
718             String errMsg = "ModuleJsonUtil:mergeTwoPackInfoObjByPackagePair failed: pack.info is not json object.";
719             LOG.error(errMsg);
720             throw new BundleException(errMsg);
721         }
722         // merge module
723         JSONObject finalSummaryObj = finalPackObj.getJSONObject(SUMMARY);
724         JSONObject srcSummaryObj = srcPackObj.getJSONObject(SUMMARY);
725         if (finalSummaryObj == null || srcSummaryObj == null) {
726             String errMsg = "ModuleJsonUtil:mergeTwoPackInfoObjByPackagePair failed: pack.info do not contain summary.";
727             LOG.error(errMsg);
728             throw new BundleException(errMsg);
729         }
730         JSONArray finalModules = finalSummaryObj.getJSONArray(MODULES);
731         JSONArray srcModules = srcSummaryObj.getJSONArray(MODULES);
732         if (finalModules == null || srcModules == null) {
733             LOG.error("ModuleJsonUtil:mergeTwoPackInfoObjByPackagePair input json file has empty module.");
734             throw new
735                 BundleException("ModuleJsonUtil:mergeTwoPackInfoObjByPackagePair input json file has empty module.");
736         }
737         boolean findModule = false;
738         for (int index = 0; index < srcModules.size(); ++index) {
739             JSONObject moduleObj = srcModules.getJSONObject(index);
740             JSONObject distroObj = moduleObj.getJSONObject(DISTRO);
741             if (distroObj.getString(MODULE_NAME).equals(moduleName)) {
742                 finalModules.add(moduleObj);
743                 findModule = true;
744                 break;
745             }
746         }
747         if (!findModule) {
748             String errMsg = "ModuleJsonUtil:mergeTwoPackInfoObjByPackagePair" +
749                     " input json do not contain " + moduleName + ".";
750             LOG.error(errMsg);
751             throw new BundleException(errMsg);
752         }
753         // merge package
754         JSONArray finalPackages = finalPackObj.getJSONArray(PACKAGES);
755         JSONArray srcPackages = srcPackObj.getJSONArray(PACKAGES);
756         if (finalPackages == null || srcPackages == null) {
757             String errMsg =
758                     "ModuleJsonUtil:mergeTwoPackInfoObjByPackagePair failed: pack.info do not contain packages.";
759             LOG.error(errMsg);
760             throw new BundleException(errMsg);
761         }
762         boolean findPackage = false;
763         for (int index = 0; index < srcPackages.size(); ++index) {
764             JSONObject srcPackageObj = srcPackages.getJSONObject(index);
765             if (srcPackageObj.getString(NAME).equals(packageName)) {
766                 finalPackages.add(srcPackageObj);
767                 findPackage = true;
768                 break;
769             }
770         }
771         if (!findPackage) {
772             String errMsg = "ModuleJsonUtil:mergeTwoPackInfoObjByPackagePair input json do not contain "
773                     + packageName + ".";
774             LOG.error(errMsg);
775             throw new BundleException(errMsg);
776         }
777     }
778 
779     /**
780      * parse FA hap is entry hap, if it is, return device type.
781      *
782      * @param hapPath is the path of hap.
783      *
784      * @throws BundleException FileNotFoundException|IOException.
785      */
parseFaEntry(String hapPath)786     public static List<String> parseFaEntry(String hapPath) throws BundleException {
787         String configJson = FileUtils.getJsonInZips(new File(hapPath), CONFIG_JSON);
788         JSONObject faObj;
789         try {
790             faObj = JSONObject.parseObject(configJson);
791         } catch (JSONException exception) {
792             String errMsg = "parse JSONobject failed.";
793             LOG.error(errMsg);
794             throw new BundleException(errMsg);
795         }
796         JSONObject moduleObj = faObj.getJSONObject(MODULE);
797         if (moduleObj == null) {
798             String errMSg = "ModuleJsonUtil::isFaEntry error, json do not contain module.";
799             LOG.error(errMSg);
800             throw new BundleException(errMSg);
801         }
802         List<String> deviceTypes = new ArrayList<>();
803         JSONObject distroObj = moduleObj.getJSONObject(DISTRO);
804         if (distroObj == null) {
805             String errMSg = "ModuleJsonUtil::isFaEntry error, json do not contain distro.";
806             LOG.error(errMSg);
807             throw new BundleException(errMSg);
808         }
809         String moduleType = distroObj.getString(MODULE_TYPE);
810         if (ENTRY.equals(moduleType)) {
811             deviceTypes = getDeviceTypeFromFAModule(moduleObj);
812         }
813         return deviceTypes;
814     }
815 
816     /**
817      * parse stage hap is entry hap, if it is, record device type.
818      *
819      * @param hapPath is the path of hap.
820      * @throws BundleException FileNotFoundException|IOException.
821      */
parseStageEntry(String hapPath)822     public static List<String> parseStageEntry(String hapPath) throws BundleException {
823         String moduleJson = FileUtils.getJsonInZips(new File(hapPath), MODULE_JSON);
824         JSONObject stageObj;
825         try {
826             stageObj = JSONObject.parseObject(moduleJson);
827         } catch (JSONException exception) {
828             String errMsg = "parse JSONobject failed.";
829             LOG.error(errMsg);
830             throw new BundleException(errMsg);
831         }
832         JSONObject moduleObj = stageObj.getJSONObject(MODULE);
833         if (moduleObj == null) {
834             String errMSg = "ModuleJsonUtil::isFaEntry error, json do not contain module.";
835             LOG.error(errMSg);
836             throw new BundleException(errMSg);
837         }
838         List<String> deviceTypes = new ArrayList<>();
839         String type = moduleObj.getString(TYPE);
840         if (type != null && type.equals(ENTRY)) {
841             deviceTypes = getDeviceTypesFromStageModule(moduleObj);
842         }
843 
844         return deviceTypes;
845     }
846 
847     /**
848      * get deviceType from fa module.
849      *
850      * @param moduleObj is the object of module.
851      * @return true is for entry hap  and false is other kind of hap
852      */
getDeviceTypeFromFAModule(JSONObject moduleObj)853     public static List<String> getDeviceTypeFromFAModule(JSONObject moduleObj) {
854         List<String> deviceTypes = new ArrayList<>();
855         if (moduleObj == null) {
856             return deviceTypes;
857         }
858         deviceTypes = JSONObject.parseArray(getJsonString(moduleObj, DEVICE_TYPE), String.class);
859         return deviceTypes;
860     }
861 
862     /**
863      * get deviceType from stage module.
864      *
865      * @param moduleObj is the object of module.
866      * @return true is for entry hap  and false is other kind of hap
867      */
getDeviceTypesFromStageModule(JSONObject moduleObj)868     public static List<String> getDeviceTypesFromStageModule(JSONObject moduleObj) {
869         List<String> deviceTypes = new ArrayList<>();
870         if (moduleObj == null) {
871             return deviceTypes;
872         }
873         deviceTypes = JSONObject.parseArray(getJsonString(moduleObj, DEVICE_TYPES), String.class);
874         return deviceTypes;
875     }
876 
877     /**
878      * parse stage hapVerifyInfo.
879      *
880      * @param hapVerifyInfo is the parse result
881      * @throws BundleException Throws this exception if the json is not standard.
882      */
parseStageHapVerifyInfo(HapVerifyInfo hapVerifyInfo)883     public static void parseStageHapVerifyInfo(HapVerifyInfo hapVerifyInfo) throws BundleException {
884         if (hapVerifyInfo.getProfileStr().isEmpty()) {
885             throw new BundleException("ModuleJsonUtil::parseStageHapVerifyInfo failed, module.json is empty.");
886         }
887         String bundleName = parseBundleName(hapVerifyInfo.getProfileStr());
888         hapVerifyInfo.setBundleName(bundleName);
889         hapVerifyInfo.setVendor(parseVendor(hapVerifyInfo.getProfileStr()));
890         hapVerifyInfo.setVersion(parseStageVersion(hapVerifyInfo.getProfileStr()));
891         hapVerifyInfo.setApiVersion(parseStageModuleApiVersion(hapVerifyInfo.getProfileStr()));
892         hapVerifyInfo.setModuleName(parseStageModuleName(hapVerifyInfo.getProfileStr()));
893         List<ModuleMetadataInfo> moduleMetadataInfos =
894                 parseModuleAllMetadata(hapVerifyInfo.getProfileStr(), hapVerifyInfo.getResourceMap());
895         hapVerifyInfo.setDistroFilter(parseStageDistroFilter(moduleMetadataInfos));
896         hapVerifyInfo.setDeviceType(parseDeviceType(hapVerifyInfo.getProfileStr()));
897         hapVerifyInfo.setAbilityNames(parseAbilityNames(hapVerifyInfo.getProfileStr()));
898         List<String> extensionAbilityNames = parseExtensionAbilityName(hapVerifyInfo.getProfileStr());
899         hapVerifyInfo.addAbilityNames(extensionAbilityNames);
900         hapVerifyInfo.setModuleType(parseModuleType(hapVerifyInfo.getProfileStr()));
901         hapVerifyInfo.setDependencyItemList(parseDependencies(hapVerifyInfo.getProfileStr(), bundleName));
902         hapVerifyInfo.setInstallationFree(parseStageInstallation(hapVerifyInfo.getProfileStr()));
903         hapVerifyInfo.setBundleType(parseStageBundleType(hapVerifyInfo.getProfileStr()));
904         hapVerifyInfo.setPreloadItems(parseAtomicServicePreloads(hapVerifyInfo.getProfileStr()));
905         hapVerifyInfo.setTargetBundleName(parseTargetBundleName(hapVerifyInfo.getProfileStr()));
906         hapVerifyInfo.setTargetPriority(parseTargetPriority(hapVerifyInfo.getProfileStr()));
907         hapVerifyInfo.setTargetModuleName(parseTargetModuleName(hapVerifyInfo.getProfileStr()));
908         hapVerifyInfo.setTargetModulePriority(parseTargetModulePriority(hapVerifyInfo.getProfileStr()));
909         hapVerifyInfo.setDebug(getDebug(hapVerifyInfo.getProfileStr()));
910         hapVerifyInfo.setCompileSdkType(getCompileSdkType(hapVerifyInfo.getProfileStr()));
911         hapVerifyInfo.setCompileSdkVersion(getCompileSdkVersion(hapVerifyInfo.getProfileStr()));
912         hapVerifyInfo.setProxyDataUris(parseProxyDataUri(hapVerifyInfo.getProfileStr()));
913         hapVerifyInfo.setContinueTypeMap(parseAbilityContinueTypeMap(hapVerifyInfo.getProfileStr()));
914         hapVerifyInfo.setMultiAppMode(parseMultiAppMode(hapVerifyInfo.getProfileStr()));
915     }
916 
917     /**
918      * parse FA hapVerifyInfo.
919      *
920      * @param hapVerifyInfo is the parse result
921      * @throws BundleException Throws this exception if the json is not standard.
922      */
parseFAHapVerifyInfo(HapVerifyInfo hapVerifyInfo)923     public static void parseFAHapVerifyInfo(HapVerifyInfo hapVerifyInfo) throws BundleException {
924         if (hapVerifyInfo.getProfileStr().isEmpty()) {
925             LOG.error("ModuleJsonUtil::parseFAHapVerifyInfo failed, config.json is empty.");
926             throw new BundleException("ModuleJsonUtil::parseFAHapVerifyInfo failed, config.json is empty.");
927         }
928         String bundleName = parseBundleName(hapVerifyInfo.getProfileStr());
929         hapVerifyInfo.setBundleName(bundleName);
930         hapVerifyInfo.setBundleType(parseFaBundleType(hapVerifyInfo.getProfileStr()));
931         hapVerifyInfo.setVendor(parseVendor(hapVerifyInfo.getProfileStr()));
932         hapVerifyInfo.setVersion(parseFaVersion(hapVerifyInfo.getProfileStr()));
933         hapVerifyInfo.setApiVersion(parseFAModuleApiVersion(hapVerifyInfo.getProfileStr()));
934         hapVerifyInfo.setModuleName(parseFaModuleName(hapVerifyInfo.getProfileStr()));
935         hapVerifyInfo.setDistroFilter(parseFADistroFilter(hapVerifyInfo.getProfileStr()));
936         hapVerifyInfo.setDeviceType(parseDeviceType(hapVerifyInfo.getProfileStr()));
937         hapVerifyInfo.setAbilityNames(parseAbilityNames(hapVerifyInfo.getProfileStr()));
938         hapVerifyInfo.setModuleType(parseFAIsEntry(hapVerifyInfo.getProfileStr()));
939         hapVerifyInfo.setPackageName(parseFaPackageStr(hapVerifyInfo.getProfileStr()));
940         hapVerifyInfo.setDependencyItemList(parseDependencies(hapVerifyInfo.getProfileStr(), bundleName));
941         hapVerifyInfo.setInstallationFree(parseFAInstallationFree(hapVerifyInfo.getProfileStr()));
942         hapVerifyInfo.setDebug(getFADebug(hapVerifyInfo.getProfileStr()));
943         hapVerifyInfo.setCompileSdkType(getFACompileSdkType(hapVerifyInfo.getProfileStr()));
944         hapVerifyInfo.setCompileSdkVersion(getFACompileSdkVersion(hapVerifyInfo.getProfileStr()));
945     }
946 
parseMultiAppMode(String jsonString)947     private static MultiAppMode parseMultiAppMode(String jsonString) throws BundleException {
948         MultiAppMode multiAppMode = new MultiAppMode();
949         JSONObject appObj = getAppObj(jsonString);
950         JSONObject modeObj = appObj.getJSONObject(MULTI_APP_MODE);
951         if (modeObj != null) {
952             String type = modeObj.getString(MULTI_APP_MODE_TYPE);
953             Integer number = modeObj.getInteger(MULTI_APP_MODE_NUMBER);
954             multiAppMode.setMultiAppModeType(type != null ? type : "");
955             multiAppMode.setMaxCount(number != null ? number : 0);
956         }
957         return multiAppMode;
958     }
959 
960     /**
961      * parse stage distroFilter.
962      *
963      * @param moduleMetadataInfos all metadata of module
964      * @return DistroFilter is the result of parsed distroFilter
965      */
parseStageDistroFilter(List<ModuleMetadataInfo> moduleMetadataInfos)966     public static DistroFilter parseStageDistroFilter(List<ModuleMetadataInfo> moduleMetadataInfos) {
967         for (ModuleMetadataInfo moduleMetadataInfo : moduleMetadataInfos) {
968             String resource = moduleMetadataInfo.resource;
969             if (resource.isEmpty()) {
970                 continue;
971             }
972             JSONObject distroFilter = JSONObject.parseObject(resource);
973             if (distroFilter.containsKey(DISTRIBUTION_FILTER)) {
974                 return JSONObject.parseObject(getJsonString(distroFilter, DISTRIBUTION_FILTER), DistroFilter.class);
975             }
976             if (distroFilter.containsKey(DISTRO_FILTER)) {
977                 return JSONObject.parseObject(getJsonString(distroFilter, DISTRO_FILTER), DistroFilter.class);
978             }
979         }
980         return new DistroFilter();
981     }
982 
983     /**
984      * parse stage parseModuleAllMetadata.
985      *
986      * @param jsonString is the string of module.json
987      * @param profileJson is the <fileName,fileString> of profile
988      * @return DistroFilter is the result of parsed distroFilter
989      */
parseModuleAllMetadata( String jsonString, HashMap<String, String> profileJson)990     public static List<ModuleMetadataInfo> parseModuleAllMetadata(
991             String jsonString, HashMap<String, String> profileJson) throws BundleException {
992         JSONObject moduleObj = getModuleObj(jsonString);
993         List<ModuleMetadataInfo> moduleMetadataInfos = new ArrayList<>();
994         if (moduleObj.containsKey(METADATA)) {
995             JSONArray metadatas = moduleObj.getJSONArray(METADATA);
996             for (int i = 0; i < metadatas.size(); ++i) {
997                 JSONObject metadata = metadatas.getJSONObject(i);
998                 moduleMetadataInfos.add(parseModuleMetadata(metadata, profileJson));
999             }
1000         }
1001         return moduleMetadataInfos;
1002     }
1003 
1004     /**
1005      * parse metadata info
1006      *
1007      * @param jsonObject Json hap json Object
1008      * @param profileJson is the <fileName,fileString> of profile
1009      * @return the ModuleMetadataInfo result
1010      * @throws BundleException Throws this exception if the json is not standard.
1011      */
parseModuleMetadata(JSONObject jsonObject, HashMap<String, String> profileJson)1012     public static ModuleMetadataInfo parseModuleMetadata(JSONObject jsonObject, HashMap<String, String> profileJson)
1013             throws BundleException {
1014         if (jsonObject == null) {
1015             throw new BundleException("ModuleJsonUtil::parseModuleMetadata failed, jsonObject is null.");
1016         }
1017         ModuleMetadataInfo moduleMetadataInfo = new ModuleMetadataInfo();
1018         if (jsonObject.containsKey(NAME)) {
1019             moduleMetadataInfo.name = getJsonString(jsonObject, NAME);
1020         }
1021         if (jsonObject.containsKey(VALUE)) {
1022             moduleMetadataInfo.value = getJsonString(jsonObject, VALUE);
1023         }
1024         if (jsonObject.containsKey(RESOURCE)) {
1025             moduleMetadataInfo.resource = getJsonString(jsonObject, RESOURCE);
1026             String fileName = moduleMetadataInfo.resource;
1027             fileName = fileName.replace(PROFILE, "");
1028             fileName = fileName + JSON_PERFIX;
1029             moduleMetadataInfo.resource = profileJson.get(fileName);
1030         }
1031         return moduleMetadataInfo;
1032     }
1033 
1034     /**
1035      * parse metadata info
1036      *
1037      * @param jsonString Json string of config.json
1038      * @return the ModuleMetadataInfo result
1039      */
parseFADistroFilter(String jsonString)1040     public static DistroFilter parseFADistroFilter(String jsonString) throws BundleException {
1041         DistroFilter distroFilter = new DistroFilter();
1042         JSONObject jsonObj;
1043         try {
1044             jsonObj = JSON.parseObject(jsonString);
1045             if (jsonObj.containsKey(MODULE)) {
1046                 JSONObject moduleObj = jsonObj.getJSONObject(MODULE);
1047                 if (moduleObj.containsKey(DISTRO_FILTER)) {
1048                     distroFilter = JSONObject.parseObject(getJsonString(moduleObj,
1049                             DISTRO_FILTER), DistroFilter.class);
1050                 }
1051             }
1052         } catch (JSONException exception) {
1053             String errMsg = "parse JSONObject failed: " + exception.getMessage();
1054             LOG.error(errMsg);
1055             throw new BundleException(errMsg);
1056         }
1057         return distroFilter;
1058     }
1059 
1060     /**
1061      * get deviceType from json file.
1062      *
1063      * @param jsonString is the json String of module.json or config.json
1064      */
parseDeviceType(String jsonString)1065     public static List<String> parseDeviceType(String jsonString) throws BundleException {
1066         List<String> deviceType = new ArrayList<>();
1067         JSONObject moduleObj = getModuleObj(jsonString);
1068         if (moduleObj.containsKey(DEVICE_TYPE)) {
1069             return JSONObject.parseArray(getJsonString(moduleObj, DEVICE_TYPE), String.class);
1070         } else if (moduleObj.containsKey(DEVICE_TYPES)) {
1071             return JSONObject.parseArray(getJsonString(moduleObj, DEVICE_TYPES), String.class);
1072         } else {
1073             return deviceType;
1074         }
1075     }
1076 
1077     /**
1078      * get ability names from json file.
1079      *
1080      * @param jsonString is the json String of module.json or config.json
1081      * @return ability names
1082      */
parseAbilityNames(String jsonString)1083     public static List<String> parseAbilityNames(String jsonString) throws BundleException {
1084         List<String> abilityNames = new ArrayList<>();
1085         JSONObject moduleObj = getModuleObj(jsonString);
1086         if (moduleObj.containsKey(ABILITIES)) {
1087             JSONArray abilityObjs = moduleObj.getJSONArray(ABILITIES);
1088             for (int i = 0; i < abilityObjs.size(); ++i) {
1089                 JSONObject abilityObj = abilityObjs.getJSONObject(i);
1090                 if (abilityObj.containsKey(NAME)) {
1091                     abilityNames.add(getJsonString(abilityObj, NAME));
1092                 }
1093             }
1094         }
1095 
1096         return abilityNames;
1097     }
1098 
1099     /**
1100      * get ability continueType map from json file.
1101      *
1102      * @param jsonString is the json String of module.json
1103      * @return continueType map
1104      */
parseAbilityContinueTypeMap(String jsonString)1105     public static Map<String, List<String>> parseAbilityContinueTypeMap(String jsonString)
1106             throws BundleException {
1107         Map<String, List<String>> continueTypeMap = new HashMap<>();
1108         JSONObject moduleObj = getModuleObj(jsonString);
1109         if (moduleObj.containsKey(ABILITIES)) {
1110             JSONArray abilityObjs = moduleObj.getJSONArray(ABILITIES);
1111             for (int i = 0; i < abilityObjs.size(); ++i) {
1112                 JSONObject abilityObj = abilityObjs.getJSONObject(i);
1113                 String abilityName = getJsonString(abilityObj, NAME);
1114                 if (abilityObj.containsKey(CONTINUE_TYPE)) {
1115                     JSONArray typeArray = abilityObj.getJSONArray(CONTINUE_TYPE);
1116                     continueTypeMap.put(abilityName, typeArray.toJavaList(String.class));
1117                 } else {
1118                     continueTypeMap.put(abilityName, new ArrayList<>());
1119                 }
1120             }
1121         }
1122         return continueTypeMap;
1123     }
1124 
1125     /**
1126      * parse stage ExtensionAbility names
1127      *
1128      * @param jsonString is the json String of module.json
1129      * @return extensionAbilityNames
1130      */
parseExtensionAbilityName(String jsonString)1131     public static List<String> parseExtensionAbilityName(String jsonString) throws BundleException {
1132         JSONObject moduleObj = getModuleObj(jsonString);
1133         List<String> extensionAbilityNames = new ArrayList<>();
1134         if (moduleObj.containsKey(EXTENSION_ABILITIES)) {
1135             JSONArray extensionAbilityObjs = moduleObj.getJSONArray(EXTENSION_ABILITIES);
1136             for (int i = 0; i < extensionAbilityObjs.size(); ++i) {
1137                 JSONObject extensionAbilityObj = extensionAbilityObjs.getJSONObject(i);
1138                 if (extensionAbilityObj.containsKey(NAME)) {
1139                     extensionAbilityNames.add(getJsonString(extensionAbilityObj, NAME));
1140                 }
1141             }
1142         }
1143         return extensionAbilityNames;
1144     }
1145 
1146     /**
1147      * get ability skills map from json file.
1148      *
1149      * @param jsonString is the json String of module.json
1150      * @return skillsMap key is ability,value indicates whether this door is a home ability
1151      */
parseAbilitySkillsMap(String jsonString)1152     public static Map<String, Boolean> parseAbilitySkillsMap(String jsonString)
1153             throws BundleException {
1154         Map<String, Boolean> skillsMap = new HashMap<>();
1155         JSONObject moduleObj = getModuleObj(jsonString);
1156         JSONArray abilityObs = moduleObj.getJSONArray(ABILITIES);
1157         if(abilityObs == null) {
1158             return skillsMap;
1159         }
1160         for (int i = 0; i < abilityObs.size(); ++i) {
1161             JSONObject abilityObj = abilityObs.getJSONObject(i);
1162             String abilityName = getJsonString(abilityObj, NAME);
1163             skillsMap.put(abilityName, false);
1164             if(!abilityObj.containsKey(SKILLS)) {
1165                 break;
1166             }
1167             JSONArray skillArray = abilityObj.getJSONArray(SKILLS);
1168             for (int j = 0; j < skillArray.size(); ++j) {
1169                 JSONObject skillObj = skillArray.getJSONObject(j);
1170                 String entities = getJsonString(skillObj, SKILLS_ENTITIES);
1171                 String actions = getJsonString(skillObj, SKILLS_ACTIONS);
1172                 if (entities.contains(ENTITY_SYSTEM_HOME) && actions.contains(ACTION_SYSTEM_HOME)) {
1173                     skillsMap.put(abilityName, true);
1174                     break;
1175                 }
1176             }
1177         }
1178         return skillsMap;
1179     }
1180 
1181     /**
1182      * parse stage module type.
1183      *
1184      * @param jsonString is the json String of module.json or config.json
1185      * @return is entry
1186      */
parseModuleType(String jsonString)1187     public static String parseModuleType(String jsonString) throws BundleException {
1188         JSONObject moduleObj = getModuleObj(jsonString);
1189         if (moduleObj.containsKey(TYPE)) {
1190             return getJsonString(moduleObj, TYPE);
1191         }
1192         return EMPTY_STRING;
1193     }
1194 
1195     /**
1196      * parse FA module type.
1197      *
1198      * @param jsonString is the json String of module.json or config.json
1199      * @return is entry
1200      */
parseFAIsEntry(String jsonString)1201     public static String parseFAIsEntry(String jsonString) throws BundleException {
1202         JSONObject moduleObj = getModuleObj(jsonString);
1203         if (moduleObj.containsKey(DISTRO)) {
1204             JSONObject distroObj = moduleObj.getJSONObject(DISTRO);
1205             if (distroObj.containsKey(MODULE_TYPE)) {
1206                 return getJsonString(distroObj, MODULE_TYPE);
1207             }
1208         }
1209         return EMPTY_STRING;
1210     }
1211 
parseDependencies(String jsonString, String bundleName)1212     static List<DependencyItem> parseDependencies(String jsonString, String bundleName) throws BundleException {
1213         JSONObject moduleObj = getModuleObj(jsonString);
1214 
1215         List<DependencyItem> dependencyItemList = new ArrayList<>();
1216         if (!moduleObj.containsKey(DEPENDENCIES)) {
1217             return dependencyItemList;
1218         }
1219         JSONArray dependencyObjList = moduleObj.getJSONArray(DEPENDENCIES);
1220         for (int i = 0; i < dependencyObjList.size(); ++i) {
1221             JSONObject object = dependencyObjList.getJSONObject(i);
1222             DependencyItem item = new DependencyItem();
1223             if (object.containsKey(BUNDLE_NAME)) {
1224                 item.setBundleName(object.getString(BUNDLE_NAME));
1225             } else {
1226                 item.setBundleName(bundleName);
1227             }
1228             if (object.containsKey(MODULE_NAME)) {
1229                 item.setModuleName(object.getString(MODULE_NAME));
1230             }
1231             dependencyItemList.add(item);
1232         }
1233         return dependencyItemList;
1234     }
1235 
parseStageInstallation(String jsonString)1236     static boolean parseStageInstallation(String jsonString) throws BundleException {
1237         JSONObject moduleObj = getModuleObj(jsonString);
1238 
1239         if (moduleObj.containsKey(INSTALLATION_FREE)) {
1240             return moduleObj.getBoolean(INSTALLATION_FREE);
1241         }
1242         return false;
1243     }
1244 
parseStageBundleType(String jsonString)1245     static String parseStageBundleType(String jsonString) throws BundleException {
1246         JSONObject moduleObj = getModuleObj(jsonString);
1247         String moduleName = parseStageModuleName(jsonString);
1248         if (!moduleObj.containsKey(TYPE)) {
1249             String errMsg = "parse failed, input module.json is invalid, " +
1250                     "module.json has no type in module: " + moduleName;
1251             LOG.error(errMsg);
1252             throw new BundleException(errMsg);
1253         }
1254         String type = moduleObj.getString(TYPE);
1255         boolean installationFree = getJsonBooleanValue(moduleObj, INSTALLATION_FREE, false);
1256         JSONObject appObj = getAppObj(jsonString);
1257         if (!appObj.containsKey(BUNDLE_TYPE)) {
1258             if (installationFree) {
1259                 String errMessage = "The app.json5 file configuration does not match the installationFree:" +
1260                         " true settings. Add the bundleType field to the app.json5 file and set it atomicService.";
1261                 LOG.error(errMessage);
1262                 throw new BundleException(errMessage);
1263             }
1264             return APP;
1265         } else {
1266             String bundleType = getJsonString(appObj, BUNDLE_TYPE);
1267             if (bundleType.equals(APP)) {
1268                 if (installationFree) {
1269                     String errMsg = "installationFree must be false in module(" +
1270                             moduleName + ") when bundleType is app.";
1271                     LOG.error(errMsg);
1272                     throw new BundleException(errMsg);
1273                 }
1274                 return APP;
1275             } else if (bundleType.equals(ATOMIC_SERVICE)) {
1276                 if (!installationFree) {
1277                     String errMsg = "installationFree must be true in module(" +
1278                             moduleName + ") when bundleType is atomicService.";
1279                     LOG.error(errMsg);
1280                     throw new BundleException(errMsg);
1281                 }
1282                 return ATOMIC_SERVICE;
1283             } else if (SHARED.equals(bundleType)) {
1284                 if (!SHARED.equals(type)) {
1285                     String errMsg = "type must be shared in module(" + moduleName + ") when bundleType is shared.";
1286                     LOG.error(errMsg);
1287                     throw new BundleException(errMsg);
1288                 }
1289                 return SHARED;
1290             } else if (APP_SERVICE.equals(bundleType)) {
1291                 return APP_SERVICE;
1292             } else {
1293                 LOG.error("bundleType is invalid in app.json.");
1294                 throw new BundleException("bundleType is invalid in app.json.");
1295             }
1296         }
1297     }
1298 
parseAtomicServicePreloads(String jsonString)1299     static List<PreloadItem> parseAtomicServicePreloads(String jsonString) throws BundleException {
1300         List<PreloadItem> preloadItems = new ArrayList<>();
1301         JSONObject moduleObj = getModuleObj(jsonString);
1302         JSONObject atomicServiceObj = null;
1303         if (!moduleObj.containsKey(ATOMIC_SERVICE)) {
1304             return preloadItems;
1305         }
1306         atomicServiceObj = moduleObj.getJSONObject(ATOMIC_SERVICE);
1307         if (!atomicServiceObj.containsKey(PRELOADS)) {
1308             return preloadItems;
1309         }
1310         JSONArray preloadObjs = atomicServiceObj.getJSONArray(PRELOADS);
1311         for (int i = 0; i < preloadObjs.size(); ++i) {
1312             PreloadItem preloadItem = new PreloadItem();
1313             JSONObject itemObj = preloadObjs.getJSONObject(i);
1314             if (itemObj.containsKey(MODULE_NAME)) {
1315                 preloadItem.setModuleName(getJsonString(itemObj, MODULE_NAME));
1316             }
1317             preloadItems.add(preloadItem);
1318         }
1319         return preloadItems;
1320     }
1321 
parseProxyDataUri(String jsonString)1322     static List<String> parseProxyDataUri(String jsonString) throws BundleException {
1323         List<String> proxyDataUris = new ArrayList<>();
1324         JSONObject moduleObj = getModuleObj(jsonString);
1325         if (!moduleObj.containsKey(PROXY_DATAS) && !moduleObj.containsKey(PROXY_DATA)) {
1326             return proxyDataUris;
1327         } else if (moduleObj.containsKey(PROXY_DATA)) {
1328             JSONArray proxyData = moduleObj.getJSONArray(PROXY_DATA);
1329             for (int i = 0; i < proxyData.size(); ++i) {
1330                 JSONObject itemObj = proxyData.getJSONObject(i);
1331                 if (!itemObj.containsKey(PROXY_URI)) {
1332                     LOG.error("parse JOSNObject failed in parseProxyDataUri.");
1333                     throw new BundleException("parse JOSNObject failed in parseProxyDataUri.");
1334                 }
1335                 String uri = itemObj.getString(PROXY_URI);
1336                 proxyDataUris.add(uri);
1337             }
1338         } else {
1339             JSONArray proxyDatas = moduleObj.getJSONArray(PROXY_DATAS);
1340             for (int i = 0; i < proxyDatas.size(); ++i) {
1341                 JSONObject itemObj = proxyDatas.getJSONObject(i);
1342                 if (!itemObj.containsKey(PROXY_URI)) {
1343                     LOG.error("parse JOSNObject failed in parseProxyDataUri.");
1344                     throw new BundleException("parse JOSNObject failed in parseProxyDataUri.");
1345                 }
1346                 String uri = itemObj.getString(PROXY_URI);
1347                 proxyDataUris.add(uri);
1348             }
1349         }
1350         return proxyDataUris;
1351     }
1352 
getAppObj(String jsonString)1353     static JSONObject getAppObj(String jsonString) throws BundleException {
1354         JSONObject jsonObject;
1355         try {
1356             jsonObject = JSON.parseObject(jsonString);
1357         } catch (JSONException exception) {
1358             String errMsg = "parse JSONobject failed.";
1359             LOG.error(errMsg);
1360             throw new BundleException(errMsg);
1361         }
1362         JSONObject appObj = jsonObject.getJSONObject(APP);
1363         if (appObj == null) {
1364             LOG.error("ModuleJsonUtil::parseStageInstallation json do not contain app.");
1365             throw new BundleException("ModuleJsonUtil::parseStageInstallation json do not contain app.");
1366         }
1367         return appObj;
1368     }
1369 
getModuleObj(String jsonString)1370     static JSONObject getModuleObj(String jsonString) throws BundleException {
1371         JSONObject jsonObj;
1372         try {
1373             jsonObj = JSON.parseObject(jsonString);
1374         } catch (JSONException exception) {
1375             String errMsg = "parse JSONobject failed.";
1376             LOG.error(errMsg);
1377             throw new BundleException(errMsg);
1378         }
1379         if (jsonObj == null) {
1380             LOG.error("ModuleJsonUtil::parseStageInstallation jsonObj is null.");
1381             throw new BundleException("ModuleJsonUtil::parseStageInstallation jsonObj is null.");
1382         }
1383         JSONObject moduleObj = jsonObj.getJSONObject(MODULE);
1384         if (moduleObj == null) {
1385             LOG.error("ModuleJsonUtil::parseStageInstallation json do not contain module.");
1386             throw new BundleException("ModuleJsonUtil::parseStageInstallation json do not contain module.");
1387         }
1388         return moduleObj;
1389     }
1390 
parseTargetBundleName(String jsonString)1391     static String parseTargetBundleName(String jsonString) throws BundleException {
1392         JSONObject appObject = getAppObj(jsonString);
1393         String targetBundleName = "";
1394         if (appObject.containsKey(TARGET_BUNDLE_NAME)) {
1395             targetBundleName = appObject.getString(TARGET_BUNDLE_NAME);
1396         }
1397         return targetBundleName;
1398     }
1399 
parseTargetPriority(String jsonString)1400     static int parseTargetPriority(String jsonString) throws BundleException {
1401         JSONObject appObject = getAppObj(jsonString);
1402         int targetPriority = 0;
1403         if (appObject.containsKey(TARGET_PRIORITY)) {
1404             targetPriority = appObject.getIntValue(TARGET_PRIORITY);
1405         }
1406         return targetPriority;
1407     }
1408 
parseTargetModuleName(String jsonString)1409     static String parseTargetModuleName(String jsonString) throws BundleException {
1410         JSONObject moduleObj = getModuleObj(jsonString);
1411         String targetModuleName = "";
1412         if (moduleObj.containsKey(TARGET_MODULE_NAME)) {
1413             targetModuleName = moduleObj.getString(TARGET_MODULE_NAME);
1414         }
1415         return targetModuleName;
1416     }
1417 
parseTargetModulePriority(String jsonString)1418     static int parseTargetModulePriority(String jsonString) throws BundleException {
1419         JSONObject moduleObj = getModuleObj(jsonString);
1420         int targetModulePriority = 0;
1421         if (moduleObj.containsKey(TARGET_PRIORITY)) {
1422             targetModulePriority = moduleObj.getIntValue(TARGET_PRIORITY);
1423         }
1424         return targetModulePriority;
1425     }
1426 
parseFAInstallationFree(String jsonString)1427     static boolean parseFAInstallationFree(String jsonString) throws BundleException {
1428         JSONObject moduleObj = getModuleObj(jsonString);
1429         JSONObject distroObj = moduleObj.getJSONObject(DISTRO);
1430         if (distroObj == null) {
1431             LOG.error("ModuleJsonUtil::parseStageInstallation json do not contain distro.");
1432             throw new BundleException("ModuleJsonUtil::parseStageInstallation json do not contain distro.");
1433         }
1434         if (distroObj.containsKey(INSTALLATION_FREE)) {
1435             return distroObj.getBoolean(INSTALLATION_FREE);
1436         }
1437         return false;
1438     }
1439 
1440     /**
1441      * get hqfVerifyINfo from hqf file
1442      *
1443      * @param hqfPath is the file path of hqf file
1444      * @return HQFVerifyInfo
1445      */
parseHQFInfo(String hqfPath)1446     static HQFInfo parseHQFInfo(String hqfPath) throws BundleException {
1447         File hqfFile = new File(hqfPath);
1448         String patchJson = FileUtils.getJsonInZips(hqfFile, PATCH_JSON);
1449         return parsePatch(patchJson);
1450     }
1451 
1452     /**
1453      * parse patch.json form json string.
1454      *
1455      * @param jsonString is the file path of hqf file
1456      * @return HQFVerifyInfo
1457      */
parsePatch(String jsonString)1458     static HQFInfo parsePatch(String jsonString) throws BundleException {
1459         JSONObject appObj = getAppObj(jsonString);
1460         HQFInfo hqfVerifyInfo = new HQFInfo();
1461         if (appObj.containsKey(BUNDLE_NAME)) {
1462             hqfVerifyInfo.setBundleName(appObj.getString(BUNDLE_NAME));
1463         }
1464         if (appObj.containsKey(VERSIONCODE)) {
1465             hqfVerifyInfo.setVersionCode(appObj.getIntValue(VERSIONCODE));
1466         }
1467         if (appObj.containsKey(VERSIONNAME)) {
1468             hqfVerifyInfo.setVersionName(appObj.getString(VERSIONNAME));
1469         }
1470         if (appObj.containsKey(PATCH_VERSION_CODE)) {
1471             hqfVerifyInfo.setPatchVersionCode(appObj.getIntValue(PATCH_VERSION_CODE));
1472         }
1473         if (appObj.containsKey(PATCH_VERSION_NAME)) {
1474             hqfVerifyInfo.setPatchVersionName(appObj.getString(PATCH_VERSION_NAME));
1475         }
1476 
1477         JSONObject moduleObj = getModuleObj(jsonString);
1478         if (moduleObj.containsKey(NAME)) {
1479             hqfVerifyInfo.setModuleName(moduleObj.getString(NAME));
1480         }
1481         if (moduleObj.containsKey(TYPE)) {
1482             hqfVerifyInfo.setType(moduleObj.getString(TYPE));
1483         }
1484         if (moduleObj.containsKey(DEVICE_TYPES)) {
1485             hqfVerifyInfo.setDeviceTypes(JSONObject.parseArray(getJsonString(moduleObj, DEVICE_TYPES), String.class));
1486         }
1487         if (moduleObj.containsKey(ORIGINAL_MODULE_HASH)) {
1488             hqfVerifyInfo.setOriginalModuleHash(moduleObj.getString(ORIGINAL_MODULE_HASH));
1489         }
1490         return hqfVerifyInfo;
1491     }
1492 
1493     /**
1494      * determine whether it is a native compression libs.
1495      *
1496      * @param jsonString is the file path of hqf file
1497      * @return the result
1498      */
stageIsCompressNativeLibs(String jsonString)1499     public static boolean stageIsCompressNativeLibs(String jsonString) throws BundleException {
1500         JSONObject moduleObj = getModuleObj(jsonString);
1501         if (moduleObj.containsKey(COMPRESS_NATIVE_LIBS)) {
1502             return moduleObj.getBoolean(COMPRESS_NATIVE_LIBS);
1503         }
1504 
1505         return false;
1506     }
1507 
1508     /**
1509      * get asanEnabled in module.json
1510      *
1511      * @param jsonString is the file content of module.json
1512      * @return the value of asanEnabled
1513      */
getStageAsanEnabled(String jsonString)1514     public static boolean getStageAsanEnabled(String jsonString) throws BundleException {
1515         JSONObject appObj = getAppObj(jsonString);
1516         if (appObj.containsKey(ASAN_ENABLED)) {
1517             return appObj.getBoolean(ASAN_ENABLED);
1518         }
1519         return false;
1520     }
1521 
1522     /**
1523      * get tsanEnabled in module.json
1524      *
1525      * @param jsonString is the file content of module.json
1526      * @return the value of tsanEnabled
1527      */
getStageTsanEnabled(String jsonString)1528     public static boolean getStageTsanEnabled(String jsonString) throws BundleException {
1529         JSONObject appObj = getAppObj(jsonString);
1530         if (appObj.containsKey(TSAN_ENABLED)) {
1531             return appObj.getBoolean(TSAN_ENABLED);
1532         }
1533         return false;
1534     }
1535 
1536     /**
1537      * get gwpAsanEnabled in module.json
1538      *
1539      * @param jsonString is the file content of module.json
1540      * @return the value of gwpAsanEnabled
1541      */
getStageGwpAsanEnabled(String jsonString)1542     public static boolean getStageGwpAsanEnabled(String jsonString) throws BundleException {
1543         JSONObject appObj = getAppObj(jsonString);
1544         if (appObj.containsKey(GWP_ASAN_ENABLED)) {
1545             return appObj.getBoolean(GWP_ASAN_ENABLED);
1546         }
1547         return false;
1548     }
1549 
1550     /**
1551      * get hwasanEnabled in module.json
1552      *
1553      * @param jsonString is the file content of module.json
1554      * @return the value of hwasanEnabled
1555      */
getStageHwasanEnabled(String jsonString)1556     public static boolean getStageHwasanEnabled(String jsonString) throws BundleException {
1557         JSONObject appObj = getAppObj(jsonString);
1558         if (appObj.containsKey(HW_ASAN_ENABLED)) {
1559             return appObj.getBoolean(HW_ASAN_ENABLED);
1560         }
1561         return false;
1562     }
1563 
1564     /**
1565      * get ubsanEnabled in module.json
1566      *
1567      * @param jsonString is the file content of module.json
1568      * @return the value of ubsanEnabled
1569      */
getStageUbsanEnabled(String jsonString)1570     public static boolean getStageUbsanEnabled(String jsonString) throws BundleException {
1571         JSONObject appObj = getAppObj(jsonString);
1572         if (appObj.containsKey(UB_SAN_ENABLED)) {
1573             return appObj.getBoolean(UB_SAN_ENABLED);
1574         }
1575         return false;
1576     }
1577 
1578 
1579     /**
1580      * get ability continueBundleName map from json file.
1581      *
1582      * @param jsonString is the json String of module.json
1583      * @return continueBundleName map
1584      */
getAbilityContinueBundleNameMap(String jsonString)1585     public static Map<String, List<String>> getAbilityContinueBundleNameMap(String jsonString)
1586             throws BundleException {
1587         Map<String, List<String>> continueBundleName = new HashMap<>();
1588         JSONObject moduleObj = getModuleObj(jsonString);
1589         if (moduleObj.containsKey(ABILITIES)) {
1590             JSONArray abilityObjs = moduleObj.getJSONArray(ABILITIES);
1591             for (int i = 0; i < abilityObjs.size(); ++i) {
1592                 JSONObject abilityObj = abilityObjs.getJSONObject(i);
1593                 String abilityName = getJsonString(abilityObj, NAME);
1594                 if (abilityObj.containsKey(CONTINUE_BUNDLE_NAME)) {
1595                     JSONArray typeArray = abilityObj.getJSONArray(CONTINUE_BUNDLE_NAME);
1596                     continueBundleName.put(abilityName, typeArray.toJavaList(String.class));
1597                 } else {
1598                     continueBundleName.put(abilityName, new ArrayList<>());
1599                 }
1600             }
1601         }
1602         return continueBundleName;
1603     }
1604 
1605     /**
1606      * get apiReleaseType in module.json
1607      *
1608      * @param jsonString is the file content of module.json
1609      * @return the result
1610      */
getStageApiReleaseType(String jsonString)1611     public static String getStageApiReleaseType(String jsonString) throws BundleException {
1612         JSONObject appObj = getAppObj(jsonString);
1613         return getJsonString(appObj, API_RELEASE_TYPE);
1614     }
1615 
1616     /**
1617      * get debug in module.json
1618      *
1619      * @param jsonString is the file content of module.json
1620      * @return the result
1621      */
getDebug(String jsonString)1622     public static boolean getDebug(String jsonString) throws BundleException {
1623         JSONObject appObj = getAppObj(jsonString);
1624 
1625         return getJsonBooleanValue(appObj, DEBUG, false);
1626     }
1627 
1628     /**
1629      * get debug in config.json
1630      *
1631      * @param jsonString is the file content of module.json
1632      * @return the result
1633      */
getFADebug(String jsonString)1634     public static boolean getFADebug(String jsonString) throws BundleException {
1635         JSONObject jsonObject;
1636         try {
1637             jsonObject = JSON.parseObject(jsonString);
1638         } catch (JSONException exception) {
1639             LOG.error("parse JOSNObject failed in getStageApiReleaseType.");
1640             throw new BundleException("parse JOSNObject failed in getStageApiReleaseType.");
1641         }
1642         JSONObject deviceConfigObj = jsonObject.getJSONObject(DEVICE_CONFIG);
1643         if (deviceConfigObj == null) {
1644             return false;
1645         }
1646         JSONObject defaultObj = deviceConfigObj.getJSONObject(DEFAULT);
1647         if (defaultObj == null) {
1648             return false;
1649         }
1650 
1651         return getJsonBooleanValue(defaultObj, DEBUG, false);
1652     }
1653 
1654     /**
1655      * get compileSdkVersion in config.json
1656      *
1657      * @param jsonString is the file content of module.json
1658      * @return the result
1659      */
getFACompileSdkVersion(String jsonString)1660     public static String getFACompileSdkVersion(String jsonString) throws BundleException {
1661         JSONObject appObj = getAppObj(jsonString);
1662         JSONObject apiVersionObj = appObj.getJSONObject(API_VERSION);
1663         String compileSdkVersion = "";
1664         if (apiVersionObj.containsKey(COMPILE_SDK_VERSION)) {
1665             compileSdkVersion = apiVersionObj.getString(COMPILE_SDK_VERSION);
1666         }
1667         return compileSdkVersion;
1668     }
1669 
1670     /**
1671      * get compileSdkType in config.json
1672      *
1673      * @param jsonString is the file content of module.json
1674      * @return the result
1675      */
getFACompileSdkType(String jsonString)1676     public static String getFACompileSdkType(String jsonString) throws BundleException {
1677         JSONObject appObj = getAppObj(jsonString);
1678         if (!appObj.containsKey(API_VERSION)) {
1679             throw new BundleException("ModuleJsonUtil::parseFAAPIVersion json file do not contain apiVersion.");
1680         }
1681         JSONObject apiVersionObj = appObj.getJSONObject(API_VERSION);
1682         String compileSdkType = "";
1683         if (apiVersionObj.containsKey(COMPILE_SDK_TYPE)) {
1684             compileSdkType = apiVersionObj.getString(COMPILE_SDK_TYPE);
1685         }
1686         return compileSdkType;
1687     }
1688 
1689     /**
1690      * get compileSdkVersion in module.json
1691      *
1692      * @param jsonString is the file content of module.json
1693      * @return the result
1694      */
getCompileSdkVersion(String jsonString)1695     public static String getCompileSdkVersion(String jsonString) throws BundleException {
1696         String compileSdkVersion = "";
1697         JSONObject appObj = getAppObj(jsonString);
1698         if (appObj.containsKey(COMPILE_SDK_VERSION)) {
1699             compileSdkVersion = appObj.getString(COMPILE_SDK_VERSION);
1700         } else {
1701             LOG.warning("getCompileSdkType failed: json file do not contain module compileSdkVersion.");
1702         }
1703         return compileSdkVersion;
1704     }
1705 
1706     /**
1707      * get compileSdkType in module.json
1708      *
1709      * @param jsonString is the file content of module.json
1710      * @return the result
1711      */
getCompileSdkType(String jsonString)1712     public static String getCompileSdkType(String jsonString) throws BundleException {
1713         String compileSdkType = "";
1714         JSONObject appObj = getAppObj(jsonString);
1715         if (appObj.containsKey(COMPILE_SDK_TYPE)) {
1716             compileSdkType = appObj.getString(COMPILE_SDK_TYPE);
1717         } else {
1718             LOG.warning("getCompileSdkType failed: json file do not contain module compileSdkType.");
1719         }
1720         return compileSdkType;
1721     }
1722 
1723     /**
1724      * get targetModuleName in module.json
1725      *
1726      * @param jsonString is the file content of module.json
1727      * @return the result
1728      */
getStageTargetModuleName(String jsonString)1729     public static String getStageTargetModuleName(String jsonString) throws BundleException {
1730         JSONObject moduleObj = getModuleObj(jsonString);
1731         return getJsonString(moduleObj, TARGET_MODULE_NAME);
1732     }
1733 
1734     /**
1735      * get targetBundleName in module.json
1736      *
1737      * @param jsonString is the file content of module.json
1738      * @return the result
1739      */
getStageTargetBundleName(String jsonString)1740     public static String getStageTargetBundleName(String jsonString) throws BundleException {
1741         JSONObject appObj = getAppObj(jsonString);
1742         return getJsonString(appObj, TARGET_BUNDLE_NAME);
1743     }
1744 
1745     /**
1746      * is existed requestPermission in module.json
1747      *
1748      * @param jsonString is the file content of module.json
1749      * @return the result
1750      */
isExistedStageRequestPermissions(String jsonString)1751     public static boolean isExistedStageRequestPermissions(String jsonString) throws BundleException {
1752         return isExistedProperty(jsonString, MODULE, REQUEST_PERMISSIONS);
1753     }
1754 
1755     /**
1756      * is existed targetPriority in module.json
1757      *
1758      * @param jsonString is the file content of module.json
1759      * @return the result
1760      */
isExistedStageModuleTargetPriority(String jsonString)1761     public static boolean isExistedStageModuleTargetPriority(String jsonString) throws BundleException {
1762         return isExistedProperty(jsonString, MODULE, TARGET_PRIORITY);
1763     }
1764 
1765     /**
1766      * is existed targetPriority in app.json
1767      *
1768      * @param jsonString is the file content of module.json
1769      * @return the result
1770      */
isExistedStageAppTargetPriority(String jsonString)1771     public static boolean isExistedStageAppTargetPriority(String jsonString) throws BundleException {
1772         return isExistedProperty(jsonString, APP, TARGET_PRIORITY);
1773     }
1774 
isExistedProperty(String jsonString, String fatherProperty, String childProperty)1775     private static boolean isExistedProperty(String jsonString, String fatherProperty,
1776                                              String childProperty) throws BundleException {
1777         JSONObject jsonObject;
1778         try {
1779             jsonObject = JSON.parseObject(jsonString);
1780         } catch (JSONException exception) {
1781             LOG.error("parse JOSNObject failed in isExistedProperty.");
1782             throw new BundleException("parse JOSNObject failed in isExistedProperty.");
1783         }
1784         JSONObject appObj = jsonObject.getJSONObject(fatherProperty);
1785         if (appObj == null) {
1786             LOG.error("parse failed, input module.json is invalid, module.json has no " + fatherProperty + ".");
1787             throw new BundleException("parse failed, input module.json is invalid, module.json has no " +
1788                     fatherProperty + ".");
1789         }
1790         return appObj.containsKey(childProperty);
1791     }
1792 
1793     /**
1794      * get asanEnabled in config.json
1795      *
1796      * @param jsonString is the file content of module.json
1797      * @return the value of asanEnabled
1798      */
getFAAsanEnabled(String jsonString)1799     public static boolean getFAAsanEnabled(String jsonString) throws BundleException {
1800         JSONObject appObj = getAppObj(jsonString);
1801         if (appObj.containsKey(ASAN_ENABLED)) {
1802             return appObj.getBoolean(ASAN_ENABLED);
1803         }
1804         return false;
1805     }
1806 
1807     /**
1808      * get releaseType in config.json
1809      *
1810      * @param jsonString is the file content of config.json
1811      * @return the result
1812      */
getFAReleaseType(String jsonString)1813     public static String getFAReleaseType(String jsonString) throws BundleException {
1814         JSONObject appObj = getAppObj(jsonString);
1815         JSONObject apiVersionObj = appObj.getJSONObject(API_VERSION);
1816         if (apiVersionObj == null) {
1817             return "";
1818         }
1819         return getJsonString(apiVersionObj, RELEASE_TYPE);
1820     }
1821 
1822     /**
1823      * check module atomic service is valid
1824      *
1825      * @param jsonString is the file content of config.json
1826      * @return the result
1827      * @throws BundleException Throws this exception if the json is not standard.
1828      */
isModuleAtomicServiceValid(String jsonString)1829     public static boolean isModuleAtomicServiceValid(String jsonString) throws BundleException {
1830         JSONObject moduleObj = getModuleObj(jsonString);
1831         if (!moduleObj.containsKey(ATOMIC_SERVICE)) {
1832             return true;
1833         }
1834         JSONObject appObj = getAppObj(jsonString);
1835 
1836         if (moduleObj.containsKey(ATOMIC_SERVICE) && (!appObj.containsKey(BUNDLE_TYPE) ||
1837                 !getJsonString(appObj, BUNDLE_TYPE).equals(ATOMIC_SERVICE))) {
1838             LOG.error("module can not config atomicService when bundleType is not atomicService.");
1839             return false;
1840         }
1841         return true;
1842     }
1843 
1844     /**
1845      * check entry module must contain at least one ability.
1846      *
1847      * @param jsonString Indicates the jsonString.
1848      * @return Returns true if jsonString is valid.
1849      */
checkEntryInAtomicService(String jsonString)1850     public static boolean checkEntryInAtomicService(String jsonString) throws BundleException {
1851         if (!parseStageBundleType(jsonString).equals(ATOMIC_SERVICE)) {
1852             return true;
1853         }
1854         if (parseModuleType(jsonString).equals(ENTRY) && parseAbilityNames(jsonString).isEmpty()) {
1855             LOG.error("entry module must contain at least one ability.");
1856             return false;
1857         }
1858         return true;
1859     }
1860 
1861     /**
1862      * check module atomic installation free is valid
1863      *
1864      * @param jsonString is the file content of config.json
1865      * @return the result
1866      * @throws BundleException Throws this exception if the json is not standard.
1867      */
checkAtomicServiceInstallationFree(String jsonString)1868     public static boolean checkAtomicServiceInstallationFree(String jsonString) throws BundleException {
1869         JSONObject moduleObj = getModuleObj(jsonString);
1870         JSONObject appObj = getAppObj(jsonString);
1871 
1872         boolean installationFree = getJsonBooleanValue(moduleObj, INSTALLATION_FREE, false);
1873         if (!appObj.containsKey(BUNDLE_TYPE)) {
1874             if (installationFree) {
1875                 String errMessage = "The app.json5 file configuration does not match the installationFree:" +
1876                         " true settings. Add the bundleType field to the app.json5 file and set it atomicService.";
1877                 LOG.error(errMessage);
1878                 return false;
1879             }
1880             return true;
1881         }
1882         String bundleType = getJsonString(appObj, BUNDLE_TYPE);
1883         if (bundleType.equals(APP)) {
1884             if (installationFree) {
1885                 LOG.error("installationFree must be false when bundleType is app.");
1886                 return false;
1887             }
1888         } else if (bundleType.equals(ATOMIC_SERVICE)) {
1889             if (!installationFree) {
1890                 LOG.error("installationFree must be true when bundleType is atomicService.");
1891                 return false;
1892             }
1893         } else if (SHARED.equals(bundleType)) {
1894             if (installationFree) {
1895                 LOG.error("installationFree must be false when bundleType is shared.");
1896                 return false;
1897             }
1898         } else if (APP_SERVICE.equals(bundleType)) {
1899             if (installationFree) {
1900                 LOG.error("installationFree must be false when bundleType is appService.");
1901                 return false;
1902             }
1903         } else {
1904             LOG.error("bundleType is invalid in app.json.");
1905             return false;
1906         }
1907         return true;
1908     }
1909 
1910     /**
1911      * get the String from JSONObject by the key.
1912      *
1913      * @param jsonObject uncompress json object
1914      * @param key value key
1915      * @return the result
1916      */
getJsonString(JSONObject jsonObject, String key)1917     private static String getJsonString(JSONObject jsonObject, String key) {
1918         String value = "";
1919         if (jsonObject != null && jsonObject.containsKey(key) && jsonObject.get(key) != null) {
1920             value = jsonObject.get(key).toString();
1921         }
1922         return value;
1923     }
1924 
getJsonBooleanValue(JSONObject jsonObject, String key, boolean defaultValue)1925     private static boolean getJsonBooleanValue(JSONObject jsonObject, String key, boolean defaultValue) {
1926         boolean value = defaultValue;
1927         if (jsonObject != null && jsonObject.containsKey(key)) {
1928             value = jsonObject.getBooleanValue(key);
1929         }
1930         return value;
1931     }
1932 
getCount(String str, char targetChar)1933     private static int getCount(String str, char targetChar) {
1934         int count = 0;
1935         for (int i = 0; i < str.length(); i++) {
1936             if (str.charAt(i) == targetChar) {
1937                 count++;
1938             }
1939         }
1940         return count;
1941     }
1942 
parsePackInfoExtensionAbility(String moduleName, JSONObject moduleJson, List<String> formNameList, List<String> fullFormNameList)1943     private static void parsePackInfoExtensionAbility(String moduleName, JSONObject moduleJson, List<String> formNameList,
1944                                               List<String> fullFormNameList) throws BundleException {
1945         if (!moduleJson.containsKey(EXTENSION_ABILITIES)) {
1946             LOG.warning("ModuleJsonUtil::parsePackInfoExtensionAbility error: summary.modules.extensionAbilities is null.");
1947             return;
1948         }
1949 
1950         JSONArray extensionAbilityJsonList = moduleJson.getJSONArray(EXTENSION_ABILITIES);
1951         for (int j = 0; j < extensionAbilityJsonList.size(); j++) {
1952             JSONObject extensionAbilityJson = extensionAbilityJsonList.getJSONObject(j);
1953             if (extensionAbilityJson == null || !extensionAbilityJson.containsKey(FORMS)) {
1954                 LOG.warning("ModuleJsonUtil::parsePackInfoExtensionAbility error: " +
1955                         "summary.modules.extensionAbilities.forms is null.");
1956                 continue;
1957             }
1958 
1959             parsePackInfoForms(moduleName, extensionAbilityJson, formNameList, fullFormNameList);
1960         }
1961     }
1962 
parsePackInfoForms(String moduleName, JSONObject extensionAbilityJson, List<String> formNameList, List<String> fullFormNameList)1963     private static void parsePackInfoForms(String moduleName, JSONObject extensionAbilityJson, List<String> formNameList,
1964                                                  List<String> fullFormNameList) throws BundleException {
1965         JSONArray formJsonList = extensionAbilityJson.getJSONArray(FORMS);
1966         for (int i = 0; i < formJsonList.size(); i++) {
1967             JSONObject formObj = formJsonList.getJSONObject(i);
1968             if (formObj == null || !formObj.containsKey(NAME)) {
1969                 LOG.warning("ModuleJsonUtil::parsePackInfoForms error: " +
1970                         "summary.modules.extensionAbilities.forms.name is null.");
1971                 continue;
1972             }
1973 
1974             String name = formObj.getString(NAME);
1975             formNameList.add(name);
1976             if (!formObj.containsKey(DEFAULTDIMENSION)) {
1977                 LOG.error("ModuleJsonUtil::parsePackInfoForms exception: " +
1978                         "summary.modules.extensionAbilities.forms.defaultDimension is null.");
1979                 throw new BundleException("Parse pack info defaultDimension failed, defaultDimension is null.");
1980             }
1981 
1982             String defaultDimension = formObj.getString(DEFAULTDIMENSION);
1983             if (getCount(defaultDimension, '*') != 1) {
1984                 LOG.error("ModuleJsonUtil::parsePackInfoForms exception: " +
1985                         "summary.modules.extensionAbilities.forms.defaultDimension is not only 1.");
1986                 throw new BundleException("Parse pack info defaultDimension failed, defaultDimension is not only 1.");
1987             }
1988             if (!formObj.containsKey(SUPPORTDIMENSIONS)) {
1989                 LOG.error("ModuleJsonUtil::parsePackInfoForms exception: " +
1990                         "summary.modules.extensionAbilities.forms.supportDimensions is null.");
1991                 throw new BundleException("Parse pack info supportDimensions failed, supportDimensions is null.");
1992             }
1993 
1994             List<String> dimensionList = JSONObject.parseArray(getJsonString(formObj, SUPPORTDIMENSIONS), String.class);
1995             for(String dimension : dimensionList) {
1996                 String nameWithDimension = moduleName + "/" + name + "-" + dimension.replace("*", "x");
1997                 fullFormNameList.add(nameWithDimension);
1998             }
1999         }
2000     }
2001 }
2002