/* * Copyright (c) 2021-2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package ohos; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONException; import java.io.File; import java.util.ArrayList; import java.util.List; import java.util.HashMap; import java.util.Optional; class ModuleJsonUtil { private static final String APP = "app"; private static final String ABILITIES = "abilities"; private static final String BUNDLE_TYPE = "bundleType"; private static final String VERSIONCODE = "versionCode"; private static final String VERSIONNAME = "versionName"; private static final String MIN_COMPATIBLE_VERSION_CODE = "minCompatibleVersionCode"; private static final String API_VERSION = "apiVersion"; private static final String MIN_API_VERSION = "minAPIVersion"; private static final String TARGET_API_VERSION = "targetAPIVersion"; private static final String API_RELEASE_TYPE = "apiReleaseType"; private static final String COMPATIBLE = "compatible"; private static final String RELEASE_TYPE = "releaseType"; private static final String TARGET = "target"; private static final String VERSION = "version"; private static final String CODE = "code"; private static final String NAME = "name"; private static final String MODULE = "module"; private static final String MODULES = "modules"; private static final String MODULE_NAME = "moduleName"; private static final String MODULE_TYPE = "moduleType"; private static final String DISTRO = "distro"; private static final String PACKAGE = "package"; private static final String PACKAGES = "packages"; private static final String SUMMARY = "summary"; private static final String BUNDLE_NAME = "bundleName"; private static final String ENTRY = "entry"; private static final char DOT = '.'; private static final String CONFIG_JSON = "config.json"; private static final String MODULE_JSON = "module.json"; private static final String DEVICE_TYPE = "deviceType"; private static final String DEVICE_TYPES = "deviceTypes"; private static final String TYPE= "type"; private static final String VENDOR = "vendor"; private static final String METADATA = "metadata"; private static final String RESOURCE = "resource"; private static final String PROFILE = "$profile:"; private static final String VALUE = "value"; private static final String JSON_PERFIX = ".json"; private static final String DISTRO_FILTER = "distroFilter"; private static final String DEPENDENCIES = "dependencies"; private static final String EXTENSION_ABILITIES = "extensionAbilities"; private static final String INSTALLATION_FREE = "installationFree"; private static final String PATCH_JSON = "patch.json"; private static final String PATCH_VERSION_CODE = "patchVersionCode"; private static final String PATCH_VERSION_NAME = "patchVersionName"; private static final String ORIGINAL_MODULE_HASH = "originalModuleHash"; private static final String EMPTY_STRING = ""; private static final String ASAN_ENABLED = "asanEnabled"; private static final String ATOMIC_SERVICE = "atomicService"; private static final String SPLIT = "split"; private static final String MAIN = "main"; private static final String PRELOADS = "preloads"; private static final String DEBUG = "debug"; private static final String DEVICE_CONFIG = "deviceConfig"; private static final String DEFAULT = "default"; private static final Log LOG = new Log(ModuleJsonUtil.class.toString()); /** * get the version from json file for stage module. * * @param jsonString uncompress json object * @throws BundleException Throws this exception if the json is not standard. * @return the result */ public static Version parseStageVersion(String jsonString) throws BundleException { Version version = new Version(); JSONObject jsonObject; try { jsonObject = JSON.parseObject(jsonString); } catch (JSONException exception) { String errMsg = "parse JSONobject failed."; LOG.error(errMsg); throw new BundleException(errMsg); } if (jsonObject.containsKey(APP)) { JSONObject appObj = jsonObject.getJSONObject(APP); if (appObj.containsKey(VERSIONCODE) && appObj.containsKey(VERSIONNAME)) { version.versionCode = getJsonIntValue(appObj, VERSIONCODE); version.versionName = getJsonString(appObj, VERSIONNAME); } else { String errMsg = "ModuleJsonUtil:parseStageVersion json file do not contain version."; LOG.error(errMsg); throw new BundleException(errMsg); } if (appObj.containsKey(MIN_COMPATIBLE_VERSION_CODE)) { version.minCompatibleVersionCode = getJsonIntValue(appObj, MIN_COMPATIBLE_VERSION_CODE); } else { version.minCompatibleVersionCode = version.versionCode; } } else { String errMsg = "ModuleJsonUtil:parseStageVersion json file do not contain app."; LOG.error(errMsg); throw new BundleException(errMsg); } return version; } /** * get the version from json file for fa module. * * @param jsonString uncompress json object * @throws BundleException Throws this exception if the json is not standard. * @return the result */ public static Version parseFaVersion(String jsonString) throws BundleException { Version version = new Version(); JSONObject jsonObject; try { jsonObject = JSON.parseObject(jsonString); } catch (JSONException exception) { String errMsg = "parse JSONobject failed."; LOG.error(errMsg); throw new BundleException(errMsg); } JSONObject appObj = jsonObject.getJSONObject(APP); if (appObj == null) { LOG.error("ModuleJsonUtil:parseFaVersion failed : json file do not contain app."); throw new BundleException("ModuleJsonUtil:parseFaVersion failed : json file do not contain app."); } JSONObject versionObj = appObj.getJSONObject(VERSION); if (versionObj == null) { LOG.error("ModuleJsonUtil:parseFaVersion failed : json file do not version."); throw new BundleException("ModuleJsonUtil:parseFaVersion failed : json file do not version."); } if (versionObj.containsKey(CODE) && versionObj.containsKey(NAME)) { version.versionName = getJsonString(versionObj, NAME); version.versionCode = getJsonIntValue(versionObj, CODE); } else { LOG.error("ModuleJsonUtil:parseFaVersion failed : json file do not version name or version code."); throw new BundleException( "ModuleJsonUtil:parseFaVersion failed : json file do not version name or version code."); } if (versionObj.containsKey(MIN_COMPATIBLE_VERSION_CODE)) { version.minCompatibleVersionCode = getJsonIntValue(versionObj, MIN_COMPATIBLE_VERSION_CODE); } else { version.minCompatibleVersionCode = version.versionCode; } return version; } /** * get the bundleType fa module. * * @param jsonString uncompress json object * @throws BundleException Throws this exception if the json is not standard. * @return the result */ public static String parseFaBundleType(String jsonString) throws BundleException { boolean installationFree = parseFAInstallationFree(jsonString); if (installationFree) { return ATOMIC_SERVICE; } return APP; } /** * get the apiVersion from json file for stage module. * * @param jsonString uncompress json object * @throws BundleException Throws this exception if the json is not standard. * @return the result */ public static ModuleApiVersion parseStageModuleApiVersion(String jsonString) throws BundleException { JSONObject jsonObject; try { jsonObject = JSON.parseObject(jsonString); } catch (JSONException exception) { String errMsg = "parse JSONobject failed"; LOG.error(errMsg); throw new BundleException(errMsg); } JSONObject appObj = jsonObject.getJSONObject(APP); if (appObj == null) { LOG.error("ModuleJsonUtil:parseFaVersion failed : json file do not contain app."); throw new BundleException("ModuleJsonUtil:parseFaVersion failed : json file do not contain app."); } ModuleApiVersion moduleApiVersion = new ModuleApiVersion(); if (appObj.containsKey(MIN_API_VERSION)) { moduleApiVersion.setCompatibleApiVersion(getJsonIntValue(appObj, MIN_API_VERSION)); } if (appObj.containsKey(TARGET_API_VERSION)) { moduleApiVersion.setTargetApiVersion(getJsonIntValue(appObj, TARGET_API_VERSION)); } if (appObj.containsKey(API_RELEASE_TYPE)) { moduleApiVersion.setReleaseType(getJsonString(appObj, API_RELEASE_TYPE)); } return moduleApiVersion; } /** * get the apiVersion from json file for fa module. * * @param jsonString uncompress json object * @throws BundleException Throws this exception if the json is not standard. * @return the result */ public static ModuleApiVersion parseFAModuleApiVersion(String jsonString) throws BundleException { JSONObject jsonObject; try { jsonObject = JSON.parseObject(jsonString); } catch (JSONException exception) { String errMsg = "parse JSONobject failed."; LOG.error(errMsg); throw new BundleException(errMsg); } JSONObject appObj = jsonObject.getJSONObject(APP); if (appObj == null) { throw new BundleException("ModuleJsonUtil::parseFAAPIVersion json file do not contain app."); } if (!appObj.containsKey(API_VERSION)) { throw new BundleException("ModuleJsonUtil::parseFAAPIVersion json file do not contain apiVersion."); } JSONObject apiVersionObj = appObj.getJSONObject(API_VERSION); ModuleApiVersion moduleApiVersion = new ModuleApiVersion(); if (apiVersionObj.containsKey(COMPATIBLE)) { moduleApiVersion.setCompatibleApiVersion(getJsonIntValue(apiVersionObj, COMPATIBLE)); } if (apiVersionObj.containsKey(RELEASE_TYPE)) { moduleApiVersion.setReleaseType(getJsonString(apiVersionObj, RELEASE_TYPE)); } if (apiVersionObj.containsKey(TARGET)) { moduleApiVersion.setTargetApiVersion(getJsonIntValue(apiVersionObj, TARGET)); } return moduleApiVersion; } /** * get the module name from json file for stage module. * * @param jsonString uncompress json object * @throws BundleException Throws this exception if the json is not standard. * @return the result */ public static String parseStageModuleName(String jsonString) throws BundleException { String moduleName = ""; JSONObject jsonObject; try { jsonObject = JSON.parseObject(jsonString); JSONObject moduleObj = jsonObject.getJSONObject(MODULE); if (moduleObj == null) { LOG.error("ModuleJsonUtil:parseStageModuleName failed: json file do not contain module."); throw new BundleException("ModuleJsonUtil:parseStageModuleName failed: json file do not contain module."); } if (moduleObj.containsKey(NAME)) { moduleName = getJsonString(moduleObj, NAME); } else { LOG.error("ModuleJsonUtil:parseStageModuleName failed: json file do not contain module name."); throw new BundleException("ModuleJsonUtil:parseStageModuleName failed: json file do not contain module name."); } } catch (BundleException e) { LOG.error("ModuleJsonUtil:parseStageModuleName failed."); throw new BundleException("ModuleJsonUtil:parseStageModuleName failed."); } return moduleName; } /** * get the moduleName from json file for stage module. * * @param jsonString uncompress json object * @throws BundleException Throws this exception if the json is not standard. * @return the result */ public static String parseFaModuleName(String jsonString) throws BundleException { String moduleName = ""; JSONObject jsonObject; try { jsonObject = JSON.parseObject(jsonString); JSONObject moduleObj = jsonObject.getJSONObject(MODULE); if (moduleObj == null) { LOG.error("ModuleJsonUtil:parseFaModuleName failed: json file do not contain module."); throw new BundleException("ModuleJsonUtil:parseFaModuleName failed: json file do not contain module."); } JSONObject distroObj = moduleObj.getJSONObject(DISTRO); if (distroObj == null) { LOG.error("ModuleJsonUtil:parseFaModuleName failed: json file do not contain distro."); throw new BundleException("ModuleJsonUtil:parseFaModuleName failed: json file do not contain distro."); } if (!distroObj.containsKey(MODULE_NAME)) { LOG.error("ModuleJsonUtil:parseFaModuleName failed: json file do not contain moduleName."); throw new BundleException("ModuleJsonUtil:parseFaModuleName failed: json file do not contain moduleName."); } moduleName = getJsonString(distroObj, MODULE_NAME); } catch (BundleException | JSONException e) { LOG.error("ModuleJsonUtil:parseFaModuleName failed."); throw new BundleException("ModuleJsonUtil:parseFaModuleName failed."); } return moduleName; } /** * get the package from json file for stage module. * * @param jsonString uncompress json object * @throws BundleException Throws this exception if the json is not standard. * @return the result */ public static String parseFaPackageStr(String jsonString) throws BundleException { String packageStr = ""; JSONObject jsonObject; try { jsonObject = JSON.parseObject(jsonString); JSONObject moduleObj = jsonObject.getJSONObject(MODULE); if (moduleObj == null) { LOG.error("ModuleJsonUtil:parseFaPackageStr failed: json file do not contain module."); throw new BundleException("ModuleJsonUtil:parseFaPackageStr failed: json file do not contain module."); } if (moduleObj.containsKey(PACKAGE)) { packageStr = getJsonString(moduleObj, PACKAGE); } else { LOG.error("ModuleJsonUtil:parseFaPackageStr failed: json file do not contain package."); throw new BundleException("ModuleJsonUtil:parseFaPackageStr failed: json file do not contain package."); } } catch (BundleException | JSONException e) { LOG.error("ModuleJsonUtil:parseFaPackageStr failed."); throw new BundleException("ModuleJsonUtil:parseFaPackageStr failed."); } return packageStr; } /** * get the bundleName from json file. * * @param jsonString uncompress json object * @throws BundleException Throws this exception if the json is not standard. * @return the result */ public static String parseBundleName(String jsonString) throws BundleException { JSONObject jsonObject; try { jsonObject = JSON.parseObject(jsonString); } catch (JSONException exception) { String errMsg = "parse JSONobject failed"; LOG.error(errMsg); throw new BundleException(errMsg); } JSONObject appObject = jsonObject.getJSONObject(APP); if (appObject == null) { LOG.error("ModuleJsonUtil::parseStageBundleName json object do not contain app."); throw new BundleException("ModuleJsonUtil::parseStageBundleName json object do not contain app."); } String bundleName = ""; if (appObject.containsKey(BUNDLE_NAME)) { bundleName = getJsonString(appObject, BUNDLE_NAME); } else { LOG.error("ModuleJsonUtil::parseStageBundleName json object do not contain bundleNames."); throw new BundleException("ModuleJsonUtil::parseStageBundleName json object do not contain bundleNames."); } return bundleName; } /** * get the vendor from json file. * * @param jsonString uncompress json object * @throws BundleException Throws this exception if the json is not standard. * @return the result */ public static String parseVendor(String jsonString) throws BundleException { JSONObject jsonObject; try { jsonObject = JSON.parseObject(jsonString); } catch (JSONException exception) { String errMsg = "parse JSONobject failed."; LOG.error(errMsg); throw new BundleException(errMsg); } JSONObject appObject = jsonObject.getJSONObject(APP); if (appObject == null) { LOG.error("ModuleJsonUtil::parseStageBundleName json object do not contain app."); throw new BundleException("ModuleJsonUtil::parseStageBundleName json object do not contain app."); } String vendor = ""; if (appObject.containsKey(VENDOR)) { vendor = getJsonString(appObject, VENDOR); } else { return vendor; } return vendor; } /** * merge two pack.info file into one pack.info file. * * @param finalPackInfo is the final packInfo * @param srcPackInfo is the packInfo to be merged * @throws BundleException Throws this exception if the json is not standard. * @return the result */ public static String mergeTwoPackInfo(String finalPackInfo, String srcPackInfo) throws BundleException { String desPackInfo = ""; JSONObject finalPackObj; try { finalPackObj = JSON.parseObject(finalPackInfo); JSONObject srcPackObj = JSON.parseObject(srcPackInfo); if (!verifyPackInfo(finalPackObj, srcPackObj)) { LOG.error("ModuleJsonUtil:mergeTwoPackInfo verify pack.info failed."); throw new BundleException("ModuleJsonUtil:mergeTwoPackInfo verify pack.info failed."); } desPackInfo = mergePackInfoObj(finalPackObj, srcPackObj); } catch (BundleException | JSONException e) { LOG.error("ModuleJsonUtil:mergeTwoPackInfo merge pack.info failed."); throw new BundleException("ModuleJsonUtil:mergeTwoPackInfo merge pack.info failed."); } return desPackInfo; } /** * verify pack.info file. * * @param finalPackObj is the final pack.info object * @param srcPackObj is the src pack.info object * @return the result */ public static boolean verifyPackInfo(JSONObject finalPackObj, JSONObject srcPackObj) throws BundleException { if (finalPackObj == null || srcPackObj == null) { LOG.error("ModuleJsonUtil:verifyPackInfo fail to read pack.info."); return false; } JSONObject finalSummaryObj = finalPackObj.getJSONObject(SUMMARY); JSONObject srcSummaryObj = srcPackObj.getJSONObject(SUMMARY); if (finalSummaryObj == null || srcSummaryObj == null) { LOG.error("ModuleJsonUtil:verifyPackInfo pack.info do not contain summary."); return false; } // check app info JSONObject finalAppObj = finalSummaryObj.getJSONObject(APP); JSONObject srcAppObj = srcSummaryObj.getJSONObject(APP); if (finalAppObj == null || srcAppObj == null) { LOG.error("ModuleJsonUtil:verifyPackInfo pack.info do not contain app."); return false; } if (!verifyAppInPackInfo(finalAppObj, srcAppObj)) { LOG.error("ModuleJsonUtil:verifyPackInfo verify app failed."); return false; } return true; } /** * verify app in pack.info file. * * @param finalAppObj is the final pack.info app object * @param srcAppObj is the src pack.info app object * @return the result */ public static boolean verifyAppInPackInfo(JSONObject finalAppObj, JSONObject srcAppObj) { if (finalAppObj == null || srcAppObj == null) { LOG.error("ModuleJsonUtil:verifyAppInPackInfo input null json object."); return false; } // check bundleName String finalBundleName = getJsonString(finalAppObj, BUNDLE_NAME); String srcBundleName = getJsonString(srcAppObj, BUNDLE_NAME); if (!finalBundleName.equals(srcBundleName)) { LOG.error("ModuleJsonUtil:verifyAppInPackInfo bundleName is different."); return false; } // check bundleType if (!checkBundleTypeInPackInfo(finalAppObj, srcAppObj)) { LOG.error("ModuleJsonUtil:verifyAppInPackInfo bundleType is different."); return false; } // check version JSONObject finalVersionObj = finalAppObj.getJSONObject(VERSION); JSONObject srcVersionObj = srcAppObj.getJSONObject(VERSION); if (finalVersionObj == null || srcVersionObj == null) { LOG.error("ModuleJsonUtil:verifyAppInPackInfo version object is empty."); return false; } String finalVersionName = getJsonString(finalVersionObj, NAME); String srcVersionName = getJsonString(srcVersionObj, NAME); if (!finalVersionName.equals(srcVersionName)) { LOG.error("ModuleJsonUtil:verifyAppInPackInfo versionName is different."); return false; } int finalVersionCode = getJsonIntValue(finalVersionObj, CODE); int srcVersionCode = getJsonIntValue(srcVersionObj, CODE); if (finalVersionCode != srcVersionCode) { LOG.error("ModuleJsonUtil:verifyAppInPackInfo versionCode is different."); return false; } return true; } /** * verify bundleType in pack.info file. * * @param finalAppObj is the final pack.info app objects * @param srcAppObj is the src pack.info app objects * @return the result */ public static boolean checkBundleTypeInPackInfo(JSONObject finalAppObj, JSONObject srcAppObj) { if (finalAppObj.isEmpty() || srcAppObj.isEmpty()) { LOG.error("ModuleJsonUtil:checkBundleTypeInPackInfo pack.info has empty module."); return false; } String finalBundleType = "app"; String srcBundleType = "app"; if (finalAppObj.containsKey(BUNDLE_TYPE)) { finalBundleType = getJsonString(finalAppObj, BUNDLE_TYPE); } if (srcAppObj.containsKey(BUNDLE_TYPE)) { srcBundleType = getJsonString(srcAppObj, BUNDLE_TYPE); } if (!finalBundleType.equals(srcBundleType)) { LOG.error("bundleType in pack.info is not same."); return false; } return true; } /** * verify module in pack.info file. * * @param finalModuleObs is the final pack.info module objects * @param srcModuleObs is the src pack.info module objects * @return the result */ public static boolean verifyModuleInPackInfo(JSONArray finalModuleObs, JSONArray srcModuleObs) throws BundleException { if (finalModuleObs.isEmpty() || srcModuleObs.isEmpty()) { LOG.error("ModuleJsonUtil:verifyModuleInPackInfo pack.info has empty module."); throw new BundleException("ModuleJsonUtil:verifyModuleInPackInfo pack.info has empty module."); } List moduleNames = new ArrayList<>(); for (int i = 0; i < finalModuleObs.size(); ++i) { JSONObject finalModuleObj = finalModuleObs.getJSONObject(i); String moduleName = parseDistroModuleName(finalModuleObj); if (moduleNames.contains(moduleName)) { LOG.error("ModuleJsonUtil:verifyModuleInPackInfo duplicated moduleName."); return false; } else { moduleNames.add(moduleName); } } for (int i = 0; i < srcModuleObs.size(); ++i) { JSONObject srcModuleObj = srcModuleObs.getJSONObject(i); String moduleName = parseDistroModuleName(srcModuleObj); if (moduleNames.contains(moduleName)) { LOG.error("ModuleJsonUtil:verifyModuleInPackInfo duplicated moduleName."); return false; } else { moduleNames.add(moduleName); } } return true; } /** * verify package name in pack.info file. * * @param finalPackageObs is the final pack.info objects * @param srcPackageObs is the src pack.info objects * @return the result */ public static boolean verifyPackageName(JSONArray finalPackageObs, JSONArray srcPackageObs) { if (finalPackageObs == null || finalPackageObs.isEmpty() || srcPackageObs == null || srcPackageObs.isEmpty()) { LOG.error("ModuleJsonUtil:verifyPackageName pack.info has empty packages."); return false; } List packageNames = new ArrayList<>(); for (int i = 0; i < finalPackageObs.size(); ++i) { JSONObject packageObj = finalPackageObs.getJSONObject(i); String packageName = getJsonString(packageObj, NAME); if (packageNames.contains(packageName)) { LOG.error("ModuleJsonUtil:verifyPackageName duplicated package name."); return false; } else { packageNames.add(packageName); } } for (int i = 0; i < srcPackageObs.size(); ++i) { JSONObject packageObj = srcPackageObs.getJSONObject(i); String packageName = getJsonString(packageObj, NAME); if (packageNames.contains(packageName)) { LOG.error("ModuleJsonUtil:verifyPackageName duplicated package name."); return false; } else { packageNames.add(packageName); } } return true; } /** * parse moduleName in pack.info file. * * @param moduleObj is the final pack.info objects * @return the result */ public static String parseDistroModuleName(JSONObject moduleObj) throws BundleException { String moduleName = ""; try { if (moduleObj == null) { LOG.error("ModuleJsonUtil:parseFaModuleName failed: json file do not contain module."); throw new BundleException("ModuleJsonUtil:parseFaModuleName failed: json file do not contain module."); } JSONObject distroObj = moduleObj.getJSONObject(DISTRO); if (distroObj == null) { LOG.error("ModuleJsonUtil:parseFaModuleName failed: json file do not contain distro."); throw new BundleException("ModuleJsonUtil:parseFaModuleName failed: json file do not contain distro."); } if (!distroObj.containsKey(MODULE_NAME)) { LOG.error("ModuleJsonUtil:parseFaModuleName failed: json file do not contain moduleName."); throw new BundleException("ModuleJsonUtil:parseFaModuleName failed: json file do not contain moduleName."); } moduleName = getJsonString(distroObj, MODULE_NAME); } catch (BundleException e) { LOG.error("ModuleJsonUtil:parseFaModuleName failed!."); throw new BundleException("ModuleJsonUtil:parseFaModuleName failed."); } return moduleName; } /** * merge pack.info file. * * @param finalPackinfoObj is the final pack.info objects * @param srcPackinfoObj is the final pack.info objects * @return the result */ public static String mergePackInfoObj(JSONObject finalPackinfoObj, JSONObject srcPackinfoObj) throws BundleException { if (finalPackinfoObj == null || srcPackinfoObj == null) { String errMsg = "ModuleJsonUtil:mergePackInfoObj input an invalid json object."; LOG.error(errMsg); throw new BundleException(errMsg); } JSONObject finalSummaryObj = finalPackinfoObj.getJSONObject(SUMMARY); JSONObject srcSummaryObj = srcPackinfoObj.getJSONObject(SUMMARY); if (finalSummaryObj == null || srcSummaryObj == null) { String errMsg = "ModuleJsonUtil:mergePackInfoObj input json file has empty summary."; LOG.error(errMsg); throw new BundleException(errMsg); } // merge modules JSONArray finalModuleObs = finalSummaryObj.getJSONArray(MODULES); JSONArray srcModuleObs = srcSummaryObj.getJSONArray(MODULES); if (finalModuleObs == null || srcModuleObs == null) { String errMsg = "ModuleJsonUtil:mergePackInfoObj input json file has empty module."; LOG.error(errMsg); throw new BundleException(errMsg); } finalModuleObs.addAll(srcModuleObs); // merge packages JSONArray finalPackageObs = finalPackinfoObj.getJSONArray(PACKAGES); JSONArray srcPackageObs = srcPackinfoObj.getJSONArray(PACKAGES); if (finalPackageObs == null || srcPackageObs == null) { String errMsg = "ModuleJsonUtil:mergePackInfoObj input json file has empty packages."; LOG.error(errMsg); throw new BundleException(errMsg); } finalPackageObs.addAll(srcPackageObs); return finalPackinfoObj.toString(); } /** * merge two pack.info file into one pack.info file by packagePair. * * @param finalPackInfo is the final packInfo * @param srcPackInfo is the packInfo to be merged * @param packagePair is the selected packageName-moduleName pair map * @throws BundleException Throws this exception if the json is not standard. * @return the result */ public static String mergeTwoPackInfoByPackagePair(String finalPackInfo, String srcPackInfo, HashMap packagePair) throws BundleException { JSONObject finalPackObj; JSONObject srcPackObj; try { finalPackObj = JSON.parseObject(finalPackInfo); srcPackObj = JSON.parseObject(srcPackInfo); } catch (JSONException exception) { String errMsg = "parse JSONobject failed."; LOG.error(errMsg); throw new BundleException(errMsg); } // verify app in pack.info JSONObject finalSummaryObj = finalPackObj.getJSONObject(SUMMARY); JSONObject finalAppObj = finalSummaryObj.getJSONObject(APP); JSONObject srcSummaryObj = srcPackObj.getJSONObject(SUMMARY); JSONObject srcAppObj = srcSummaryObj.getJSONObject(APP); if (!verifyAppInPackInfo(finalAppObj, srcAppObj)) { String errMsg = "verify pack.info failed, different version, bundleType or bundleName."; LOG.error(errMsg); throw new BundleException(errMsg); } for (HashMap.Entry entry : packagePair.entrySet()) { String packageName = entry.getKey().substring(0, entry.getKey().lastIndexOf(DOT)); mergeTwoPackInfoObjByPackagePair(finalPackObj, srcPackObj, packageName, entry.getValue()); } return finalPackObj.toString(); } /** * merge two pack.info file into one pack.info file by packagePair. * * @param finalPackObj is the final packInfo * @param srcPackObj is the packInfo to be merged * @param packageName is the selected packageName * @param moduleName is the selected moduleName * @throws BundleException Throws this exception if the json is not standard. */ public static void mergeTwoPackInfoObjByPackagePair(JSONObject finalPackObj, JSONObject srcPackObj, String packageName, String moduleName) throws BundleException { if (finalPackObj == null || srcPackObj == null) { String errMsg = "ModuleJsonUtil:mergeTwoPackInfoObjByPackagePair failed: pack.info is not json object."; LOG.error(errMsg); throw new BundleException(errMsg); } // merge module JSONObject finalSummaryObj = finalPackObj.getJSONObject(SUMMARY); JSONObject srcSummaryObj = srcPackObj.getJSONObject(SUMMARY); if (finalSummaryObj == null || srcSummaryObj == null) { String errMsg = "ModuleJsonUtil:mergeTwoPackInfoObjByPackagePair failed: pack.info do not contain summary."; LOG.error(errMsg); throw new BundleException(errMsg); } JSONArray finalModules = finalSummaryObj.getJSONArray(MODULES); JSONArray srcModules = srcSummaryObj.getJSONArray(MODULES); if (finalModules == null || srcModules == null) { LOG.error("ModuleJsonUtil:mergeTwoPackInfoObjByPackagePair input json file has empty module."); throw new BundleException("ModuleJsonUtil:mergeTwoPackInfoObjByPackagePair input json file has empty module."); } boolean findModule = false; for (int index = 0; index < srcModules.size(); ++index) { JSONObject moduleObj = srcModules.getJSONObject(index); JSONObject distroObj = moduleObj.getJSONObject(DISTRO); if (getJsonString(distroObj, MODULE_NAME).equals(moduleName)) { finalModules.add(moduleObj); findModule = true; break; } } if (!findModule) { String errMsg = "ModuleJsonUtil:mergeTwoPackInfoObjByPackagePair" + " input json do not contain " + moduleName + "."; LOG.error(errMsg); throw new BundleException(errMsg); } // merge package JSONArray finalPackages = finalPackObj.getJSONArray(PACKAGES); JSONArray srcPackages = srcPackObj.getJSONArray(PACKAGES); if (finalPackages == null || srcPackages == null) { String errMsg = "ModuleJsonUtil:mergeTwoPackInfoObjByPackagePair failed: pack.info do not contain packages."; LOG.error(errMsg); throw new BundleException(errMsg); } boolean findPackage = false; for (int index = 0; index < srcPackages.size(); ++index) { JSONObject srcPackageObj = srcPackages.getJSONObject(index); if (getJsonString(srcPackageObj, NAME).equals(packageName)) { finalPackages.add(srcPackageObj); findPackage = true; break; } } if (!findPackage) { String errMsg = "ModuleJsonUtil:mergeTwoPackInfoObjByPackagePair input json do not contain " + packageName + "."; LOG.error(errMsg); throw new BundleException(errMsg); } } /** * parse FA hap is entry hap, if it is, return device type. * * @param hapPath is the path of hap. * * @throws BundleException FileNotFoundException|IOException. */ public static List parseFaEntry(String hapPath) throws BundleException { String configJson = FileUtils.getJsonInZips(new File(hapPath), CONFIG_JSON); JSONObject faObj; try { faObj = JSONObject.parseObject(configJson); } catch (JSONException exception) { String errMsg = "parse JSONobject failed."; LOG.error(errMsg); throw new BundleException(errMsg); } JSONObject moduleObj = faObj.getJSONObject(MODULE); if (moduleObj == null) { String errMSg = "ModuleJsonUtil::isFaEntry error, json do not contain module."; LOG.error(errMSg); throw new BundleException(errMSg); } List deviceTypes = new ArrayList<>(); JSONObject distroObj = moduleObj.getJSONObject(DISTRO); if (distroObj == null) { String errMSg = "ModuleJsonUtil::isFaEntry error, json do not contain distro."; LOG.error(errMSg); throw new BundleException(errMSg); } String moduleType = getJsonString(distroObj, MODULE_TYPE); if (ENTRY.equals(moduleType)) { deviceTypes = getDeviceTypeFromFAModule(moduleObj); } return deviceTypes; } /** * parse stage hap is entry hap, if it is, record device type. * * @param hapPath is the path of hap. * @throws BundleException FileNotFoundException|IOException. */ public static List parseStageEntry(String hapPath) throws BundleException { String moduleJson = FileUtils.getJsonInZips(new File(hapPath), MODULE_JSON); JSONObject stageObj; try { stageObj = JSONObject.parseObject(moduleJson); } catch (JSONException exception) { String errMsg = "parse JSONobject failed."; LOG.error(errMsg); throw new BundleException(errMsg); } JSONObject moduleObj = stageObj.getJSONObject(MODULE); if (moduleObj == null) { String errMSg = "ModuleJsonUtil::isFaEntry error, json do not contain module."; LOG.error(errMSg); throw new BundleException(errMSg); } List deviceTypes = new ArrayList<>(); String type = getJsonString(moduleObj, TYPE); if (type != null && type.equals(ENTRY)) { deviceTypes = getDeviceTypesFromStageModule(moduleObj); } return deviceTypes; } /** * get deviceType from fa module. * * @param moduleObj is the object of module. * @return true is for entry hap and false is other kind of hap */ public static List getDeviceTypeFromFAModule(JSONObject moduleObj) { List deviceTypes = new ArrayList<>(); if (moduleObj == null) { return deviceTypes; } deviceTypes = JSONObject.parseArray(getJsonString(moduleObj, DEVICE_TYPE), String.class); return deviceTypes; } /** * get deviceType from stage module. * * @param moduleObj is the object of module. * @return true is for entry hap and false is other kind of hap */ public static List getDeviceTypesFromStageModule(JSONObject moduleObj) { List deviceTypes = new ArrayList<>(); if (moduleObj == null) { return deviceTypes; } deviceTypes = JSONObject.parseArray(getJsonString(moduleObj, DEVICE_TYPES), String.class); return deviceTypes; } /** * check entry module must contain at least one ability. * * @param jsonString Indicates the jsonString. * @return Returns true if jsonString is valid. */ public static boolean checkEntryInAtomicService(String jsonString) throws BundleException { JSONObject jsonObject; try { jsonObject = JSON.parseObject(jsonString); } catch (JSONException exception) { LOG.error("parse JOSNObject failed in getStageApiReleaseType."); throw new BundleException("parse JOSNObject failed in getStageApiReleaseType."); } JSONObject moduleObj = jsonObject.getJSONObject(MODULE); if (moduleObj == null) { LOG.error("parse failed, input config.json is invalid, config.json has no module."); throw new BundleException("parse failed, input config.json is invalid, module.json has no app."); } JSONObject appObj = jsonObject.getJSONObject(APP); if (appObj == null) { LOG.error("parse failed, input config.json is invalid, module.json has no app."); throw new BundleException("parse failed, input config.json is invalid, module.json has no app."); } if (!parseStageBundleType(jsonString).equals(ATOMIC_SERVICE)) { return true; } if (parseModuleType(jsonString).equals(ENTRY) && parseAbilityNames(jsonString).isEmpty()) { LOG.error("entry module must contain at least one ability."); return false; } return true; } /** * parse stage module type. * * @param jsonString is the json String of module.json or config.json * @return is entry */ public static String parseModuleType(String jsonString) throws BundleException { JSONObject jsonObj; try { jsonObj = JSON.parseObject(jsonString); } catch (JSONException exception) { String errMsg = "parse JSONObject failed."; LOG.error(errMsg); throw new BundleException(errMsg); } if (jsonObj.containsKey(MODULE)) { JSONObject moduleObj = jsonObj.getJSONObject(MODULE); if (moduleObj.containsKey(TYPE)) { return getJsonString(moduleObj, TYPE); } } return EMPTY_STRING; } /** * parse stage hapVerifyInfo. * * @param hapVerifyInfo is the parse result * @throws BundleException Throws this exception if the json is not standard. */ public static void parseStageHapVerifyInfo(HapVerifyInfo hapVerifyInfo) throws BundleException { if (hapVerifyInfo.getProfileStr().isEmpty()) { throw new BundleException("ModuleJsonUtil::parseStageHapVerifyInfo failed, module.json is empty."); } String bundleName = parseBundleName(hapVerifyInfo.getProfileStr()); hapVerifyInfo.setBundleName(bundleName); hapVerifyInfo.setBundleType(parseStageBundleType(hapVerifyInfo.getProfileStr())); hapVerifyInfo.setVendor(parseVendor(hapVerifyInfo.getProfileStr())); hapVerifyInfo.setVersion(parseStageVersion(hapVerifyInfo.getProfileStr())); hapVerifyInfo.setApiVersion(parseStageModuleApiVersion(hapVerifyInfo.getProfileStr())); hapVerifyInfo.setModuleName(parseStageModuleName(hapVerifyInfo.getProfileStr())); List moduleMetadataInfos = parseModuleAllMetadata(hapVerifyInfo.getProfileStr(), hapVerifyInfo.getResourceMap()); hapVerifyInfo.setDistroFilter(parseStageDistroFilter(moduleMetadataInfos)); hapVerifyInfo.setDeviceType(parseDeviceType(hapVerifyInfo.getProfileStr())); hapVerifyInfo.setAbilityNames(parseAbilityNames(hapVerifyInfo.getProfileStr())); List extensionAbilityNames = parseExtensionAbilityName(hapVerifyInfo.getProfileStr()); hapVerifyInfo.addAbilityNames(extensionAbilityNames); hapVerifyInfo.setModuleType(parseStageIsEntry(hapVerifyInfo.getProfileStr())); hapVerifyInfo.setDependencyItemList(parseDependencies(hapVerifyInfo.getProfileStr(), bundleName)); hapVerifyInfo.setInstallationFree(parseStageInstallation(hapVerifyInfo.getProfileStr())); hapVerifyInfo.setPreloadItems(parseAtomicServicePreloads(hapVerifyInfo.getProfileStr())); } /** * parse FA hapVerifyInfo. * * @param hapVerifyInfo is the parse result * @throws BundleException Throws this exception if the json is not standard. */ public static void parseFAHapVerifyInfo(HapVerifyInfo hapVerifyInfo) throws BundleException { if (hapVerifyInfo.getProfileStr().isEmpty()) { LOG.error("ModuleJsonUtil::parseStageHapVerifyInfo failed, config.json is empty."); throw new BundleException("ModuleJsonUtil::parseStageHapVerifyInfo failed, config.json is empty."); } String bundleName = parseBundleName(hapVerifyInfo.getProfileStr()); hapVerifyInfo.setBundleName(parseBundleName(hapVerifyInfo.getProfileStr())); hapVerifyInfo.setVendor(parseVendor(hapVerifyInfo.getProfileStr())); hapVerifyInfo.setVersion(parseFaVersion(hapVerifyInfo.getProfileStr())); hapVerifyInfo.setApiVersion(parseFAModuleApiVersion(hapVerifyInfo.getProfileStr())); hapVerifyInfo.setModuleName(parseFaModuleName(hapVerifyInfo.getProfileStr())); hapVerifyInfo.setDistroFilter(parseFADistroFilter(hapVerifyInfo.getProfileStr())); hapVerifyInfo.setDeviceType(parseDeviceType(hapVerifyInfo.getProfileStr())); hapVerifyInfo.setAbilityNames(parseAbilityNames(hapVerifyInfo.getProfileStr())); hapVerifyInfo.setModuleType(parseFAIsEntry(hapVerifyInfo.getProfileStr())); hapVerifyInfo.setPackageName(parseFaPackageStr(hapVerifyInfo.getProfileStr())); hapVerifyInfo.setDependencyItemList(parseDependencies(hapVerifyInfo.getProfileStr(), bundleName)); hapVerifyInfo.setInstallationFree(parseFAInstallationFree(hapVerifyInfo.getProfileStr())); } /** * parse stage distroFilter. * * @param moduleMetadataInfos all metadata of module * @return DistroFilter is the result of parsed distroFilter */ public static DistroFilter parseStageDistroFilter( List moduleMetadataInfos) throws BundleException { DistroFilter distroFilter = new DistroFilter(); for (ModuleMetadataInfo moduleMetadataInfo : moduleMetadataInfos) { if (moduleMetadataInfo.resource.isEmpty()) { continue; } try { JSONObject distroFilterObj = JSON.parseObject(moduleMetadataInfo.resource); if (distroFilterObj.containsKey(DISTRO_FILTER)) { distroFilter = JSONObject.parseObject(getJsonString(distroFilterObj, DISTRO_FILTER), DistroFilter.class); } } catch (JSONException exception) { String errMsg = "parse JSONobject failed."; LOG.error(errMsg); throw new BundleException(errMsg); } } return distroFilter; } /** * parse stage parseModuleAllMetadata. * * @param jsonString is the string of module.json * @param profileJson is the of profile * @return DistroFilter is the result of parsed distroFilter */ public static List parseModuleAllMetadata( String jsonString, HashMap profileJson) throws BundleException { JSONObject jsonObject; try { jsonObject = JSON.parseObject(jsonString); } catch (JSONException exception) { String errMsg = "parse JSONobject failed."; LOG.error(errMsg); throw new BundleException(errMsg); } JSONObject moduleObj = jsonObject.getJSONObject(MODULE); if (moduleObj == null) { LOG.error("ModuleJsonUtil::parseModuleAllMetadata failed, module is null."); throw new BundleException("ModuleJsonUtil::parseModuleAllMetadata failed, module is null."); } List moduleMetadataInfos = new ArrayList<>(); if (moduleObj.containsKey(METADATA)) { JSONArray metadatas = moduleObj.getJSONArray(METADATA); for (int i = 0; i < metadatas.size(); ++i) { JSONObject metadata = metadatas.getJSONObject(i); moduleMetadataInfos.add(parseModuleMetadata(metadata, profileJson)); } } return moduleMetadataInfos; } /** * parse metadata info * * @param jsonObject Json hap json Object * @param profileJson is the of profile * @return the ModuleMetadataInfo result * @throws BundleException Throws this exception if the json is not standard. */ public static ModuleMetadataInfo parseModuleMetadata(JSONObject jsonObject, HashMap profileJson) throws BundleException { if (jsonObject == null) { throw new BundleException("ModuleJsonUtil::parseModuleMetadata failed, jsonObject is null."); } ModuleMetadataInfo moduleMetadataInfo = new ModuleMetadataInfo(); if (jsonObject.containsKey(NAME)) { moduleMetadataInfo.name = getJsonString(jsonObject, NAME); } if (jsonObject.containsKey(VALUE)) { moduleMetadataInfo.value = getJsonString(jsonObject, VALUE); } if (jsonObject.containsKey(RESOURCE)) { moduleMetadataInfo.resource = getJsonString(jsonObject, RESOURCE); String fileName = moduleMetadataInfo.resource; fileName = fileName.replace(PROFILE, ""); fileName = fileName + JSON_PERFIX; moduleMetadataInfo.resource = profileJson.get(fileName); } return moduleMetadataInfo; } /** * parse metadata info * * @param jsonString Json string of config.json * @return the ModuleMetadataInfo result */ public static DistroFilter parseFADistroFilter(String jsonString) throws BundleException { DistroFilter distroFilter = new DistroFilter(); JSONObject jsonObj; try { jsonObj = JSON.parseObject(jsonString); if (jsonObj.containsKey(MODULE)) { JSONObject moduleObj = jsonObj.getJSONObject(MODULE); if (moduleObj.containsKey(DISTRO_FILTER)) { distroFilter = JSONObject.parseObject(getJsonString(moduleObj, DISTRO_FILTER), DistroFilter.class); } } } catch (JSONException exception) { String errMsg = "parse JSONobject failed."; LOG.error(errMsg); throw new BundleException(errMsg); } return distroFilter; } /** * get deviceType from json file. * * @param jsonString is the json String of module.json or config.json */ public static List parseDeviceType(String jsonString) throws BundleException { JSONObject jsonObj; try { jsonObj = JSON.parseObject(jsonString); } catch (JSONException exception) { String errMsg = "parse JSONobject failed."; LOG.error(errMsg); throw new BundleException(errMsg); } List deviceType = new ArrayList<>(); if (jsonObj.containsKey(MODULE)) { JSONObject moduleObj = jsonObj.getJSONObject(MODULE); if (moduleObj.containsKey(DEVICE_TYPE)) { return JSONObject.parseArray(getJsonString(moduleObj, DEVICE_TYPE), String.class); } else if (moduleObj.containsKey(DEVICE_TYPES)) { return JSONObject.parseArray(getJsonString(moduleObj, DEVICE_TYPES), String.class); } else { return deviceType; } } return deviceType; } /** * get ability names from json file. * * @param jsonString is the json String of module.json or config.json * @return ability names */ public static List parseAbilityNames(String jsonString) throws BundleException { JSONObject jsonObj; try { jsonObj = JSON.parseObject(jsonString); } catch (JSONException exception) { String errMsg = "parse JSONobject failed."; LOG.error(errMsg); throw new BundleException(errMsg); } List abilityNames = new ArrayList<>(); JSONObject moduleObj = jsonObj.getJSONObject(MODULE); if (moduleObj != null && moduleObj.containsKey(ABILITIES)) { JSONArray abilityObjs = moduleObj.getJSONArray(ABILITIES); for (int i = 0; i < abilityObjs.size(); ++i) { JSONObject abilityObj = abilityObjs.getJSONObject(i); if (abilityObj.containsKey(NAME)) { abilityNames.add(getJsonString(abilityObj, NAME)); } } } return abilityNames; } /** * parse stage ExtensionAbility names * * @param jsonString is the json String of module.json * @return extensionAbilityNames */ public static List parseExtensionAbilityName(String jsonString) throws BundleException { JSONObject jsonObj; try { jsonObj = JSON.parseObject(jsonString); } catch (JSONException exception) { String errMsg = "parse JSONobject failed."; LOG.error(errMsg); throw new BundleException(errMsg); } JSONObject moduleObj = jsonObj.getJSONObject(MODULE); if (moduleObj == null) { LOG.error("ModuleJsonUtil::parseExtensionAbilityName failed, module is null."); throw new BundleException("ModuleJsonUtil::parseExtensionAbilityName failed, module is null."); } List extensionAbilityNames = new ArrayList<>(); if (moduleObj.containsKey(EXTENSION_ABILITIES)) { JSONArray extensionAbilityObjs = moduleObj.getJSONArray(EXTENSION_ABILITIES); for (int i = 0; i < extensionAbilityObjs.size(); ++i) { JSONObject extensionAbilityObj = extensionAbilityObjs.getJSONObject(i); if (extensionAbilityObj.containsKey(NAME)) { extensionAbilityNames.add(getJsonString(extensionAbilityObj, NAME)); } } } return extensionAbilityNames; } /** * parse stage module type. * * @param jsonString is the json String of module.json or config.json * @return is entry */ public static String parseStageIsEntry(String jsonString) throws BundleException { JSONObject jsonObj; try { jsonObj = JSON.parseObject(jsonString); } catch (JSONException exception) { String errMsg = "parse JSONobject failed."; LOG.error(errMsg); throw new BundleException(errMsg); } if (jsonObj.containsKey(MODULE)) { JSONObject moduleObj = jsonObj.getJSONObject(MODULE); if (moduleObj.containsKey(TYPE)) { return getJsonString(moduleObj, TYPE); } } return EMPTY_STRING; } /** * parse FA module type. * * @param jsonString is the json String of module.json or config.json * @return is entry */ public static String parseFAIsEntry(String jsonString) throws BundleException { JSONObject jsonObj; try { jsonObj = JSON.parseObject(jsonString); } catch (JSONException exception) { String errMsg = "parse JSONobject failed."; LOG.error(errMsg); throw new BundleException(errMsg); } if (jsonObj.containsKey(MODULE)) { JSONObject moduleObj = jsonObj.getJSONObject(MODULE); if (moduleObj.containsKey(DISTRO)) { JSONObject distroObj = moduleObj.getJSONObject(DISTRO); if (distroObj.containsKey(MODULE_TYPE)) { return getJsonString(distroObj, MODULE_TYPE); } } } return EMPTY_STRING; } /** * parse dependencies form json string. * * @param jsonString is the json String of module.json or config.json * @return dependencies */ static List parseDependencies(String jsonString, String bundleName) throws BundleException { JSONObject jsonObj; try { jsonObj = JSON.parseObject(jsonString); } catch (JSONException exception) { String errMsg = "parse json object failed!"; LOG.error(errMsg); throw new BundleException(errMsg); } JSONObject moduleObj = jsonObj.getJSONObject(MODULE); if (moduleObj == null) { LOG.error("parseDependencies failed: lack of module object."); throw new BundleException("parseDependencies failed: lack of module object."); } List dependencyItemList = new ArrayList<>(); if (!moduleObj.containsKey(DEPENDENCIES)) { return dependencyItemList; } JSONArray dependencyObjList = moduleObj.getJSONArray(DEPENDENCIES); for (int i = 0; i < dependencyObjList.size(); ++i) { JSONObject object = dependencyObjList.getJSONObject(i); DependencyItem item = new DependencyItem(); if (object.containsKey(BUNDLE_NAME)) { item.setBundleName(getJsonString(object, BUNDLE_NAME)); } else { item.setBundleName(bundleName); } if (object.containsKey(MODULE_NAME)) { item.setModuleName(getJsonString(object, MODULE_NAME)); } dependencyItemList.add(item); } return dependencyItemList; } static String parseStageBundleType(String jsonString) throws BundleException { JSONObject jsonObject; try { jsonObject = JSON.parseObject(jsonString); } catch (JSONException exception) { LOG.error("parse JOSNObject failed in getStageAsanEnabled."); throw new BundleException("parse JOSNObject failed in getStageAsanEnabled."); } JSONObject appObj = jsonObject.getJSONObject(APP); if (appObj == null) { LOG.error("parse failed, input module.json is invalid, module.json has no app."); throw new BundleException("parse failed, input module.json is invalid, module.json has no app."); } JSONObject moduleObj = jsonObject.getJSONObject(MODULE); if (moduleObj == null) { LOG.error("parse failed, input module.json is invalid, module.json has no module."); throw new BundleException("parse failed, input module.json is invalid, module.json has no module."); } boolean installationFree = getJsonBooleanValue(moduleObj, INSTALLATION_FREE, false); if (!appObj.containsKey(BUNDLE_TYPE)) { if (installationFree) { String errMessage = "The app.json5 file configuration does not match the installationFree:" + " true settings. Add the bundleType field to the app.json5 file and set it atomicService."; LOG.error(errMessage); throw new BundleException(errMessage); } return APP; } else { String bundleType = getJsonString(appObj, BUNDLE_TYPE); if (bundleType.equals(APP)) { if (installationFree) { LOG.error("installationFree must be false when bundleType is app."); throw new BundleException("installationFree must be false when bundleType is app."); } return APP; } else if (bundleType.equals(ATOMIC_SERVICE)) { if (!installationFree) { LOG.error("installationFree must be true when bundleType is atomicService."); throw new BundleException("installationFree must be true when bundleType is atomicService."); } return ATOMIC_SERVICE; } else { LOG.error("bundleType is invalid in app.json."); throw new BundleException("bundleType is invalid in app.json."); } } } static boolean parseStageInstallation(String jsonString) throws BundleException { JSONObject jsonObj; try { jsonObj = JSON.parseObject(jsonString); } catch (JSONException exception) { String errMsg = "parse JSONobject failed."; LOG.error(errMsg); throw new BundleException(errMsg); } JSONObject moduleObj = jsonObj.getJSONObject(MODULE); if (moduleObj == null) { LOG.error("ModuleJsonUtil::parseStageInstallation json do not contain module."); throw new BundleException("ModuleJsonUtil::parseStageInstallation json do not contain module."); } if (moduleObj.containsKey(INSTALLATION_FREE)) { return moduleObj.getBoolean(INSTALLATION_FREE); } return false; } static List parseAtomicServicePreloads(String jsonString) throws BundleException { List preloadItems = new ArrayList<>(); JSONObject jsonObject; try { jsonObject = JSON.parseObject(jsonString); } catch (JSONException exception) { LOG.error("parse JOSNObject failed in getStageAsanEnabled."); throw new BundleException("parse JOSNObject failed in getStageAsanEnabled."); } JSONObject moduleObj = jsonObject.getJSONObject(MODULE); JSONObject atomicServiceObj = null; if (!moduleObj.containsKey(ATOMIC_SERVICE)) { return preloadItems; } atomicServiceObj = moduleObj.getJSONObject(ATOMIC_SERVICE); if (!atomicServiceObj.containsKey(PRELOADS)) { return preloadItems; } JSONArray preloadObjs = atomicServiceObj.getJSONArray(PRELOADS); for (int i = 0; i < preloadObjs.size(); ++i) { PreloadItem preloadItem = new PreloadItem(); JSONObject itemObj = preloadObjs.getJSONObject(i); if (itemObj.containsKey(MODULE_NAME)) { preloadItem.setModuleName(getJsonString(itemObj, MODULE_NAME)); } preloadItems.add(preloadItem); } return preloadItems; } static boolean parseFAInstallationFree(String jsonString) throws BundleException { JSONObject jsonObject; try { jsonObject = JSON.parseObject(jsonString); } catch (JSONException exception) { String errMsg = "parse JSONobject failed."; LOG.error(errMsg); throw new BundleException(errMsg); } JSONObject moduleObj = jsonObject.getJSONObject(MODULE); if (moduleObj == null) { LOG.error("ModuleJsonUtil::parseStageInstallation json do not contain module."); throw new BundleException("ModuleJsonUtil::parseStageInstallation json do not contain module."); } JSONObject distroObj = moduleObj.getJSONObject(DISTRO); if (distroObj == null) { LOG.error("ModuleJsonUtil::parseStageInstallation json do not contain distro."); throw new BundleException("ModuleJsonUtil::parseStageInstallation json do not contain distro."); } if (distroObj.containsKey(INSTALLATION_FREE)) { return distroObj.getBoolean(INSTALLATION_FREE); } return false; } /** * get hqfVerifyINfo from hqf file * * @param hqfPath is the file path of hqf file * @return HQFVerifyInfo */ static HQFInfo parseHQFInfo(String hqfPath) throws BundleException { File hqfFile = new File(hqfPath); String patchJson = FileUtils.getJsonInZips(hqfFile, PATCH_JSON); return parsePatch(patchJson); } /** * parse patch.json form json string. * * @param jsonString is the file path of hqf file * @return HQFVerifyInfo */ static HQFInfo parsePatch(String jsonString) throws BundleException { JSONObject jsonObject; try { jsonObject = JSON.parseObject(jsonString); } catch (JSONException exception) { String errMsg = "parse JSONobject failed."; LOG.error(errMsg); throw new BundleException(errMsg); } JSONObject appObj = jsonObject.getJSONObject(APP); if (appObj == null) { LOG.error("Error: parsePatch failed, input patch.json is invalid, patch.json has no app."); throw new BundleException("Error: parsePatch failed, input patch.json is invalid."); } HQFInfo hqfVerifyInfo = new HQFInfo(); if (appObj.containsKey(BUNDLE_NAME)) { hqfVerifyInfo.setBundleName(getJsonString(appObj, BUNDLE_NAME)); } if (appObj.containsKey(VERSIONCODE)) { hqfVerifyInfo.setVersionCode(getJsonIntValue(appObj, VERSIONCODE)); } if (appObj.containsKey(VERSIONNAME)) { hqfVerifyInfo.setVersionName(getJsonString(appObj, VERSIONNAME)); } if (appObj.containsKey(PATCH_VERSION_CODE)) { hqfVerifyInfo.setPatchVersionCode(getJsonIntValue(appObj, PATCH_VERSION_CODE)); } if (appObj.containsKey(PATCH_VERSION_NAME)) { hqfVerifyInfo.setPatchVersionName(getJsonString(appObj, PATCH_VERSION_NAME)); } JSONObject moduleObj = jsonObject.getJSONObject(MODULE); if (moduleObj == null) { LOG.error("Error: parse failed, input patch.json is invalid, patch.json has no module."); throw new BundleException("Error: parse failed, input patch.json is invalid, patch.json has no module."); } if (moduleObj.containsKey(NAME)) { hqfVerifyInfo.setModuleName(getJsonString(moduleObj, NAME)); } if (moduleObj.containsKey(TYPE)) { hqfVerifyInfo.setType(getJsonString(moduleObj, TYPE)); } if (moduleObj.containsKey(DEVICE_TYPES)) { hqfVerifyInfo.setDeviceTypes(JSONObject.parseArray(getJsonString(moduleObj, DEVICE_TYPES), String.class)); } if (moduleObj.containsKey(ORIGINAL_MODULE_HASH)) { hqfVerifyInfo.setOriginalModuleHash(getJsonString(moduleObj, ORIGINAL_MODULE_HASH)); } return hqfVerifyInfo; } /** * get asanEnabled in module.json * * @param jsonString is the file content of module.json * @return the value of asanEnabled */ public static boolean getStageAsanEnabled(String jsonString) throws BundleException { JSONObject jsonObject; try { jsonObject = JSON.parseObject(jsonString); } catch (JSONException exception) { LOG.error("Error: parse JOSNObject failed in getStageAsanEnabled."); throw new BundleException("parse JOSNObject failed in getStageAsanEnabled."); } JSONObject appObj = jsonObject.getJSONObject(APP); if (appObj == null) { LOG.error("Error: parse failed, input module.json is invalid, module.json has no app."); throw new BundleException("Error: parse failed, input module.json is invalid, module.json has no app."); } if (appObj.containsKey(ASAN_ENABLED)) { return appObj.getBoolean(ASAN_ENABLED); } return false; } /** * get asanEnabled in module.json * * @param jsonString is the file content of module.json * @return the result */ public static String getStageApiReleaseType(String jsonString) throws BundleException { JSONObject jsonObject; try { jsonObject = JSON.parseObject(jsonString); } catch (JSONException exception) { LOG.error("Error: parse JOSNObject failed in getStageApiReleaseType."); throw new BundleException("parse JOSNObject failed in getStageApiReleaseType."); } JSONObject appObj = jsonObject.getJSONObject(APP); if (appObj == null) { LOG.error("Error: parse failed, input module.json is invalid, module.json has no app."); throw new BundleException("Error: parse failed, input module.json is invalid, module.json has no app."); } return getJsonString(appObj, API_RELEASE_TYPE); } /** * get debug in module.json * * @param jsonString is the file content of module.json * @return the result */ public static boolean getDebug(String jsonString) throws BundleException { JSONObject jsonObject; try { jsonObject = JSON.parseObject(jsonString); } catch (JSONException exception) { LOG.error("parse JOSNObject failed in getStageApiReleaseType."); throw new BundleException("parse JOSNObject failed in getStageApiReleaseType."); } JSONObject appObj = jsonObject.getJSONObject(APP); if (appObj == null) { LOG.error("parse failed, input module.json is invalid, module.json has no app."); throw new BundleException("parse failed, input module.json is invalid, module.json has no app."); } return getJsonBooleanValue(appObj, DEBUG, false); } /** * get debug in config.json * * @param jsonString is the file content of module.json * @return the result */ public static boolean getFADebug(String jsonString) throws BundleException { JSONObject jsonObject; try { jsonObject = JSON.parseObject(jsonString); } catch (JSONException exception) { LOG.error("parse JOSNObject failed in getStageApiReleaseType."); throw new BundleException("parse JOSNObject failed in getStageApiReleaseType."); } JSONObject deviceConfigObj = jsonObject.getJSONObject(DEVICE_CONFIG); if (deviceConfigObj == null) { return false; } JSONObject defaultObj = deviceConfigObj.getJSONObject(DEFAULT); if (defaultObj == null) { return false; } return getJsonBooleanValue(defaultObj, DEBUG, false); } /** * get asanEnabled in config.json * * @param jsonString is the file content of module.json * @return the value of asanEnabled */ public static boolean getFAAsanEnabled(String jsonString) throws BundleException { JSONObject jsonObject; try { jsonObject = JSON.parseObject(jsonString); } catch (JSONException exception) { LOG.error("Error: parse JOSNObject failed in getStageAsanEnabled."); throw new BundleException("parse JOSNObject failed in getStageAsanEnabled."); } JSONObject appObj = jsonObject.getJSONObject(APP); if (appObj == null) { LOG.error("Error: parse failed, input module.json is invalid, module.json has no app."); throw new BundleException("Error: parse failed, input module.json is invalid, module.json has no app."); } if (appObj.containsKey(ASAN_ENABLED)) { return appObj.getBoolean(ASAN_ENABLED); } return false; } /** * get releaseType in config.json * * @param jsonString is the file content of config.json * @return the result */ public static String getFAReleaseType(String jsonString) throws BundleException { JSONObject jsonObject; try { jsonObject = JSON.parseObject(jsonString); } catch (JSONException exception) { LOG.error("Error: parse JOSNObject failed in getStageApiReleaseType."); throw new BundleException("parse JOSNObject failed in getStageApiReleaseType."); } JSONObject appObj = jsonObject.getJSONObject(APP); if (appObj == null) { LOG.error("Error: parse failed, input config.json is invalid, config.json has no app."); throw new BundleException("Error: parse failed, input config.json is invalid, config.json has no app."); } JSONObject apiVersionObj = appObj.getJSONObject(API_VERSION); if (apiVersionObj == null) { return ""; } return getJsonString(apiVersionObj, RELEASE_TYPE); } /** * check module atomic service is valid * @param jsonString is the file content of config.json * @return the result */ public static boolean isModuleAtomicServiceValid(String jsonString) throws BundleException { JSONObject jsonObject; try { jsonObject = JSON.parseObject(jsonString); } catch (JSONException exception) { LOG.error("parse JOSNObject failed in getStageApiReleaseType."); throw new BundleException("parse JOSNObject failed in getStageApiReleaseType."); } JSONObject moduleObj = jsonObject.getJSONObject(MODULE); if (moduleObj == null) { LOG.error("parse failed, input config.json is invalid, config.json has no module."); throw new BundleException("parse failed, input config.json is invalid, module.json has no app."); } if (!moduleObj.containsKey(ATOMIC_SERVICE)) { return true; } JSONObject appObj = jsonObject.getJSONObject(APP); if (appObj == null) { LOG.error("parse failed, input config.json is invalid, module.json has no app."); throw new BundleException("parse failed, input config.json is invalid, module.json has no app."); } if (moduleObj.containsKey(ATOMIC_SERVICE) && (!appObj.containsKey(BUNDLE_TYPE) || !getJsonString(appObj, BUNDLE_TYPE).equals(ATOMIC_SERVICE))) { LOG.error("module can not config atomicService when bundleType is not atomicService."); return false; } return true; } /** * check module atomic installation free is valid * @param jsonString is the file content of config.json * @return the result */ public static boolean checkAtomicServiceInstallationFree(String jsonString) throws BundleException { JSONObject jsonObject; try { jsonObject = JSON.parseObject(jsonString); } catch (JSONException exception) { LOG.error("parse JOSNObject failed in getStageApiReleaseType."); throw new BundleException("parse JOSNObject failed in getStageApiReleaseType."); } JSONObject moduleObj = jsonObject.getJSONObject(MODULE); if (moduleObj == null) { LOG.error("parse failed, input config.json is invalid, config.json has no module."); throw new BundleException("parse failed, input config.json is invalid, module.json has no app."); } JSONObject appObj = jsonObject.getJSONObject(APP); if (appObj == null) { LOG.error("parse failed, input config.json is invalid, module.json has no app."); throw new BundleException("parse failed, input config.json is invalid, module.json has no app."); } boolean installationFree = getJsonBooleanValue(moduleObj, INSTALLATION_FREE, false); if (!appObj.containsKey(BUNDLE_TYPE)) { if (installationFree) { String errMessage = "The app.json5 file configuration does not match the installationFree:" + " true settings. Add the bundleType field to the app.json5 file and set it atomicService."; LOG.error(errMessage); return false; } return true; } String bundleType = getJsonString(appObj, BUNDLE_TYPE); if (bundleType.equals(APP)) { if (installationFree) { LOG.error("installationFree must be false when bundleType is app."); return false; } } else if (bundleType.equals(ATOMIC_SERVICE)) { if (!installationFree) { LOG.error("installationFree must be true when bundleType is atomicService."); return false; } } else { LOG.error("bundleType is invalid in app.json."); return false; } return true; } /** * get the String from JSONObject by the key. * * @param jsonObject uncompress json object * @param key value key * @return the result */ private static String getJsonString(JSONObject jsonObject, String key) { String value = ""; if (jsonObject != null && jsonObject.containsKey(key)) { value = jsonObject.get(key).toString(); } return value; } private static boolean getJsonBooleanValue(JSONObject jsonObject, String key, boolean defaultValue) { boolean value = defaultValue; if (jsonObject != null && jsonObject.containsKey(key)) { value = jsonObject.getBooleanValue(key); } return value; } /** * get the int from JSONObject by the key. * * @param jsonObject uncompress json object * @param key value key * @return the result */ private static int getJsonIntValue(JSONObject jsonObject, String key) { int value = 0; if (jsonObject != null && jsonObject.containsKey(key)) { value = jsonObject.getIntValue(key); } return value; } }