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