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