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