1 /* 2 * Copyright (c) 2021-2025 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 package ohos; 17 18 import java.util.AbstractMap; 19 import java.util.HashMap; 20 import java.util.Map; 21 import java.util.function.Function; 22 23 /** 24 * command parser. 25 * 26 */ 27 public class CommandParser { 28 /** 29 * Parses and returns the hap list that supports the device type. 30 */ 31 public static final String PARSE_MODE_HAPLIST = "hap-list"; 32 33 /** 34 * Parses and returns the information about the hap. 35 */ 36 public static final String PARSE_MODE_HAPINFO = "hap-info"; 37 38 private static final String CMD_MODE = "--mode"; 39 private static final String CMD_JSON_PATH = "--json-path"; 40 private static final String CMD_PROFILE_PATH = "--profile-path"; 41 private static final String CMD_INDEX_PATH = "--index-path"; 42 private static final String CMD_JS_PATH = "--js-path"; 43 private static final String CMD_ETS_PATH = "--ets-path"; 44 private static final String CMD_HNP_PATH = "--hnp-path"; 45 private static final String CMD_RPCID_PATH = "--rpcid-path"; 46 private static final String CMD_RPCID = "--rpcid"; 47 private static final String CMD_LIBS = "--libs"; 48 private static final String CMD_CPU_ABIS = "--cpu-abis"; 49 private static final String CMD_SO_PATH = "--maple-so-path"; 50 private static final String CMD_SO_DIR = "--maple-so-dir"; 51 private static final String CMD_ABILITY_SO_PATH = "--ability-so-path"; 52 private static final String CMD_DEX_PATH = "--dex-path"; 53 private static final String CMD_ABC_PATH = "--abc-path"; 54 private static final String CMD_FILE_PATH = "--file-path"; 55 private static final String CMD_LIB_PATH = "--lib-path"; 56 private static final String CMD_RES_PATH = "--res-path"; 57 private static final String CMD_RESOURCES_PATH = "--resources-path"; 58 private static final String CMD_ASSETS_PATH = "--assets-path"; 59 private static final String CMD_APK_PATH = "--shell-apk-path"; 60 private static final String CMD_HAP_PATH = "--hap-path"; 61 private static final String CMD_APP_PATH = "--app-path"; 62 private static final String CMD_SIGNATURE_PATH = "--signature-path"; 63 private static final String CMD_CERTIFICATE_PATH = "--certificate-path"; 64 private static final String CMD_FORCE = "--force"; 65 private static final String CMD_OUT_PATH = "--out-path"; 66 private static final String CMD_PACK_INFO_PATH = "--pack-info-path"; 67 private static final String CMD_ENCRYPT_PATH = "--encrypt-path"; 68 private static final String CMD_PAC_JSON_PATH = "--pac-json-path"; 69 private static final String CMD_BIN_PATH = "--bin-path"; 70 private static final String CMD_JAR_PATH = "--jar-path"; 71 private static final String CMD_TXT_PATH = "--txt-path"; 72 private static final String CMD_HAR_PATH = "--har-path"; 73 private static final String CMD_HSP_PATH = "--hsp-path"; 74 private static final String CMD_PARSE_MODE = "--p"; 75 private static final String CMD_PACK_RES_PATH = "--pack-res-path"; 76 private static final String CMD_UNPACKAPK = "--unpackapk"; 77 private static final String CMD_UNPACK_CUT_ENTRY_APK = "--unpack-cut_entry"; 78 private static final String CMD_SHAREDLIBS_PATH = "--shared-libs-path"; 79 private static final String CMD_ENTRYCARD_PATH = "--entrycard-path"; 80 private static final String CMD_HAP_LIST = "--hap-list"; 81 private static final String CMD_HSP_LIST = "--hsp-list"; 82 private static final String CMD_APP_LIST = "--app-list"; 83 private static final String CMD_DIR_LIST = "--dir-list"; 84 private static final String CMD_HQF_LIST = "--hqf-list"; 85 private static final String CMD_APPQF_PATH = "--appqf-path"; 86 private static final String CMD_AN_PATH = "--an-path"; 87 private static final String CMD_AP_PATH = "--ap-path"; 88 private static final String MAIN_MODULE_LIMIT = "--main-module-limit"; 89 private static final String NORMAL_MODULE_LIMIT = "--normal-module-limit"; 90 private static final String TOTAL_LIMIT = "--total-limit"; 91 private static final String ATOMIC_SERVICE_ENTRY_SIZE_LIMIT = "--atomic-service-entry-size-limit"; 92 private static final String ATOMIC_SERVICE_NON_ENTRY_SIZE_LIMIT = "--atomic-service-non-entry-size-limit"; 93 private static final String VERSION_CODE = "--version-code"; 94 private static final String VERSION_NAME = "--version-name"; 95 private static final String INPUT_LIST = "--input-list"; 96 private static final String PARAM_DEVICE_TYPES = "--device-types"; 97 private static final String PARAM_MIN_COMPATIBLE_VERSION_CODE = "--min-compatible-version-code"; 98 private static final String PARAM_MIN_API_VERSION = "--min-api-version"; 99 private static final String PARAM_TARGET_API_VERSION = "--target-api-version"; 100 private static final String PARAM_API_RELEASE_TYPE = "--api-release-type"; 101 private static final String PARAM_BUNDLE_TYPE = "--bundle-type"; 102 private static final String PARAM_INSTALLATION_FREE = "--installation-free"; 103 private static final String PARAM_DELIVERY_WITH_INSTALL = "--delivery-with-install"; 104 private static final String VERSION_CODE_PARAM = "versionCode"; 105 private static final String VERSION_NAME_PARAM = "versionName"; 106 private static final String DEVICE_TYPES_PARAM = "deviceTypes"; 107 private static final String BUNDLE_NAME_PARAM = "bundleName"; 108 private static final String MIN_COMPATIBLE_VERSION_CODE_PARAM = "minCompatibleVersionCode"; 109 private static final String MIN_API_VERSION_PARAM = "minAPIVersion"; 110 private static final String TARGET_API_VERSION_PARAM = "targetAPIVersion"; 111 private static final String API_RELEASE_TYPE_PARAM = "apiReleaseType"; 112 private static final String BUNDLE_TYPE_PARAM = "bundleType"; 113 private static final String INSTALLATION_FREE_PARAM = "installationFree"; 114 private static final String DELIVERY_WITH_INSTALL_PARAM = "deliveryWithInstall"; 115 private static final String INPUT = "--input"; 116 private static final String STAT_DUPLICATE = "--stat-duplicate"; 117 private static final String STAT_SUFFIX = "--stat-suffix"; 118 private static final String STAT_FILE_SIZE = "--stat-file-size"; 119 private static final String CMD_COMPRESS_LEVEL = "--compress-level"; 120 private static final String CMD_PKG_CONTEXT_PATH = "--pkg-context-path"; 121 private static final String CMD_BUNDLE_NAME = "--bundle-name"; 122 private static final String PARSER_STAT_DUPLICATE_ERROR = "code:9132600 " + 123 "error:statDuplicate is invalid! Must be true or false."; 124 private static final String PARSER_STAT_SUFFIX_ERROR = "code:9132601 " + 125 "error:statSuffix is invalid! Must be true or false."; 126 private static final int PARSE_MODE_VALUE_LENGTH = 2; 127 private static final Log LOG = new Log(CommandParser.class.toString()); 128 private static final Map<String, Function<Map.Entry<Utility, String>, Boolean>> commandFuncs = new HashMap<>(); 129 130 static { initCommandFuncs()131 initCommandFuncs(); 132 } 133 initCommandFuncs()134 private static void initCommandFuncs() { 135 commandFuncs.put(CMD_MODE, entry -> { 136 entry.getKey().setMode(entry.getValue()); 137 return true; 138 }); 139 commandFuncs.put(CMD_JSON_PATH, entry -> { 140 entry.getKey().setJsonPath(entry.getValue()); 141 return true; 142 }); 143 commandFuncs.put(CMD_PROFILE_PATH, entry -> { 144 entry.getKey().setProfilePath(entry.getValue()); 145 return true; 146 }); 147 commandFuncs.put(CMD_INDEX_PATH, entry -> { 148 entry.getKey().setIndexPath(entry.getValue()); 149 return true; 150 }); 151 commandFuncs.put(CMD_JS_PATH, entry -> { 152 entry.getKey().setJsPath(entry.getValue()); 153 return true; 154 }); 155 commandFuncs.put(CMD_ETS_PATH, entry -> { 156 entry.getKey().setEtsPath(entry.getValue()); 157 return true; 158 }); 159 commandFuncs.put(CMD_HNP_PATH, entry -> { 160 entry.getKey().setHnpPath(entry.getValue()); 161 return true; 162 }); 163 commandFuncs.put(CMD_RPCID_PATH, entry -> { 164 entry.getKey().setRpcidPath(entry.getValue()); 165 return true; 166 }); 167 commandFuncs.put(CMD_RPCID, entry -> { 168 entry.getKey().setRpcid(entry.getValue()); 169 return true; 170 }); 171 commandFuncs.put(CMD_LIBS, entry -> { 172 entry.getKey().setLibs(entry.getValue()); 173 return true; 174 }); 175 commandFuncs.put(CMD_CPU_ABIS, entry -> { 176 entry.getKey().setCpuAbis(entry.getValue()); 177 return true; 178 }); 179 commandFuncs.put(CMD_SO_PATH, entry -> { 180 entry.getKey().setSoPath(entry.getValue()); 181 return true; 182 }); 183 commandFuncs.put(CMD_SO_DIR, entry -> { 184 entry.getKey().setSoDir(entry.getValue()); 185 return true; 186 }); 187 commandFuncs.put(CMD_ABILITY_SO_PATH, entry -> { 188 entry.getKey().setAbilitySoPath(entry.getValue()); 189 return true; 190 }); 191 commandFuncs.put(CMD_DEX_PATH, entry -> { 192 entry.getKey().setDexPath(entry.getValue()); 193 return true; 194 }); 195 commandFuncs.put(CMD_ABC_PATH, entry -> { 196 entry.getKey().setAbcPath(entry.getValue()); 197 return true; 198 }); 199 commandFuncs.put(CMD_FILE_PATH, entry -> { 200 entry.getKey().setFilePath(entry.getValue()); 201 return true; 202 }); 203 commandFuncs.put(CMD_LIB_PATH, entry -> { 204 entry.getKey().setLibPath(entry.getValue()); 205 return true; 206 }); 207 commandFuncs.put(CMD_RES_PATH, entry -> { 208 entry.getKey().setResPath(entry.getValue()); 209 return true; 210 }); 211 commandFuncs.put(CMD_RESOURCES_PATH, entry -> { 212 entry.getKey().setResourcesPath(entry.getValue()); 213 return true; 214 }); 215 commandFuncs.put(CMD_ASSETS_PATH, entry -> { 216 entry.getKey().setAssetsPath(entry.getValue()); 217 return true; 218 }); 219 commandFuncs.put(CMD_APK_PATH, entry -> { 220 entry.getKey().setApkPath(entry.getValue()); 221 return true; 222 }); 223 commandFuncs.put(CMD_HAP_PATH, entry -> { 224 entry.getKey().setHapPath(entry.getValue()); 225 return true; 226 }); 227 commandFuncs.put(CMD_APP_PATH, entry -> { 228 entry.getKey().setAppPath(entry.getValue()); 229 return true; 230 }); 231 commandFuncs.put(CMD_SIGNATURE_PATH, entry -> { 232 entry.getKey().setSignaturePath(entry.getValue()); 233 return true; 234 }); 235 commandFuncs.put(CMD_CERTIFICATE_PATH, entry -> { 236 entry.getKey().setCertificatePath(entry.getValue()); 237 return true; 238 }); 239 commandFuncs.put(CMD_FORCE, entry -> { 240 entry.getKey().setForceRewrite(entry.getValue()); 241 return true; 242 }); 243 commandFuncs.put(CMD_OUT_PATH, entry -> { 244 entry.getKey().setOutPath(entry.getValue()); 245 return true; 246 }); 247 commandFuncs.put(CMD_PACK_INFO_PATH, entry -> { 248 entry.getKey().setPackInfoPath(entry.getValue()); 249 return true; 250 }); 251 commandFuncs.put(CMD_ENCRYPT_PATH, entry -> { 252 entry.getKey().setEncryptPath(entry.getValue()); 253 return true; 254 }); 255 commandFuncs.put(CMD_PAC_JSON_PATH, entry -> { 256 entry.getKey().setPacJsonPath(entry.getValue()); 257 return true; 258 }); 259 commandFuncs.put(CMD_BIN_PATH, entry -> { 260 entry.getKey().setBinPath(entry.getValue()); 261 return true; 262 }); 263 commandFuncs.put(CMD_JAR_PATH, entry -> { 264 entry.getKey().setJarPath(entry.getValue()); 265 return true; 266 }); 267 commandFuncs.put(CMD_TXT_PATH, entry -> { 268 entry.getKey().setTxtPath(entry.getValue()); 269 return true; 270 }); 271 commandFuncs.put(CMD_HAR_PATH, entry -> { 272 entry.getKey().setHarPath(entry.getValue()); 273 return true; 274 }); 275 commandFuncs.put(CMD_HSP_PATH, entry -> { 276 entry.getKey().setHspPath(entry.getValue()); 277 return true; 278 }); 279 commandFuncs.put(CMD_PACK_RES_PATH, entry -> { 280 entry.getKey().setPackResPath(entry.getValue()); 281 return true; 282 }); 283 commandFuncs.put(CMD_UNPACKAPK, entry -> { 284 entry.getKey().setUnpackApk(entry.getValue()); 285 return true; 286 }); 287 commandFuncs.put(CMD_UNPACK_CUT_ENTRY_APK, entry -> { 288 entry.getKey().setUnpackCutEntryApk(entry.getValue()); 289 return true; 290 }); 291 commandFuncs.put(CMD_SHAREDLIBS_PATH, entry -> { 292 entry.getKey().setSharedLibsPath(entry.getValue()); 293 return true; 294 }); 295 commandFuncs.put(CMD_ENTRYCARD_PATH, entry -> { 296 entry.getKey().setEntryCardPath(entry.getValue()); 297 return true; 298 }); 299 commandFuncs.put(CMD_HAP_LIST, entry -> { 300 entry.getKey().setHapList(entry.getValue()); 301 return true; 302 }); 303 commandFuncs.put(CMD_HSP_LIST, entry -> { 304 entry.getKey().setHspList(entry.getValue()); 305 return true; 306 }); 307 commandFuncs.put(CMD_APP_LIST, entry -> { 308 entry.getKey().setAppList(entry.getValue()); 309 return true; 310 }); 311 commandFuncs.put(CMD_DIR_LIST, entry -> { 312 entry.getKey().setDirList(entry.getValue()); 313 return true; 314 }); 315 commandFuncs.put(CMD_HQF_LIST, entry -> { 316 entry.getKey().setHqfList(entry.getValue()); 317 return true; 318 }); 319 commandFuncs.put(CMD_APPQF_PATH, entry -> { 320 entry.getKey().setAPPQFPath(entry.getValue()); 321 return true; 322 }); 323 commandFuncs.put(CMD_AN_PATH, entry -> { 324 entry.getKey().setANPath(entry.getValue()); 325 return true; 326 }); 327 commandFuncs.put(CMD_AP_PATH, entry -> { 328 entry.getKey().setAPPath(entry.getValue()); 329 return true; 330 }); 331 commandFuncs.put(MAIN_MODULE_LIMIT, entry -> { 332 entry.getKey().setMainModuleLimit(entry.getValue()); 333 return true; 334 }); 335 commandFuncs.put(NORMAL_MODULE_LIMIT, entry -> { 336 entry.getKey().setNormalModuleLimit(entry.getValue()); 337 return true; 338 }); 339 commandFuncs.put(TOTAL_LIMIT, entry -> { 340 entry.getKey().setAtomicServiceTotalSizeLimit(entry.getValue()); 341 return true; 342 }); 343 commandFuncs.put(ATOMIC_SERVICE_ENTRY_SIZE_LIMIT, entry -> { 344 entry.getKey().setAtomicServiceEntrySizeLimit(entry.getValue()); 345 return true; 346 }); 347 commandFuncs.put(ATOMIC_SERVICE_NON_ENTRY_SIZE_LIMIT, entry -> { 348 entry.getKey().setAtomicServiceNonEntrySizeLimit(entry.getValue()); 349 return true; 350 }); 351 commandFuncs.put(VERSION_CODE, entry -> { 352 entry.getKey().addGeneralNormalizeList(VERSION_CODE_PARAM); 353 try { 354 entry.getKey().setVersionCode(Integer.parseInt(entry.getValue())); 355 } catch (NumberFormatException ignored) { 356 LOG.error(PackingToolErrMsg.COMMAND_PARSER_FAILED.toString( 357 "--version-code value is not number or invalid.")); 358 entry.getKey().setParameterIsInvalid(false); 359 return false; 360 } 361 return true; 362 }); 363 commandFuncs.put(VERSION_NAME, entry -> { 364 entry.getKey().setVersionName(entry.getValue()); 365 entry.getKey().addGeneralNormalizeList(VERSION_NAME_PARAM); 366 return true; 367 }); 368 commandFuncs.put(INPUT_LIST, entry -> { 369 entry.getKey().setInputList(entry.getValue()); 370 return true; 371 }); 372 commandFuncs.put(INPUT, entry -> { 373 entry.getKey().setInput(entry.getValue()); 374 return true; 375 }); 376 commandFuncs.put(STAT_DUPLICATE, entry -> { 377 if (Boolean.TRUE.toString().equals(entry.getValue()) || Boolean.FALSE.toString().equals(entry.getValue())) { 378 entry.getKey().setStatDuplicate(Boolean.parseBoolean(entry.getValue())); 379 return true; 380 } else { 381 LOG.error(PARSER_STAT_DUPLICATE_ERROR); 382 return false; 383 } 384 }); 385 commandFuncs.put(STAT_SUFFIX, entry -> { 386 if (Boolean.TRUE.toString().equals(entry.getValue()) || Boolean.FALSE.toString().equals(entry.getValue())) { 387 entry.getKey().setStatSuffix(Boolean.parseBoolean(entry.getValue())); 388 return true; 389 } else { 390 LOG.error(PARSER_STAT_SUFFIX_ERROR); 391 return false; 392 } 393 }); 394 commandFuncs.put(STAT_FILE_SIZE, entry -> { 395 entry.getKey().setStatFileSize(entry.getValue()); 396 return true; 397 }); 398 commandFuncs.put(CMD_COMPRESS_LEVEL, entry -> { 399 String level = entry.getValue(); 400 try { 401 int compressLevel = Integer.parseInt(level); 402 if (compressLevel < 1 || compressLevel > 9) { 403 LOG.error(PackingToolErrMsg.COMMAND_PARSER_FAILED.toString( 404 "--compress-level value not number between 1-9.")); 405 return false; 406 } else { 407 entry.getKey().setCompressLevel(compressLevel); 408 return true; 409 } 410 } catch (NumberFormatException ex) { 411 LOG.error(PackingToolErrMsg.COMMAND_PARSER_FAILED.toString( 412 "--compress-level value not number between 1-9.")); 413 return false; 414 } 415 }); 416 commandFuncs.put(CMD_PKG_CONTEXT_PATH, entry -> { 417 entry.getKey().setPkgContextPath(entry.getValue()); 418 return true; 419 }); 420 commandFuncs.put(CMD_BUNDLE_NAME, entry -> { 421 entry.getKey().setBundleName(entry.getValue()); 422 entry.getKey().addGeneralNormalizeList(BUNDLE_NAME_PARAM); 423 return true; 424 }); 425 commandFuncs.put(PARAM_DEVICE_TYPES, entry -> { 426 entry.getKey().setDeviceTypes(entry.getValue()); 427 entry.getKey().addGeneralNormalizeList(DEVICE_TYPES_PARAM); 428 return true; 429 }); 430 commandFuncs.put(PARAM_MIN_COMPATIBLE_VERSION_CODE, entry -> { 431 entry.getKey().addGeneralNormalizeList(MIN_COMPATIBLE_VERSION_CODE_PARAM); 432 try { 433 entry.getKey().setMinCompatibleVersionCode(Integer.parseInt(entry.getValue())); 434 } catch (NumberFormatException ignored) { 435 LOG.error(PackingToolErrMsg.COMMAND_PARSER_FAILED.toString( 436 "--min-compatible-version-code value is not number or invalid.")); 437 entry.getKey().setParameterIsInvalid(false); 438 return false; 439 } 440 return true; 441 }); 442 commandFuncs.put(PARAM_MIN_API_VERSION, entry -> { 443 entry.getKey().addGeneralNormalizeList(MIN_API_VERSION_PARAM); 444 try { 445 entry.getKey().setMinAPIVersion(Integer.parseInt(entry.getValue())); 446 } catch (NumberFormatException ignored) { 447 LOG.error(PackingToolErrMsg.COMMAND_PARSER_FAILED.toString( 448 "--min-api-version value is not number or invalid.")); 449 entry.getKey().setParameterIsInvalid(false); 450 return false; 451 } 452 return true; 453 }); 454 commandFuncs.put(PARAM_TARGET_API_VERSION, entry -> { 455 entry.getKey().addGeneralNormalizeList(TARGET_API_VERSION_PARAM); 456 try { 457 entry.getKey().setTargetAPIVersion(Integer.parseInt(entry.getValue())); 458 } catch (NumberFormatException ignored) { 459 LOG.error(PackingToolErrMsg.COMMAND_PARSER_FAILED.toString( 460 "--target-api-version value is not number or invalid.")); 461 entry.getKey().setParameterIsInvalid(false); 462 return false; 463 } 464 return true; 465 }); 466 commandFuncs.put(PARAM_API_RELEASE_TYPE, entry -> { 467 entry.getKey().setApiReleaseType(entry.getValue()); 468 entry.getKey().addGeneralNormalizeList(API_RELEASE_TYPE_PARAM); 469 return true; 470 }); 471 commandFuncs.put(PARAM_BUNDLE_TYPE, entry -> { 472 entry.getKey().setBundleType(entry.getValue()); 473 entry.getKey().addGeneralNormalizeList(BUNDLE_TYPE_PARAM); 474 return true; 475 }); 476 commandFuncs.put(PARAM_INSTALLATION_FREE, entry -> { 477 entry.getKey().setInstallationFree(entry.getValue()); 478 entry.getKey().addGeneralNormalizeList(INSTALLATION_FREE_PARAM); 479 return true; 480 }); 481 commandFuncs.put(PARAM_DELIVERY_WITH_INSTALL, entry -> { 482 entry.getKey().setDeliveryWithInstall(entry.getValue()); 483 entry.getKey().addGeneralNormalizeList(DELIVERY_WITH_INSTALL_PARAM); 484 return true; 485 }); 486 } 487 488 /** 489 * judge args is null and enter parser. 490 * 491 * @param utility common data 492 * @param args command line 493 * @return commandParser if input valid 494 */ commandParser(Utility utility, String[] args)495 public static boolean commandParser(Utility utility, String[] args) { 496 if (args == null) { 497 LOG.error(PackingToolErrMsg.COMMAND_PARSER_FAILED.toString("Parser args is null.")); 498 return false; 499 } 500 for (int i = 0; i < args.length - 1; ++i) { 501 String key = args[i]; 502 String value = args[i + 1]; 503 Map.Entry<Utility, String> entry = new AbstractMap.SimpleEntry<>(utility, value); 504 if (commandFuncs.get(key) != null) { 505 commandFuncs.get(key).apply(entry); 506 ++i; 507 } else if (CMD_PARSE_MODE.equals(key)) { 508 if (i + PARSE_MODE_VALUE_LENGTH >= args.length) { 509 LOG.error(PackingToolErrMsg.COMMAND_PARSER_FAILED.toString( 510 "Input wrong number value for --p command.")); 511 return false; 512 } 513 utility.setParseMode(args[i + 1]); 514 if (PARSE_MODE_HAPLIST.equals(utility.getParseMode())) { 515 utility.setDeviceType(args[i + PARSE_MODE_VALUE_LENGTH]); 516 } else if (PARSE_MODE_HAPINFO.equals(utility.getParseMode())) { 517 utility.setHapName(args[i + PARSE_MODE_VALUE_LENGTH]); 518 } 519 i += PARSE_MODE_VALUE_LENGTH; 520 } else { 521 LOG.warning(key + " is invalid!"); 522 } 523 } 524 return true; 525 } 526 } 527