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