From 1687f13ea7739270076fefb5d11da9f787dfa156 Mon Sep 17 00:00:00 2001 From: lanhaoyu Date: Fri, 25 Apr 2025 09:38:39 +0800 Subject: [PATCH] add general java Signed-off-by: lanhaoyu --- adapter/ohos/CommandParser.java | 85 ++++- adapter/ohos/CompressVerify.java | 155 +++++++++- adapter/ohos/Compressor.java | 460 +++++++++++++++++++++++++++- adapter/ohos/PackingToolErrMsg.java | 10 + adapter/ohos/Utility.java | 86 +++++- 5 files changed, 787 insertions(+), 9 deletions(-) diff --git a/adapter/ohos/CommandParser.java b/adapter/ohos/CommandParser.java index 59865bab..19615008 100644 --- a/adapter/ohos/CommandParser.java +++ b/adapter/ohos/CommandParser.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2023 Huawei Device Co., Ltd. + * Copyright (c) 2021-2025 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 @@ -90,6 +90,25 @@ public class CommandParser { private static final String VERSION_CODE = "--version-code"; private static final String VERSION_NAME = "--version-name"; private static final String INPUT_LIST = "--input-list"; + private static final String PARAM_DEVICE_TYPES = "--device-types"; + private static final String PARAM_MIN_COMPATIBLE_VERSION_CODE = "--min-compatible-version-code"; + private static final String PARAM_MIN_API_VERSION = "--min-api-version"; + private static final String PARAM_TARGET_API_VERSION = "--target-api-version"; + private static final String PARAM_API_RELEASE_TYPE = "--api-release-type"; + private static final String PARAM_BUNDLE_TYPE = "--bundle-type"; + private static final String PARAM_INSTALLATION_FREE = "--installation-free"; + private static final String PARAM_DELIVERY_WITH_INSTALL = "--delivery-with-install"; + private static final String VERSION_CODE_PARAM = "versionCode"; + private static final String VERSION_NAME_PARAM = "versionName"; + private static final String DEVICE_TYPES_PARAM = "deviceTypes"; + private static final String BUNDLE_NAME_PARAM = "bundleName"; + private static final String MIN_COMPATIBLE_VERSION_CODE_PARAM = "minCompatibleVersionCode"; + private static final String MIN_API_VERSION_PARAM = "minAPIVersion"; + private static final String TARGET_API_VERSION_PARAM = "targetAPIVersion"; + private static final String API_RELEASE_TYPE_PARAM = "apiReleaseType"; + private static final String BUNDLE_TYPE_PARAM = "bundleType"; + private static final String INSTALLATION_FREE_PARAM = "installationFree"; + private static final String DELIVERY_WITH_INSTALL_PARAM = "deliveryWithInstall"; private static final String INPUT = "--input"; private static final String STAT_DUPLICATE = "--stat-duplicate"; private static final String STAT_SUFFIX = "--stat-suffix"; @@ -317,15 +336,17 @@ public class CommandParser { commandFuncs.put(VERSION_CODE, entry -> { try { entry.getKey().setVersionCode(Integer.parseInt(entry.getValue())); + entry.getKey().addGeneralNormalizeList(VERSION_CODE_PARAM); } catch (NumberFormatException ignored) { LOG.error(PackingToolErrMsg.COMMAND_PARSER_FAILED.toString( - "--version-code value must be number.")); + "--version-code value is not number or invalid.")); return false; } return true; }); commandFuncs.put(VERSION_NAME, entry -> { entry.getKey().setVersionName(entry.getValue()); + entry.getKey().addGeneralNormalizeList(VERSION_NAME_PARAM); return true; }); commandFuncs.put(INPUT_LIST, entry -> { @@ -382,11 +403,69 @@ public class CommandParser { }); commandFuncs.put(CMD_BUNDLE_NAME, entry -> { entry.getKey().setBundleName(entry.getValue()); + entry.getKey().addGeneralNormalizeList(BUNDLE_NAME_PARAM); + return true; + }); + commandFuncs.put(PARAM_DEVICE_TYPES, entry -> { + entry.getKey().setDeviceTypes(entry.getValue()); + entry.getKey().addGeneralNormalizeList(DEVICE_TYPES_PARAM); + return true; + }); + commandFuncs.put(PARAM_MIN_COMPATIBLE_VERSION_CODE, entry -> { + try { + entry.getKey().setMinCompatibleVersionCode(Integer.parseInt(entry.getValue())); + entry.getKey().addGeneralNormalizeList(MIN_COMPATIBLE_VERSION_CODE_PARAM); + } catch (NumberFormatException ignored) { + LOG.error(PackingToolErrMsg.COMMAND_PARSER_FAILED.toString( + "--min-compatible-version-code value is not number or invalid.")); + return false; + } + return true; + }); + commandFuncs.put(PARAM_MIN_API_VERSION, entry -> { + try { + entry.getKey().setMinAPIVersion(Integer.parseInt(entry.getValue())); + entry.getKey().addGeneralNormalizeList(MIN_API_VERSION_PARAM); + } catch (NumberFormatException ignored) { + LOG.error(PackingToolErrMsg.COMMAND_PARSER_FAILED.toString( + "--min-api-version value is not number or invalid.")); + return false; + } + return true; + }); + commandFuncs.put(PARAM_TARGET_API_VERSION, entry -> { + try { + entry.getKey().setTargetAPIVersion(Integer.parseInt(entry.getValue())); + entry.getKey().addGeneralNormalizeList(TARGET_API_VERSION_PARAM); + } catch (NumberFormatException ignored) { + LOG.error(PackingToolErrMsg.COMMAND_PARSER_FAILED.toString( + "--target-api-version value is not number or invalid.")); + return false; + } + return true; + }); + commandFuncs.put(PARAM_API_RELEASE_TYPE, entry -> { + entry.getKey().setApiReleaseType(entry.getValue()); + entry.getKey().addGeneralNormalizeList(API_RELEASE_TYPE_PARAM); + return true; + }); + commandFuncs.put(PARAM_BUNDLE_TYPE, entry -> { + entry.getKey().setBundleType(entry.getValue()); + entry.getKey().addGeneralNormalizeList(BUNDLE_TYPE_PARAM); + return true; + }); + commandFuncs.put(PARAM_INSTALLATION_FREE, entry -> { + entry.getKey().setInstallationFree(entry.getValue()); + entry.getKey().addGeneralNormalizeList(INSTALLATION_FREE_PARAM); + return true; + }); + commandFuncs.put(PARAM_DELIVERY_WITH_INSTALL, entry -> { + entry.getKey().setDeliveryWithInstall(entry.getValue()); + entry.getKey().addGeneralNormalizeList(DELIVERY_WITH_INSTALL_PARAM); return true; }); } - /** * judge args is null and enter parser. * diff --git a/adapter/ohos/CompressVerify.java b/adapter/ohos/CompressVerify.java index c6eeb608..1bdd37d6 100644 --- a/adapter/ohos/CompressVerify.java +++ b/adapter/ohos/CompressVerify.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2021-2025 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 @@ -24,6 +24,7 @@ import java.io.IOException; import java.io.Reader; import java.nio.charset.StandardCharsets; import java.util.ArrayList; +import java.util.Arrays; import java.util.Locale; import java.util.Map; import java.util.regex.Matcher; @@ -76,7 +77,25 @@ public class CompressVerify { "([a-zA-Z]|[a-zA-Z]+(_*[0-9a-zA-Z])+)(\\.[0-9a-zA-Z]|\\.[0-9a-zA-Z]+(_*[0-9a-zA-Z])+){2,}"; private static final int BUNDLE_NAME_LEN_MIN = 7; private static final int BUNDLE_NAME_LEN_MAX = 128; - + private static final int MAX_LENGTH = 127; + private static final int MINI_NUM = 0; + private static final int MAXI_NUM = 2147483647; + private static final String API_RELEASE_TYPE_PATTERN = "^(Canary[1-9]\\d*)|(Beta[1-9]\\d*)|(Release[1-9]\\d*)$"; + private static final String VERSION_CODE = "versionCode"; + private static final String VERSION_NAME = "versionName"; + private static final String DEVICE_TYPES = "deviceTypes"; + private static final String BUNDLE_NAME = "bundleName"; + private static final String MIN_COMPATIBLE_VERSION_CODE = "minCompatibleVersionCode"; + 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 BUNDLE_TYPE = "bundleType"; + private static final String INSTALLATION_FREE = "installationFree"; + private static final String DELIVERY_WITH_INSTALL = "deliveryWithInstall"; + private static final List bundleTypeList = + Arrays.asList("app", "atomicService", "shared", "appService", "appPlugin"); + private static final List deviceTypeList = + Arrays.asList("default", "tablet", "tv", "wearable", "car", "2in1"); private static final Log LOG = new Log(CompressVerify.class.toString()); private static final boolean TYPE_FILE = true; @@ -140,6 +159,8 @@ public class CompressVerify { return validateVersionNormalizeMode(utility); case Utility.PACKAGE_NORMALIZE: return validatePackageNormalizeMode(utility); + case Utility.GENERAL_NORMALIZE: + return validateGeneralNormalizeMode(utility); default: LOG.error(PackingToolErrMsg.COMMAND_MODE_INVALID.toString()); return false; @@ -246,6 +267,136 @@ public class CompressVerify { return true; } + private static boolean validateGeneralNormalizeMode(Utility utility) { + if (utility.getInputList().isEmpty()) { + String errMsg = "--input-list is empty."; + LOG.error(PackingToolErrMsg.GENERAL_NORMALIZE_MODE_ARGS_INVALID.toString(errMsg)); + return false; + } + + if (!handleHapAndHspInput(utility, utility.getInputList(), utility.getFormattedHapList())) { + String errMsg = "--input-list is invalid."; + LOG.error(PackingToolErrMsg.GENERAL_NORMALIZE_MODE_ARGS_INVALID.toString(errMsg)); + return false; + } + + if (utility.getFormattedHapList().isEmpty()) { + String errMsg = "--input-list is empty."; + LOG.error(PackingToolErrMsg.GENERAL_NORMALIZE_MODE_ARGS_INVALID.toString(errMsg)); + return false; + } + + if (utility.getGeneralNormalizeList().contains(DEVICE_TYPES)) { + String[] types = utility.getDeviceTypes().split(","); + for (String type : types) { + if (!deviceTypeList.contains(type)) { + String errMsg = "--device-types is invalid."; + LOG.error(PackingToolErrMsg.GENERAL_NORMALIZE_MODE_ARGS_INVALID.toString(errMsg)); + return false; + } + } + } + + if (utility.getGeneralNormalizeList().contains(VERSION_CODE)) { + if (utility.getVersionCode() < MINI_NUM || utility.getVersionCode() > MAXI_NUM) { + String errMsg = "--version-code is invalid."; + LOG.error(PackingToolErrMsg.GENERAL_NORMALIZE_MODE_ARGS_INVALID.toString(errMsg)); + return false; + } + } + + if (utility.getGeneralNormalizeList().contains(VERSION_NAME)) { + Pattern versionNamePattern = Pattern.compile(VERSION_NAME_PATTERN); + Matcher versionNameMatcher = versionNamePattern.matcher(utility.getVersionName()); + if (!versionNameMatcher.matches() || utility.getVersionName().length() > MAX_LENGTH) { + String errMsg = "--version-name is invalid."; + LOG.error(PackingToolErrMsg.GENERAL_NORMALIZE_MODE_ARGS_INVALID.toString(errMsg)); + return false; + } + } + + if (utility.getGeneralNormalizeList().contains(BUNDLE_NAME)) { + if (!isBundleNameValid(utility.getBundleName())) { + String errMsg = "--bundle-name is invalid."; + LOG.error(PackingToolErrMsg.GENERAL_NORMALIZE_MODE_ARGS_INVALID.toString(errMsg)); + return false; + } + } + + if (utility.getGeneralNormalizeList().contains(MIN_COMPATIBLE_VERSION_CODE)) { + if (utility.getMinCompatibleVersionCode() < MINI_NUM || utility.getMinCompatibleVersionCode() > MAXI_NUM) { + String errMsg = "--min-compatible-version-code is invalid."; + LOG.error(PackingToolErrMsg.GENERAL_NORMALIZE_MODE_ARGS_INVALID.toString(errMsg)); + return false; + } + } + + if (utility.getGeneralNormalizeList().contains(MIN_API_VERSION)) { + if (utility.getMinAPIVersion() < MINI_NUM || utility.getMinAPIVersion() > MAXI_NUM) { + String errMsg = "--min-api-version is invalid."; + LOG.error(PackingToolErrMsg.GENERAL_NORMALIZE_MODE_ARGS_INVALID.toString(errMsg)); + return false; + } + } + + if (utility.getGeneralNormalizeList().contains(TARGET_API_VERSION)) { + if (utility.getTargetAPIVersion() < MINI_NUM || utility.getTargetAPIVersion() > MAXI_NUM) { + String errMsg = "--target-api-version is invalid."; + LOG.error(PackingToolErrMsg.GENERAL_NORMALIZE_MODE_ARGS_INVALID.toString(errMsg)); + return false; + } + } + + if (utility.getGeneralNormalizeList().contains(API_RELEASE_TYPE)) { + Pattern pattern = Pattern.compile(API_RELEASE_TYPE_PATTERN); + if (!pattern.matcher(utility.getApiReleaseType()).matches()) { + String errMsg = "--api-release-type is invalid."; + LOG.error(PackingToolErrMsg.GENERAL_NORMALIZE_MODE_ARGS_INVALID.toString(errMsg)); + return false; + } + } + + if (utility.getGeneralNormalizeList().contains(BUNDLE_TYPE)) { + if (!bundleTypeList.contains(utility.getBundleType())) { + String errMsg = "--bundle-type is invalid."; + LOG.error(PackingToolErrMsg.GENERAL_NORMALIZE_MODE_ARGS_INVALID.toString(errMsg)); + return false; + } + } + + if (utility.getGeneralNormalizeList().contains(INSTALLATION_FREE)) { + if (!Boolean.TRUE.toString().equals(utility.getInstallationFree()) && + !Boolean.FALSE.toString().equals(utility.getInstallationFree())) { + String errMsg = "--installation-free is invalid."; + LOG.error(PackingToolErrMsg.GENERAL_NORMALIZE_MODE_ARGS_INVALID.toString(errMsg)); + return false; + } + } + + if (utility.getGeneralNormalizeList().contains(DELIVERY_WITH_INSTALL)) { + if (!Boolean.TRUE.toString().equals(utility.getDeliveryWithInstall()) && + !Boolean.FALSE.toString().equals(utility.getDeliveryWithInstall())) { + String errMsg = "--delivery-with-install is invalid."; + LOG.error(PackingToolErrMsg.GENERAL_NORMALIZE_MODE_ARGS_INVALID.toString(errMsg)); + return false; + } + } + + if (utility.getOutPath().isEmpty()) { + String errMsg = "--out-path is empty."; + LOG.error(PackingToolErrMsg.GENERAL_NORMALIZE_MODE_ARGS_INVALID.toString(errMsg)); + return false; + } + + File outDir = new File(utility.getOutPath()); + if (!outDir.isDirectory()) { + String errMsg = "--out-path is not a directory."; + LOG.error(PackingToolErrMsg.GENERAL_NORMALIZE_MODE_ARGS_INVALID.toString(errMsg)); + return false; + } + return true; + } + private static boolean isValidRpcid(Utility utility) { if (!utility.getRpcidPath().isEmpty()) { File file = new File(utility.getRpcidPath()); diff --git a/adapter/ohos/Compressor.java b/adapter/ohos/Compressor.java index b36f8ea4..0060781d 100644 --- a/adapter/ohos/Compressor.java +++ b/adapter/ohos/Compressor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2024 Huawei Device Co., Ltd. + * Copyright (c) 2021-2025 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 @@ -136,6 +136,7 @@ public class Compressor { private static final String BUILD_HASH = "buildHash"; private static final String TEMP_DIR = "temp"; private static final String SHA_256 = "SHA-256"; + private static final String MODULES = "modules"; private static final String JSON_SUFFIX = ".json"; private static final String ATOMIC_SERVICE = "atomicService"; private static final String RAW_FILE_PATH = "resources/rawfile"; @@ -146,7 +147,22 @@ public class Compressor { private static final String VERSION = "version"; private static final String CODE = "code"; private static final String VERSION_RECORD = "version_record.json"; + private static final String GENERAL_RECORD = "general_record.json"; private static final String RES_INDEX = "resources.index"; + private static final String DEVICE_TYPES = "deviceTypes"; + private static final String BUNDLE_NAME = "bundleName"; + private static final String MIN_COMPATIBLE_VERSION_CODE = "minCompatibleVersionCode"; + 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 BUNDLE_TYPE = "bundleType"; + private static final String INSTALLATION_FREE = "installationFree"; + private static final String DELIVERY_WITH_INSTALL = "deliveryWithInstall"; + private static final String API_VERSION = "apiVersion"; + private static final String RELEASE_TYPE = "releaseType"; + private static final String TARGET = "target"; + private static final String COMPATIBLE = "compatible"; + private static final String PACKAGES = "packages"; private static final String ETS_FILE_NAME = "ets"; private static final String HNP_FILE_NAME = "hnp"; private static final String DIR_FILE_NAME = "dir"; @@ -163,6 +179,7 @@ public class Compressor { private static final String TARGET_FILE_PATH = HAPADDITION_FOLDER_NAME + LINUX_FILE_SEPARATOR + "resources" + LINUX_FILE_SEPARATOR + "base" + LINUX_FILE_SEPARATOR + "profile"; private static final String BACKUP_PREFIX = "backup"; + private HashMap outPutMap = new HashMap<>(); // set timestamp to get fixed MD5 private static final int ENTRY_FILE_LIMIT_DEFAULT = 2; @@ -337,6 +354,9 @@ public class Compressor { return true; case Utility.PACKAGE_NORMALIZE: return PackageNormalize.normalize(utility); + case Utility.GENERAL_NORMALIZE: + generalNormalize(utility); + return true; default: return defaultProcess(utility); } @@ -3470,7 +3490,7 @@ public class Compressor { return util; } - private void compressDirToHap(Path sourceDir, String zipFilePath) + private boolean compressDirToHap(Path sourceDir, String zipFilePath) throws IOException, BundleException { Utility utility = new Utility(); utility.setOutPath(zipFilePath); @@ -3536,7 +3556,7 @@ public class Compressor { } }); } - compressProcess(utility); + return compressProcess(utility); } private static void deleteDirectory(File dir) { @@ -3633,4 +3653,438 @@ public class Compressor { LOG.info("Compressor::packEncryptJsonFile has no encrypt.json"); } } + + private void generalNormalize(Utility utility) { + List> recordList = new ArrayList<>(); + Path tempDir = null; + boolean isSuccess = true; + String[] name = new String[2]; + for (String hapPath : utility.getFormattedHapList()) { + try { + tempDir = Files.createTempDirectory(Paths.get(utility.getOutPath()), "temp"); + unpackHap(hapPath, tempDir.toAbsolutePath().toString()); + HashMap outPutMap = new HashMap<>(); + File moduleFile = new File( + tempDir.toAbsolutePath() + LINUX_FILE_SEPARATOR + MODULE_JSON); + File configFile = new File( + tempDir.toAbsolutePath() + LINUX_FILE_SEPARATOR + CONFIG_JSON); + File packInfoFile = new File( + tempDir.toAbsolutePath() + LINUX_FILE_SEPARATOR + PACKINFO_NAME); + + if (moduleFile.exists() && configFile.exists()) { + LOG.error(PackingToolErrMsg.GENERAL_NORMALIZE_MODE_ARGS_INVALID .toString("Invalid hap structure")); + throw new BundleException("generalNormalize failed, invalid hap structure."); + } + if (moduleFile.exists()) { + String moduleJsonPath = tempDir.resolve(MODULE_JSON).toString(); + outPutMap = parseAndModifyGeneralModuleJson(moduleJsonPath, utility, name); + } else if (configFile.exists()) { + String configJsonPath = tempDir.resolve(CONFIG_JSON).toString(); + outPutMap = parseAndModifyGeneralConfigJson(configJsonPath, utility, name); + } else { + LOG.error(PackingToolErrMsg.GENERAL_NORMALIZE_MODE_ARGS_INVALID .toString("Invalid hap structure")); + throw new BundleException("generalNormalize failed, invalid hap structure."); + } + if (packInfoFile.exists()) { + String packInfoPath = tempDir.resolve(PACKINFO_NAME).toString(); + parseAndModifyGeneralPackInfo(packInfoPath, utility); + } + recordList.add(outPutMap); + String modifiedHapPath = Paths.get(utility.getOutPath()) + + LINUX_FILE_SEPARATOR + Paths.get(hapPath).getFileName().toString(); + boolean ret = compressDirToHap(tempDir, modifiedHapPath); + if (!ret) { + isSuccess = false; + String errMsg = "compressDirToHap failed bundleName:" + name[0] + " moduleName:" + name[1]; + LOG.error(PackingToolErrMsg.GENERAL_NORMALIZE_MODE_ARGS_INVALID .toString(errMsg)); + break; + } + } catch (Exception e) { + String errMsg = "general normalize exist Exception bundleName:" + name[0] + " moduleName:" + name[1]; + LOG.error(PackingToolErrMsg.GENERAL_NORMALIZE_MODE_ARGS_INVALID .toString(errMsg + e.getMessage())); + isSuccess = false; + break; + } finally { + if (tempDir != null) { + deleteDirectory(tempDir.toFile()); + } + } + } + if (!isSuccess) { + if (Paths.get(utility.getOutPath()) != null) { + deleteFile(Paths.get(utility.getOutPath()).toFile()); + } + return; + } + writeGeneralRecord(recordList, utility.getOutPath()); + } + + private HashMap parseAndModifyGeneralModuleJson(String jsonFilePath, Utility utility, String[] name) + throws BundleException { + try (FileInputStream jsonStream = new FileInputStream(jsonFilePath)) { + JSONObject jsonObject = JSON.parseObject(jsonStream, JSONObject.class); + if (!jsonObject.containsKey(APP)) { + LOG.error(PackingToolErrMsg.PARSE_AND_MODIFY_MODULEJSON_FAILED.toString("The module.json file " + + "does not contain 'app'.")); + throw new BundleException("The module.json file does not contain 'app'. "); + } + JSONObject appObject = jsonObject.getJSONObject(APP); + JSONObject moduleObject = jsonObject.getJSONObject(MODULE); + if (!moduleObject.containsKey(NAME)) { + LOG.error(PackingToolErrMsg.PARSE_AND_MODIFY_MODULEJSON_FAILED.toString("The module object of " + + "module.json file does not contain 'name'.")); + throw new BundleException("The module object of module.json file does not contain 'name'. "); + } + if (!appObject.containsKey(BUNDLE_NAME)) { + LOG.error(PackingToolErrMsg.PARSE_AND_MODIFY_MODULEJSON_FAILED.toString("The app object of " + + "app.json file does not contain 'bundleName'.")); + throw new BundleException("The app object of app.json file does not contain 'bundleName'. "); + } + name[0] = appObject.getString(BUNDLE_NAME); + name[1] = moduleObject.getString(NAME); + outPutMap.put(MODULE_NAME_NEW, moduleObject.getString(NAME)); + + if (utility.getGeneralNormalizeList().contains(DEVICE_TYPES)) { + outPutMap.put(DEVICE_TYPES, getJsonString(moduleObject, DEVICE_TYPES)); + moduleObject.put(DEVICE_TYPES, utility.getDeviceTypes().split(",")); + } + + if (utility.getGeneralNormalizeList().contains(VERSION_CODE)) { + outPutMap.put(VERSION_CODE, String.valueOf(appObject.getIntValue(VERSION_CODE))); + appObject.put(VERSION_CODE, utility.getVersionCode()); + } + + if (utility.getGeneralNormalizeList().contains(VERSION_NAME)) { + outPutMap.put(VERSION_NAME, appObject.getString(VERSION_NAME)); + appObject.put(VERSION_NAME, utility.getVersionName()); + } + + if (utility.getGeneralNormalizeList().contains(BUNDLE_NAME)) { + outPutMap.put(BUNDLE_NAME, appObject.getString(BUNDLE_NAME)); + appObject.put(BUNDLE_NAME, utility.getBundleName()); + } + + if (utility.getGeneralNormalizeList().contains(MIN_COMPATIBLE_VERSION_CODE)) { + outPutMap.put(MIN_COMPATIBLE_VERSION_CODE, String.valueOf( + appObject.getIntValue(MIN_COMPATIBLE_VERSION_CODE))); + appObject.put(MIN_COMPATIBLE_VERSION_CODE, utility.getMinCompatibleVersionCode()); + } + + if (utility.getGeneralNormalizeList().contains(MIN_API_VERSION)) { + outPutMap.put(MIN_API_VERSION, String.valueOf(appObject.getIntValue(MIN_API_VERSION))); + appObject.put(MIN_API_VERSION, utility.getMinAPIVersion()); + } + + if (utility.getGeneralNormalizeList().contains(TARGET_API_VERSION)) { + outPutMap.put(TARGET_API_VERSION, String.valueOf(appObject.getIntValue(TARGET_API_VERSION))); + appObject.put(TARGET_API_VERSION, utility.getTargetAPIVersion()); + } + + if (utility.getGeneralNormalizeList().contains(API_RELEASE_TYPE)) { + outPutMap.put(API_RELEASE_TYPE, appObject.getString(API_RELEASE_TYPE)); + appObject.put(API_RELEASE_TYPE, utility.getApiReleaseType()); + } + + if (utility.getGeneralNormalizeList().contains(BUNDLE_TYPE)) { + outPutMap.put(BUNDLE_TYPE, appObject.getString(BUNDLE_TYPE)); + appObject.put(BUNDLE_TYPE, utility.getBundleType()); + } + + if (utility.getGeneralNormalizeList().contains(INSTALLATION_FREE)) { + outPutMap.put(INSTALLATION_FREE, moduleObject.getBoolean(INSTALLATION_FREE).toString()); + moduleObject.put(INSTALLATION_FREE, utility.getDeliveryWithInstall()); + } + + if (utility.getGeneralNormalizeList().contains(DELIVERY_WITH_INSTALL)) { + outPutMap.put(DELIVERY_WITH_INSTALL, moduleObject.getBoolean(DELIVERY_WITH_INSTALL).toString()); + moduleObject.put(DELIVERY_WITH_INSTALL, utility.getInstallationFree()); + } + writeJson(jsonFilePath, jsonObject); + } catch (IOException e) { + LOG.error(PackingToolErrMsg.IO_EXCEPTION.toString("Parse and modify module.json exist IOException: " + + e.getMessage())); + throw new BundleException("Parse and modify module.json exist IOException: " + e.getMessage()); + } + return outPutMap; + } + + private HashMap parseAndModifyGeneralConfigJson(String jsonFilePath, Utility utility, String[] name) + throws BundleException { + try (FileInputStream jsonStream = new FileInputStream(jsonFilePath)) { + JSONObject jsonObject = JSON.parseObject(jsonStream, JSONObject.class); + if (!jsonObject.containsKey(APP)) { + LOG.error(PackingToolErrMsg.PARSE_MODIFY_CONFIG_JSON_FAILED.toString("The config.json file " + + "does not contain 'app'.")); + throw new BundleException("The config.json file does not contain 'app'. "); + } + JSONObject appObject = jsonObject.getJSONObject(APP); + + if (!appObject.containsKey(VERSION)) { + LOG.error(PackingToolErrMsg.PARSE_MODIFY_CONFIG_JSON_FAILED.toString("The app object of config.json " + + "file does not contain 'version'.")); + throw new BundleException("The app object of config.json file does not contain 'version'. "); + } + JSONObject versionObj = appObject.getJSONObject(VERSION); + + if (!appObject.containsKey(API_VERSION)) { + JSONObject apiVersion = new JSONObject(); + appObject.put(API_VERSION, apiVersion); + } + JSONObject apiVersionObj = appObject.getJSONObject(API_VERSION); + + if (!jsonObject.containsKey(MODULE)) { + LOG.error(PackingToolErrMsg.PARSE_MODIFY_CONFIG_JSON_FAILED.toString("The app object of config.json " + + "file does not contain 'module'.")); + throw new BundleException("The app object of config.json file does not contain 'module'. "); + } + JSONObject moduleObject = jsonObject.getJSONObject(MODULE); + + if (!moduleObject.containsKey(DISTRO)) { + LOG.error(PackingToolErrMsg.PARSE_MODIFY_CONFIG_JSON_FAILED.toString("The app object of config.json " + + "file does not contain 'distro'.")); + throw new BundleException("The app object of config.json file does not contain 'distro'. "); + } + JSONObject distroObj = moduleObject.getJSONObject(DISTRO); + + if (!distroObj.containsKey(MODULE_NAME_NEW)) { + LOG.error(PackingToolErrMsg.PARSE_MODIFY_CONFIG_JSON_FAILED.toString("The module object of " + + "config.json file does not contain 'moduleName'.")); + throw new BundleException("The module object of module.json file does not contain 'moduleName'. "); + } + if (!appObject.containsKey(BUNDLE_NAME)) { + LOG.error(PackingToolErrMsg.PARSE_MODIFY_CONFIG_JSON_FAILED.toString("The app object of " + + "config.json file does not contain 'bundleName'.")); + throw new BundleException("The app object of config.json file does not contain 'bundleName'. "); + } + name[0] = appObject.getString(BUNDLE_NAME); + name[1] = distroObj.getString(MODULE_NAME_NEW); + outPutMap.put(MODULE_NAME_NEW, distroObj.getString(MODULE_NAME_NEW)); + + if (utility.getGeneralNormalizeList().contains(DEVICE_TYPES)) { + outPutMap.put(DEVICE_TYPE, getJsonString(moduleObject, DEVICE_TYPE)); + moduleObject.put(DEVICE_TYPE, utility.getDeviceTypes().split(",")); + } + if (utility.getGeneralNormalizeList().contains(VERSION_CODE)) { + outPutMap.put(CODE, String.valueOf(versionObj.getIntValue(CODE))); + versionObj.put(CODE, utility.getVersionCode()); + } + + if (utility.getGeneralNormalizeList().contains(VERSION_NAME)) { + outPutMap.put(NAME, versionObj.getString(NAME)); + versionObj.put(NAME, utility.getVersionName()); + } + + if (utility.getGeneralNormalizeList().contains(MIN_COMPATIBLE_VERSION_CODE)) { + outPutMap.put(MIN_COMPATIBLE_VERSION_CODE, String.valueOf( + versionObj.getIntValue(MIN_COMPATIBLE_VERSION_CODE))); + versionObj.put(MIN_COMPATIBLE_VERSION_CODE, utility.getMinCompatibleVersionCode()); + } + + if (utility.getGeneralNormalizeList().contains(BUNDLE_NAME)) { + outPutMap.put(BUNDLE_NAME, appObject.getString(BUNDLE_NAME)); + appObject.put(BUNDLE_NAME, utility.getBundleName()); + } + + if (utility.getGeneralNormalizeList().contains(MIN_API_VERSION)) { + outPutMap.put(COMPATIBLE, String.valueOf(apiVersionObj.getIntValue(COMPATIBLE))); + apiVersionObj.put(COMPATIBLE, utility.getMinAPIVersion()); + } + + if (utility.getGeneralNormalizeList().contains(TARGET_API_VERSION)) { + outPutMap.put(TARGET, String.valueOf(apiVersionObj.getIntValue(TARGET))); + apiVersionObj.put(TARGET, utility.getTargetAPIVersion()); + } + + if (utility.getGeneralNormalizeList().contains(API_RELEASE_TYPE)) { + outPutMap.put(RELEASE_TYPE, apiVersionObj.getString(RELEASE_TYPE)); + apiVersionObj.put(RELEASE_TYPE, utility.getApiReleaseType()); + } + + if (utility.getGeneralNormalizeList().contains(BUNDLE_TYPE)) { + outPutMap.put(BUNDLE_TYPE, appObject.getString(BUNDLE_TYPE)); + appObject.put(BUNDLE_TYPE, utility.getBundleType()); + } + + if (utility.getGeneralNormalizeList().contains(INSTALLATION_FREE)) { + outPutMap.put(INSTALLATION_FREE, distroObj.getBoolean(INSTALLATION_FREE).toString()); + distroObj.put(INSTALLATION_FREE, utility.getDeliveryWithInstall()); + } + + if (utility.getGeneralNormalizeList().contains(DELIVERY_WITH_INSTALL)) { + outPutMap.put(DELIVERY_WITH_INSTALL, distroObj.getBoolean(DELIVERY_WITH_INSTALL).toString()); + distroObj.put(DELIVERY_WITH_INSTALL, utility.getInstallationFree()); + } + writeJson(jsonFilePath, jsonObject); + } catch (IOException e) { + LOG.error(PackingToolErrMsg.IO_EXCEPTION.toString("Parse and modify module.json exist IOException: " + + e.getMessage())); + throw new BundleException("Parse and modify config.json exist IOException: " + e.getMessage()); + } + return outPutMap; + } + + private void parseAndModifyGeneralPackInfo(String packInfoPath, Utility utility) + throws BundleException { + try (FileInputStream jsonStream = new FileInputStream(packInfoPath)) { + JSONObject jsonObject = JSON.parseObject(jsonStream, JSONObject.class); + if (jsonObject == null) { + LOG.warning("parseAndModifyGeneralPackInfo failed, json format invalid."); + return; + } + JSONObject summaryObject = jsonObject.getJSONObject(SUMMARY); + if (summaryObject == null) { + LOG.warning("parseAndModifyGeneralPackInfo failed, summary invalid."); + return; + } + JSONObject appObject = summaryObject.getJSONObject(APP); + if (appObject == null) { + LOG.warning("parseAndModifyGeneralPackInfo failed, app invalid."); + return; + } + JSONArray moduleJsonList = summaryObject.getJSONArray(MODULES); + if (moduleJsonList.isEmpty()) { + LOG.warning("parseAndModifyGeneralPackInfo failed, modules invalid."); + return; + } + + if (utility.getGeneralNormalizeList().contains(DEVICE_TYPES)) { + for (int i = 0; i < moduleJsonList.size(); i++) { + JSONObject moduleJson = moduleJsonList.getJSONObject(i); + if (moduleJson == null) { + LOG.warning("parseAndModifyGeneralPackInfo failed, moduleJson invalid."); + continue; + } + moduleJson.put(DEVICE_TYPE, utility.getDeviceTypes().split(",")); + } + } + + JSONObject versionObject = appObject.getJSONObject(VERSION); + if (versionObject == null) { + LOG.warning("parseAndModifyGeneralPackInfo failed, version invalid."); + return; + } + + if (utility.getGeneralNormalizeList().contains(VERSION_CODE)) { + versionObject.put(CODE, utility.getVersionCode()); + } + + if (utility.getGeneralNormalizeList().contains(VERSION_NAME)) { + versionObject.put(NAME, utility.getVersionName()); + } + + if (utility.getGeneralNormalizeList().contains(BUNDLE_NAME)) { + appObject.put(BUNDLE_NAME, utility.getBundleName()); + } + + if (utility.getGeneralNormalizeList().contains(MIN_COMPATIBLE_VERSION_CODE)) { + versionObject.put(MIN_COMPATIBLE_VERSION_CODE, utility.getMinCompatibleVersionCode()); + } + + if (utility.getGeneralNormalizeList().contains(MIN_API_VERSION)) { + setApiVersion(moduleJsonList, MIN_API_VERSION, utility); + } + + if (utility.getGeneralNormalizeList().contains(TARGET_API_VERSION)) { + setApiVersion(moduleJsonList, TARGET_API_VERSION, utility); + } + + if (utility.getGeneralNormalizeList().contains(API_RELEASE_TYPE)) { + setApiVersion(moduleJsonList, API_RELEASE_TYPE, utility); + } + + if (utility.getGeneralNormalizeList().contains(BUNDLE_TYPE)) { + appObject.put(BUNDLE_TYPE, utility.getBundleType()); + } + + if (utility.getGeneralNormalizeList().contains(INSTALLATION_FREE)) { + setDistroObj(moduleJsonList, INSTALLATION_FREE, utility); + } + + if (utility.getGeneralNormalizeList().contains(DELIVERY_WITH_INSTALL)) { + setDistroObj(moduleJsonList, DELIVERY_WITH_INSTALL, utility); + } + + JSONArray jsonArray = jsonObject.getJSONArray(PACKAGES); + if (jsonArray != null) { + for (int i = 0; i < jsonArray.size(); i++) { + JSONObject object = jsonArray.getJSONObject(i); + if (utility.getGeneralNormalizeList().contains(DEVICE_TYPES)) { + object.put(DEVICE_TYPE, utility.getDeviceTypes().split(",")); + } + if (utility.getGeneralNormalizeList().contains(DELIVERY_WITH_INSTALL)) { + object.put(DELIVERY_WITH_INSTALL, utility.getDeliveryWithInstall()); + } + } + } + + writeJson(packInfoPath, jsonObject); + } catch (IOException e) { + LOG.warning("parseAndModifyGeneralPackInfo failed, IOException." + e.getMessage()); + } + } + + private static void setApiVersion(JSONArray moduleJsonList, String key, Utility utility) { + for (int i = 0; i < moduleJsonList.size(); i++) { + JSONObject moduleJson = moduleJsonList.getJSONObject(i); + if (moduleJson == null) { + LOG.warning("setApiVersion failed, moduleJson invalid."); + break; + } + JSONObject apiVersionObj = moduleJson.getJSONObject(API_VERSION); + if (apiVersionObj == null) { + JSONObject apiVersion = new JSONObject(); + moduleJson.put(API_VERSION, apiVersion); + apiVersionObj = moduleJson.getJSONObject(API_VERSION); + } + if(key == MIN_API_VERSION) { + apiVersionObj.put(COMPATIBLE, utility.getMinAPIVersion()); + } else if (key == TARGET_API_VERSION) { + apiVersionObj.put(TARGET, utility.getTargetAPIVersion()); + } else if (key == API_RELEASE_TYPE) { + apiVersionObj.put(RELEASE_TYPE, utility.getApiReleaseType()); + } + } + } + + private static void setDistroObj(JSONArray moduleJsonList, String key, Utility utility) { + for (int i = 0; i < moduleJsonList.size(); i++) { + JSONObject moduleJson = moduleJsonList.getJSONObject(i); + if (moduleJson == null) { + LOG.warning("setDistroObj failed, moduleJson invalid."); + break; + } + JSONObject distroObj = moduleJson.getJSONObject(DISTRO); + if (distroObj == null) { + LOG.warning("setDistroObj failed, distro invalid."); + break; + } + if(key == INSTALLATION_FREE) { + distroObj.put(INSTALLATION_FREE, utility.getInstallationFree()); + } else if (key == DELIVERY_WITH_INSTALL) { + distroObj.put(DELIVERY_WITH_INSTALL, utility.getDeliveryWithInstall()); + } + } + } + + private static void writeGeneralRecord(List> recordList, String outPath) { + try (FileWriter fileWriter = new FileWriter(outPath + LINUX_FILE_SEPARATOR + GENERAL_RECORD)) { + for (HashMap record : recordList) { + String jsonString = JSON.toJSONString(record); + fileWriter.write(jsonString); + fileWriter.write(","); + } + } catch (IOException e) { + LOG.error(PackingToolErrMsg.IO_EXCEPTION.toString("Write general record exist IOException: " + + e.getMessage())); + } + } + + private static void deleteFile(File dir) { + File[] children = dir.listFiles(); + if (children != null) { + for (File child : children) { + child.delete(); + } + } + } } diff --git a/adapter/ohos/PackingToolErrMsg.java b/adapter/ohos/PackingToolErrMsg.java index 18c40da2..2b3914eb 100644 --- a/adapter/ohos/PackingToolErrMsg.java +++ b/adapter/ohos/PackingToolErrMsg.java @@ -255,6 +255,16 @@ public class PackingToolErrMsg { .setCause("%s") .build(); + /** + * GENERAL_NORMALIZE_MODE_ARGS_INVALID + */ + public static final ErrorMsg GENERAL_NORMALIZE_MODE_ARGS_INVALID = ErrorMsg.getPackingToolErrBuilder() + .setTypeCode("11") + .setErrCode("021") + .setDescription("Parse and check args invalid in generalNormalize mode.") + .setCause("%s") + .build(); + // compress process error /** * COMPRESS_PROCESS_FAILED diff --git a/adapter/ohos/Utility.java b/adapter/ohos/Utility.java index 81bf9967..3866fb82 100644 --- a/adapter/ohos/Utility.java +++ b/adapter/ohos/Utility.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2023 Huawei Device Co., Ltd. + * Copyright (c) 2021-2025 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 @@ -39,6 +39,7 @@ public class Utility { static final String MODE_HAPADDITION = "hapAddition"; static final String VERSION_NORMALIZE = "versionNormalize"; static final String PACKAGE_NORMALIZE = "packageNormalize"; + static final String GENERAL_NORMALIZE = "generalNormalize"; static final String FALSE_STRING = "false"; static final String TRUE_STRING = "true"; @@ -110,6 +111,17 @@ public class Utility { private String absoluteHapPath = ""; private boolean generateBuildHash = false; private boolean buildHashFinish = false; + private int minCompatibleVersionCode = -1; + private int minAPIVersion = -1; + private String compileSdkType = ""; + private String compileSdkVersion = ""; + private int targetAPIVersion = -1; + private String apiReleaseType = ""; + private String bundleType = ""; + private String installationFree = ""; + private String deliveryWithInstall = ""; + private String deviceTypes = ""; + private List generalNormalizeList = new ArrayList<>(); private List formattedCpuAbiList = new ArrayList<>(); private List formattedSoPathList = new ArrayList<>(); @@ -922,4 +934,76 @@ public class Utility { public void setStatFileSize(String statFileSize) { this.statFileSize = statFileSize; } + + public int getMinCompatibleVersionCode() { + return minCompatibleVersionCode; + } + + public void setMinCompatibleVersionCode(int minCompatibleVersionCode) { + this.minCompatibleVersionCode = minCompatibleVersionCode; + } + + public int getMinAPIVersion() { + return minAPIVersion; + } + + public void setMinAPIVersion(int minAPIVersion) { + this.minAPIVersion = minAPIVersion; + } + + public int getTargetAPIVersion() { + return targetAPIVersion; + } + + public void setTargetAPIVersion(int targetAPIVersion) { + this.targetAPIVersion = targetAPIVersion; + } + + public String getApiReleaseType() { + return apiReleaseType; + } + + public void setApiReleaseType(String apiReleaseType) { + this.apiReleaseType = apiReleaseType; + } + + public String getBundleType() { + return bundleType; + } + + public void setBundleType(String bundleType) { + this.bundleType = bundleType; + } + + public String getDeliveryWithInstall() { + return deliveryWithInstall; + } + + public void setDeliveryWithInstall(String deliveryWithInstall) { + this.deliveryWithInstall = deliveryWithInstall; + } + + public String getInstallationFree() { + return installationFree; + } + + public void setInstallationFree(String installationFree) { + this.installationFree = installationFree; + } + + public String getDeviceTypes() { + return deviceTypes; + } + + public void setDeviceTypes(String deviceTypes) { + this.deviceTypes = deviceTypes; + } + + public void addGeneralNormalizeList(String generalNormalize) { + this.generalNormalizeList.add(generalNormalize); + } + + public List getGeneralNormalizeList() { + return generalNormalizeList; + } } -- Gitee