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