• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 package ohos;
17 
18 import com.alibaba.fastjson.JSONValidator;
19 import java.io.File;
20 import java.io.FileInputStream;
21 import java.io.FileReader;
22 import java.io.InputStreamReader;
23 import java.io.IOException;
24 import java.io.Reader;
25 import java.nio.charset.StandardCharsets;
26 import java.util.ArrayList;
27 import java.util.Locale;
28 import java.util.Map;
29 import java.util.regex.Matcher;
30 import java.util.regex.Pattern;
31 import java.util.List;
32 import java.util.Optional;
33 
34 /**
35  * compress comment,command parser.
36  *
37  */
38 public class CompressVerify {
39     private static final String COMMA_SPLIT = ",";
40     private static final String JSON_PROFILE = "config.json";
41     private static final String MODULE_PROFILE = "module.json";
42     private static final String PATCH_PROFILE = "patch.json";
43     private static final String PKG_CONTEXT_INFO = "pkgContextInfo.json";
44     private static final String PROFILE_NAME = "CAPABILITY.profile";
45     private static final String INDEX_PROFILE = "resources.index";
46     private static final String RPCID_PROFILE = "rpcid.sc";
47     private static final String PACK_INFO = "pack.info";
48     private static final String PACK_RES = "pack.res";
49     private static final String HAP_SUFFIX = ".hap";
50     private static final String HAR_SUFFIX = ".har";
51     private static final String APP_SUFFIX = ".app";
52     private static final String APK_SUFFIX = ".apk";
53     private static final String DEX_SUFFIX = ".dex";
54     private static final String ABC_SUFFIX = ".abc";
55     private static final String SO_SUFFIX = ".so";
56     private static final String JAR_SUFFIX = ".jar";
57     private static final String TXT_SUFFIX = ".txt";
58     private static final String PNG_SUFFIX = ".png";
59     private static final String RES_SUFFIX = ".res";
60     private static final String HQF_SUFFIX = ".hqf";
61     private static final String APPQF_SUFFIX = ".appqf";
62     private static final String HSP_SUFFIX = ".hsp";
63     private static final String JSON_SUFFIX = ".json";
64     private static final String FALSE = "false";
65     private static final String ENTRY_CARD_DIRECTORY_NAME = "EntryCard";
66     private static final String VERSION_NAME_PATTERN = "^[0-9.]+|(?=.*[{])(?=.*[}])[0-9a-zA-Z_.{}]+$";
67     private static final String LINUX_FILE_SEPARATOR = "/";
68     private static final String BUNDLE_TYPE_SHARE = "shared";
69     private static final String BUNDLE_TYPE_APP = "app";
70     private static final String BUNDLE_TYPE_APP_SERVICE = "appService";
71     private static final String SKILLS_ENTITIES = "entities";
72     private static final String SKILLS_ACTIONS = "actions";
73     private static final String ACTION_SYSTEM_HOME = "action.system.home";
74     private static final String ENTITY_SYSTEM_HOME = "entity.system.home";
75     private static final String BUNDLE_NAME_PATTERN =
76             "([a-zA-Z]|[a-zA-Z]+(_*[0-9a-zA-Z])+)(\\.[0-9a-zA-Z]|\\.[0-9a-zA-Z]+(_*[0-9a-zA-Z])+){2,}";
77     private static final int BUNDLE_NAME_LEN_MIN = 7;
78     private static final int BUNDLE_NAME_LEN_MAX = 128;
79 
80     private static final Log LOG = new Log(CompressVerify.class.toString());
81 
82     private static final boolean TYPE_FILE = true;
83     private static final boolean TYPE_DIR = false;
84     private static final Integer ONE = 1;
85 
86     /**
87      * if args valid.
88      *
89      * @param utility common data
90      * @return commandVerify if command valid.
91      */
commandVerify(Utility utility)92     public static boolean commandVerify(Utility utility) {
93         if (utility == null) {
94             LOG.error(PackingToolErrMsg.COMMAND_VERIFY_FAILED.toString("Command verify utility is null."));
95             return false;
96         }
97 
98         if (!utility.getForceRewrite().isEmpty() && !"true".equals(utility.getForceRewrite())
99                 && !"false".equals(utility.getForceRewrite())) {
100             LOG.error(PackingToolErrMsg.COMMAND_VERIFY_FAILED.toString(
101                 "If the --force parameter is configured, the value must be either 'true' or 'false'."));
102             return false;
103         }
104         return commandPathVerify(utility);
105     }
106 
107     /**
108      * verify path.
109      *
110      * @param utility common data
111      * @return commandPathVerify if command valid.
112      */
commandPathVerify(Utility utility)113     private static boolean commandPathVerify(Utility utility) {
114         switch (utility.getMode()) {
115             case Utility.MODE_HAP:
116                 if (!utility.getBinPath().isEmpty() && utility.getJsonPath().isEmpty()) {
117                     return isOutPathValid(utility, HAP_SUFFIX);
118                 } else {
119                     return isVerifyValidInHapCommonMode(utility) && isVerifyValidInHapMode(utility);
120                 }
121             case Utility.MODE_HAR:
122                 return isVerifyValidInHarMode(utility);
123             case Utility.MODE_APP:
124                 return isVerifyValidInAppMode(utility);
125             case Utility.MODE_FAST_APP:
126                 return PackageUtil.isVerifyValidInFastAppMode(utility);
127             case Utility.MODE_RES:
128                 return isVerifyValidInResMode(utility);
129             case Utility.MODE_MULTI_APP:
130                 return isVerifyValidInMultiAppMode(utility);
131             case Utility.MODE_HQF:
132                 return isVerifyValidInHQFMode(utility);
133             case Utility.MODE_APPQF:
134                 return isVerifyValidInAPPQFMode(utility);
135             case Utility.MODE_HSP:
136                 return isVerifyValidInHspMode(utility);
137             case Utility.MODE_HAPADDITION:
138                 return isVerifyValidInHapAdditionMode(utility);
139             case Utility.VERSION_NORMALIZE:
140                 return validateVersionNormalizeMode(utility);
141             case Utility.PACKAGE_NORMALIZE:
142                 return validatePackageNormalizeMode(utility);
143             default:
144                 LOG.error(PackingToolErrMsg.COMMAND_MODE_INVALID.toString());
145                 return false;
146         }
147     }
148 
isBundleNameValid(String bundleName)149     private static boolean isBundleNameValid(String bundleName) {
150         if (bundleName != null &&
151                 bundleName.length() >= BUNDLE_NAME_LEN_MIN &&
152                 bundleName.length() <= BUNDLE_NAME_LEN_MAX) {
153             Pattern pattern = Pattern.compile(BUNDLE_NAME_PATTERN);
154             return pattern.matcher(bundleName).matches();
155         }
156         return false;
157     }
158 
validatePackageNormalizeMode(Utility utility)159     private static boolean validatePackageNormalizeMode(Utility utility) {
160         if (utility.getHspList().isEmpty()) {
161             LOG.error("CompressVerify::validatePackageNormalizeMode hsp-list is empty.");
162             return false;
163         } else {
164             if (!compatibleProcess(utility, utility.getHspList(), utility.getFormattedHspPathList(), HSP_SUFFIX)) {
165                 LOG.error("CompressVerify::validatePackageNormalizeMode hsp-list is invalid.");
166                 return false;
167             }
168         }
169         if (!isBundleNameValid(utility.getBundleName())) {
170             LOG.error("CompressVerify::validatePackageNormalizeMode bundle-name is invalid.");
171             return false;
172         }
173         if (utility.getVersionCode() <= 0) {
174             LOG.error("CompressVerify::validatePackageNormalizeMode version-code is invalid.");
175             return false;
176         }
177         if (utility.getOutPath().isEmpty()) {
178             LOG.error("CompressVerify::validatePackageNormalizeMode out-path is empty.");
179             return false;
180         }
181         File outDir = new File(utility.getOutPath());
182         if (!outDir.isDirectory()) {
183             LOG.error("CompressVerify::validatePackageNormalizeMode out-path is not a directory.");
184             return false;
185         }
186         return true;
187     }
188 
validateVersionNormalizeMode(Utility utility)189     private static boolean validateVersionNormalizeMode(Utility utility) {
190         if (utility.getInputList().isEmpty()) {
191             LOG.error("CompressVerify::validateVersionNormalizeMode input-list is empty.");
192             return false;
193         }
194 
195         if (!handleHapAndHspInput(utility, utility.getInputList(), utility.getFormattedHapList())) {
196             LOG.error("CompressVerify::validateVersionNormalizeMode input-list is invalid.");
197             return false;
198         }
199 
200         if (utility.getFormattedHapList().isEmpty()) {
201             LOG.error("CompressVerify::validateVersionNormalizeMode input-list is empty.");
202             return false;
203         }
204 
205         if (utility.getVersionCode() <= 0) {
206             LOG.error("CompressVerify::validateVersionNormalizeMode version-code is invalid.");
207             return false;
208         }
209 
210         if (utility.getVersionName().isEmpty()) {
211             LOG.error("CompressVerify::validateVersionNormalizeMode version-name is empty.");
212             return false;
213         }
214 
215         Pattern versionNamePattern = Pattern.compile(VERSION_NAME_PATTERN);
216         Matcher versionNameMatcher = versionNamePattern.matcher(utility.getVersionName());
217         if (!versionNameMatcher.matches()) {
218             LOG.error("CompressVerify::validateVersionNormalizeMode version-name is not valid.");
219             return false;
220         }
221 
222         if (utility.getOutPath().isEmpty()) {
223             LOG.error("CompressVerify::validateVersionNormalizeMode out-path is empty.");
224             return false;
225         }
226 
227         File outDir = new File(utility.getOutPath());
228         if (!outDir.isDirectory()) {
229             LOG.error("CompressVerify::validateVersionNormalizeMode out-path is not a directory.");
230             return false;
231         }
232         return true;
233     }
234 
isValidRpcid(Utility utility)235     private static boolean isValidRpcid(Utility utility) {
236         if (!utility.getRpcidPath().isEmpty()) {
237             File file = new File(utility.getRpcidPath());
238             if (!file.isFile()) {
239                 String errMsg = "--rpcid-path is not a file.";
240                 LOG.error(PackingToolErrMsg.HAP_MODE_ARGS_INVALID.toString(errMsg));
241                 return false;
242             }
243             if (!RPCID_PROFILE.equals(file.getName())) {
244                 String errMsg = "--rpcid-path must be the rpcid.sc file.";
245                 LOG.error(PackingToolErrMsg.HAP_MODE_ARGS_INVALID.toString(errMsg));
246                 return false;
247             }
248         }
249         return true;
250     }
251 
isValidPackInfo(Utility utility)252     private static boolean isValidPackInfo(Utility utility) {
253         if (!utility.getPackInfoPath().isEmpty()) {
254             File file = new File(utility.getPackInfoPath());
255             if (!file.isFile()) {
256                 String errMsg = "--pack-info-path is not a file.";
257                 LOG.error(PackingToolErrMsg.HAP_MODE_ARGS_INVALID.toString(errMsg));
258                 return false;
259             }
260             if (!PACK_INFO.equals(file.getName())) {
261                 String errMsg = "--pack-info-path must be the pack.info file.";
262                 LOG.error(PackingToolErrMsg.HAP_MODE_ARGS_INVALID.toString(errMsg));
263                 return false;
264             }
265         }
266         return true;
267     }
268 
isVerifyValidInHapCommonMode(Utility utility)269     private static boolean isVerifyValidInHapCommonMode(Utility utility) {
270         if (utility.getJsonPath().isEmpty()) {
271             String errMsg = "--json-path is empty";
272             LOG.error(PackingToolErrMsg.HAP_MODE_ARGS_INVALID.toString(errMsg));
273             return false;
274         }
275         if (!isPathValid(utility.getJsonPath(), TYPE_FILE, JSON_PROFILE)
276                 && !isPathValid(utility.getJsonPath(), TYPE_FILE, MODULE_PROFILE)) {
277             String errMsg = "--json-path must be the config.json file or module.json file.";
278             LOG.error(PackingToolErrMsg.HAP_MODE_ARGS_INVALID.toString(errMsg));
279             return false;
280         }
281 
282         if (!isValidRpcid(utility) || !isValidPackInfo(utility)) {
283             return false;
284         }
285 
286         if (!utility.getApkPath().isEmpty() && !compatibleProcess(utility, utility.getApkPath(),
287                 utility.getFormattedApkPathList(), APK_SUFFIX)) {
288             String errMsg = "--shell-apk-path is invalid.";
289             LOG.error(PackingToolErrMsg.HAP_MODE_ARGS_INVALID.toString(errMsg));
290             return false;
291         }
292 
293         if (!utility.getProfilePath().isEmpty()) {
294             File file = new File(utility.getProfilePath());
295             if (!file.isFile() || !PROFILE_NAME.equals(file.getName())) {
296                 String errMsg = "--profile-path must be the CAPABILITY.profile file.";
297                 LOG.error(PackingToolErrMsg.HAP_MODE_ARGS_INVALID.toString(errMsg));
298                 return false;
299             }
300         }
301 
302         if (!utility.getDexPath().isEmpty() && !compatibleProcess(utility, utility.getDexPath(),
303                 utility.getFormattedDexPathList(), DEX_SUFFIX)) {
304             String errMsg = "--dex-path is invalid.";
305             LOG.error(PackingToolErrMsg.HAP_MODE_ARGS_INVALID.toString(errMsg));
306             return false;
307         }
308 
309         if (!utility.getAbcPath().isEmpty() && !compatibleProcess(utility, utility.getAbcPath(),
310                 utility.getFormattedAbcPathList(), ABC_SUFFIX)) {
311             String errMsg = "--abc-path is invalid.";
312             LOG.error(PackingToolErrMsg.HAP_MODE_ARGS_INVALID.toString(errMsg));
313             return false;
314         }
315 
316         if (!utility.getDirList().isEmpty() && !splitDirList(utility, utility.getDirList(),
317                 utility.getFormatedDirList())) {
318             String errMsg = "--dir-list is invalid.";
319             LOG.error(PackingToolErrMsg.HAP_MODE_ARGS_INVALID.toString(errMsg));
320             return false;
321         }
322         if (!utility.getPkgContextPath().isEmpty()) {
323             File file = new File(utility.getPkgContextPath());
324             if (!file.isFile() || !PKG_CONTEXT_INFO.equals(file.getName())) {
325                 String errMsg = "--pkg-context-path file must be the pkgContextInfo.json file.";
326                 LOG.error(PackingToolErrMsg.HAP_MODE_ARGS_INVALID.toString(errMsg));
327                 return false;
328             }
329         }
330         return true;
331     }
332 
333     /**
334      * parse and check args if valid in hap mode.
335      *
336      * @param utility common data
337      * @return isVerifyValidInHapMode if verify valid in hap mode.
338      */
isVerifyValidInHapMode(Utility utility)339     private static boolean isVerifyValidInHapMode(Utility utility) {
340         File file = new File(utility.getIndexPath());
341         if (!utility.getIndexPath().isEmpty() && !file.isFile() && INDEX_PROFILE.equals(file.getName())) {
342             String errMsg = "--index-path must be the resources.index file.";
343             LOG.error(PackingToolErrMsg.HAP_MODE_ARGS_INVALID.toString(errMsg));
344             return false;
345         }
346 
347         if (!utility.getSoPath().isEmpty() &&
348                 !compatibleProcess(utility, utility.getSoPath(), utility.getFormattedSoPathList(), SO_SUFFIX)) {
349             String errMsg = "--maple-so-path is invalid.";
350             LOG.error(PackingToolErrMsg.HAP_MODE_ARGS_INVALID.toString(errMsg));
351             return false;
352         }
353 
354         if (!utility.getAbilitySoPath().isEmpty() && !compatibleProcess(utility, utility.getAbilitySoPath(),
355                 utility.getFormattedAbilitySoPathList(), SO_SUFFIX)) {
356             String errMsg = "--ability-so-path is invalid.";
357             LOG.error(PackingToolErrMsg.HAP_MODE_ARGS_INVALID.toString(errMsg));
358             return false;
359         }
360 
361         if (isHapPathValid(utility.getSoDir())) {
362             String errMsg = "--maple-so-dir is invalid.";
363             LOG.error(PackingToolErrMsg.HAP_MODE_ARGS_INVALID.toString(errMsg));
364             return false;
365         }
366 
367         if (isHapPathValid(utility.getLibPath())) {
368             String errMsg = "--lib-path is invalid.";
369             LOG.error(PackingToolErrMsg.HAP_MODE_ARGS_INVALID.toString(errMsg));
370             return false;
371         }
372 
373         if (isHapPathValid(utility.getHnpPath())) {
374             String errMsg = "--hnp-path is invalid.";
375             LOG.error(PackingToolErrMsg.HAP_MODE_ARGS_INVALID.toString(errMsg));
376             return false;
377         }
378 
379         if (isHapPathValid(utility.getResPath())) {
380             String errMsg = "--res-path is invalid.";
381             LOG.error(PackingToolErrMsg.HAP_MODE_ARGS_INVALID.toString(errMsg));
382             return false;
383         }
384 
385         if (isHapPathValid(utility.getResourcesPath())) {
386             String errMsg = "--resources-path is invalid.";
387             LOG.error(PackingToolErrMsg.HAP_MODE_ARGS_INVALID.toString(errMsg));
388             return false;
389         }
390 
391         if (isHapPathValid(utility.getAssetsPath())) {
392             String errMsg = "--assets-path is invalid.";
393             LOG.error(PackingToolErrMsg.HAP_MODE_ARGS_INVALID.toString(errMsg));
394             return false;
395         }
396 
397         if (isHapPathValid(utility.getSharedLibsPath())) {
398             String errMsg = "--shared-libs-path is invalid.";
399             LOG.error(PackingToolErrMsg.HAP_MODE_ARGS_INVALID.toString(errMsg));
400             return false;
401         }
402 
403         if (!utility.getJarPath().isEmpty()
404                 && !compatibleProcess(utility, utility.getJarPath(), utility.getFormattedJarPathList(), JAR_SUFFIX)) {
405             String errMsg = "--jar-path is invalid.";
406             LOG.error(PackingToolErrMsg.HAP_MODE_ARGS_INVALID.toString(errMsg));
407             return false;
408         }
409 
410         if (!utility.getTxtPath().isEmpty()
411                 && !compatibleProcess(utility, utility.getTxtPath(), utility.getFormattedTxtPathList(), TXT_SUFFIX)) {
412             String errMsg = "--txt-path is invalid.";
413             LOG.error(PackingToolErrMsg.HAP_MODE_ARGS_INVALID.toString(errMsg));
414             return false;
415         }
416 
417         if (isHapPathValid(utility.getANPath())) {
418             String errMsg = "--an-path is invalid.";
419             LOG.error(PackingToolErrMsg.HAP_MODE_ARGS_INVALID.toString(errMsg));
420             return false;
421         }
422 
423         if (!utility.getEtsPath().isEmpty() && !isPathExists(utility.getEtsPath())) {
424             String errMsg = "--ets-path is invalid.";
425             LOG.error(PackingToolErrMsg.HAP_MODE_ARGS_INVALID.toString(errMsg));
426             return false;
427         }
428 
429         return isOutPathValid(utility, HAP_SUFFIX);
430     }
431 
432     /**
433      * check hap path if valid
434      *
435      * @param path path input
436      * @return isPathValid if path verify
437      */
isHapPathValid(String path)438     private static boolean isHapPathValid(String path) {
439         return (!path.isEmpty() && !isPathValid(path, TYPE_DIR, null));
440     }
441 
442     /**
443      * parse and check args if valid in har mode.
444      *
445      * @param utility common data
446      * @return isVerifyValidInHarMode if verify valid in har mode.
447      */
isVerifyValidInHarMode(Utility utility)448     private static boolean isVerifyValidInHarMode(Utility utility) {
449         if (utility.getJsonPath().isEmpty()) {
450             LOG.error("CompressVerify::isArgsValidInHarMode json-path is empty.");
451             return false;
452         }
453 
454         if (!isPathValid(utility.getJsonPath(), TYPE_FILE, JSON_PROFILE)
455                 && !isPathValid(utility.getJsonPath(), TYPE_FILE, MODULE_PROFILE)) {
456             LOG.error("CompressVerify::isArgsValidInHarMode json-path must be config.json file.");
457             return false;
458         }
459 
460         if (!utility.getJarPath().isEmpty()
461                 && !compatibleProcess(utility, utility.getJarPath(), utility.getFormattedJarPathList(), JAR_SUFFIX)) {
462             LOG.error("CompressVerify::isArgsValidInHarMode jar-path is invalid.");
463             return false;
464         }
465 
466         if (!utility.getTxtPath().isEmpty()
467                 && !compatibleProcess(utility, utility.getTxtPath(), utility.getFormattedTxtPathList(), TXT_SUFFIX)) {
468             LOG.error("CompressVerify::isArgsValidInHarMode txt-path is invalid.");
469             return false;
470         }
471 
472         if (!utility.getLibPath().isEmpty() && !isPathValid(utility.getLibPath(), TYPE_DIR, null)) {
473             LOG.error("CompressVerify::isArgsValidInHarMode lib-path is invalid.");
474             return false;
475         }
476 
477         if (!utility.getResPath().isEmpty() && !isPathValid(utility.getResPath(), TYPE_DIR, null)) {
478             LOG.error("CompressVerify::isArgsValidInHarMode res-path is invalid.");
479             return false;
480         }
481 
482         if (utility.getResourcesPath().isEmpty() || !isPathValid(utility.getResourcesPath(), TYPE_DIR, null)) {
483             LOG.error("CompressVerify::isArgsValidInHarMode resources-path is invalid.");
484             return false;
485         }
486 
487         if (!utility.getAssetsPath().isEmpty() && !isPathValid(utility.getAssetsPath(), TYPE_DIR, null)) {
488             LOG.error("CompressVerify::isArgsValidInHarMode assets-path is invalid.");
489             return false;
490         }
491 
492         return isOutPathValid(utility, HAR_SUFFIX);
493     }
494 
495     /**
496      * parse and check args if valid in app mode.
497      *
498      * @param utility common data
499      * @return isVerifyValidInAppMode if verify valid in app mode.
500      */
isVerifyValidInAppMode(Utility utility)501     private static boolean isVerifyValidInAppMode(Utility utility) {
502         if (!checkBundleTypeConsistency(utility)) {
503             String errMsg = "The bundleType is inconsistent for different HAP and HSP modules.";
504             LOG.error(PackingToolErrMsg.APP_MODE_ARGS_INVALID.toString(errMsg));
505             return false;
506         }
507 
508         if (!checkInputModulePath(utility)) {
509             LOG.warning("CompressVerify::isArgsValidInAppMode input hap-path or hspPath is invalid.");
510         }
511 
512         if (!utility.getHapPath().isEmpty()
513                 && !compatibleProcess(utility, utility.getHapPath(), utility.getFormattedHapPathList(), HAP_SUFFIX)) {
514             String errMsg = "--hap-path is invalid.";
515             LOG.error(PackingToolErrMsg.APP_MODE_ARGS_INVALID.toString(errMsg));
516             return false;
517         }
518 
519         if (!utility.getHspPath().isEmpty()
520                 && !compatibleProcess(utility, utility.getHspPath(), utility.getFormattedHspPathList(), HSP_SUFFIX)) {
521             String errMsg = "--hsp-path is invalid.";
522             LOG.error(PackingToolErrMsg.APP_MODE_ARGS_INVALID.toString(errMsg));
523             return false;
524         }
525 
526         if (utility.getPackInfoPath().isEmpty()) {
527             String errMsg = "--pack-info-path is empty.";
528             LOG.error(PackingToolErrMsg.APP_MODE_ARGS_INVALID.toString(errMsg));
529             return false;
530         }
531 
532         File file = new File(utility.getPackInfoPath());
533         if (!file.isFile() || !PACK_INFO.equals(file.getName())) {
534             String errMsg = "--pack-info-path is invalid.";
535             LOG.error(PackingToolErrMsg.APP_MODE_ARGS_INVALID.toString(errMsg));
536             return false;
537         }
538 
539         if (!isValidEncryptJsonFile(utility)) {
540             String errMsg = "--encrypt-path is invalid.";
541             LOG.error(PackingToolErrMsg.APP_MODE_ARGS_INVALID.toString(errMsg));
542             return false;
543         }
544 
545         if (!utility.getSignaturePath().isEmpty() && !(new File(utility.getSignaturePath())).isFile()) {
546             String errMsg = "--signature-path is invalid.";
547             LOG.error(PackingToolErrMsg.APP_MODE_ARGS_INVALID.toString(errMsg));
548             return false;
549         }
550 
551         if (!utility.getCertificatePath().isEmpty() && !(new File(utility.getCertificatePath())).isFile()) {
552             String errMsg = "--certificate-path is invalid.";
553             LOG.error(PackingToolErrMsg.APP_MODE_ARGS_INVALID.toString(errMsg));
554             return false;
555         }
556 
557         if (!utility.getEntryCardPath().isEmpty() &&
558                 !compatibleProcess(utility, utility.getEntryCardPath(),
559                         utility.getformattedEntryCardPathList(), PNG_SUFFIX)) {
560             String errMsg = "--entrycard-path is invalid.";
561             LOG.error(PackingToolErrMsg.APP_MODE_ARGS_INVALID.toString(errMsg));
562             return false;
563         }
564         if (!utility.getPackResPath().isEmpty() && !isPathValid(utility.getPackResPath(), TYPE_FILE, PACK_RES)) {
565             String errMsg = "--pack-res-path is invalid.";
566             LOG.error(PackingToolErrMsg.APP_MODE_ARGS_INVALID.toString(errMsg));
567             return false;
568         }
569 
570         return isOutPathValid(utility, APP_SUFFIX);
571     }
572 
checkBundleTypeConsistency(Utility utility)573     private static boolean checkBundleTypeConsistency(Utility utility) {
574         String bundleType = new String();
575         List<String> tmpHapPathList = new ArrayList<>();
576         List<String> tmpHspPathList = new ArrayList<>();
577         compatibleProcess(utility, utility.getHapPath(), tmpHapPathList, HAP_SUFFIX);
578         compatibleProcess(utility, utility.getHspPath(), tmpHspPathList, HSP_SUFFIX);
579         try {
580             if (!tmpHapPathList.isEmpty()) {
581                 HapVerifyInfo hapVerifyInfo = Compressor.parseStageHapVerifyInfo(tmpHapPathList.get(0));
582                 bundleType = hapVerifyInfo.getBundleType();
583             } else if (!tmpHspPathList.isEmpty()) {
584                 HapVerifyInfo hapVerifyInfo = Compressor.parseStageHapVerifyInfo(tmpHspPathList.get(0));
585                 bundleType = hapVerifyInfo.getBundleType();
586             }
587             for (String hapPath : tmpHapPathList) {
588                 HapVerifyInfo hapVerifyInfo = Compressor.parseStageHapVerifyInfo(hapPath);
589                 if (!bundleType.equals(hapVerifyInfo.getBundleType())) {
590                     LOG.error(PackingToolErrMsg.CHECK_BUNDLETYPE_CONSISTENCY_FAILED.toString(
591                         "The bundleType is not same for different HAP modules."));
592                     return false;
593                 }
594             }
595             for (String hspPath : tmpHspPathList) {
596                 HapVerifyInfo hapVerifyInfo = Compressor.parseStageHapVerifyInfo(hspPath);
597                 if (!bundleType.equals(hapVerifyInfo.getBundleType())) {
598                     LOG.error(PackingToolErrMsg.CHECK_BUNDLETYPE_CONSISTENCY_FAILED.toString(
599                         "The bundleType is not same for different HSP modules."));
600                     return false;
601                 }
602             }
603         } catch (BundleException e) {
604             return true;
605         }
606         return true;
607     }
608 
checkInputModulePath(Utility utility)609     private static boolean checkInputModulePath(Utility utility) {
610         boolean isSharedApp = isSharedApp(utility);
611         boolean isAppService = isAppService(utility);
612         if (utility.getHapPath().isEmpty() && !isSharedApp && !isAppService) {
613             LOG.warning("CompressVerify::CheckInputModulePath hap-path is empty.");
614             return false;
615         }
616 
617         if (utility.getHspPath().isEmpty() && isAppService) {
618             LOG.warning("CompressVerify::CheckInputModulePath hsp-path is empty.");
619             return false;
620         }
621         return true;
622     }
623 
624     /**
625      * parse and check args if valid in multiApp mode.
626      *
627      * @param utility common data
628      * @return isVerifyValidInMultiAppMode if verify valid in multiApp mode.
629      */
isVerifyValidInMultiAppMode(Utility utility)630     private static boolean isVerifyValidInMultiAppMode(Utility utility) {
631         if (utility.getAppList().isEmpty() && utility.getHapList().isEmpty() && utility.getHspList().isEmpty()) {
632             LOG.error("CompressVerify::isVerifyValidInMultiAppMode input app-list, hap-list and hsp-list are null.");
633             return false;
634         }
635         if (!utility.getAppList().isEmpty()) {
636             if (!compatibleProcess(utility, utility.getAppList(), utility.getFormattedAppList(), APP_SUFFIX)) {
637                 LOG.error("CompressVerify::isVerifyValidInMultiAppMode app-list is invalid.");
638                 return false;
639             }
640         }
641         if (!utility.getHapList().isEmpty()) {
642             if (!compatibleProcess(utility, utility.getHapList(), utility.getFormattedHapList(), HAP_SUFFIX)) {
643                 LOG.error("CompressVerify::isVerifyValidInMultiAppMode hap-list is invalid.");
644                 return false;
645             }
646         }
647 
648         if (!utility.getHspList().isEmpty()) {
649             if (!compatibleProcess(utility, utility.getHspList(), utility.getFormattedHapList(), HSP_SUFFIX)) {
650                 LOG.error("CompressVerify::isVerifyValidInMultiAppMode hsp-list is invalid.");
651                 return false;
652             }
653         }
654 
655         if (!isValidEncryptJsonFile(utility)) {
656             LOG.error("CompressVerify::isVerifyValidInMultiAppMode encrypt-path is invalid.");
657             return false;
658         }
659 
660         File outFile = new File(utility.getOutPath());
661         if (("false".equals(utility.getForceRewrite())) && outFile.exists()) {
662             LOG.error("CompressVerify::isVerifyValidInMultiAppMode out file already existed.");
663             return false;
664         }
665         if (!outFile.getName().toLowerCase(Locale.ENGLISH).endsWith(APP_SUFFIX)) {
666             LOG.error("CompressVerify::isVerifyValidInMultiAppMode out-path must end with .app.");
667             return false;
668         }
669         return true;
670     }
671 
672 
673     /**
674      * parse and check args if valid in res mode.
675      *
676      * @param utility common data
677      * @return isVerifyValidInAppMode if verify valid in app mode.
678      */
isVerifyValidInResMode(Utility utility)679     private static boolean isVerifyValidInResMode(Utility utility) {
680         if (!isPathValid(utility.getPackInfoPath(), TYPE_FILE, PACK_INFO)) {
681             LOG.error("CompressVerify::isArgsValidInResMode pack-info-path is invalid.");
682             return false;
683         }
684 
685         if (!isDirectoryValidStrictCase(utility.getEntryCardPath(), ENTRY_CARD_DIRECTORY_NAME)) {
686             LOG.error("CompressVerify::isArgsValidInResMode the level-1 directory name must is EntryCard" +
687                 ", current is " + utility.getEntryCardPath());
688             return false;
689         }
690         if (!compatibleProcess(utility, utility.getEntryCardPath(),
691                 utility.getformattedEntryCardPathList(), PNG_SUFFIX)) {
692             LOG.error("CompressVerify::isArgsValidInResMode entrycard-path is invalid.");
693             return false;
694         }
695         return isOutPathValid(utility, RES_SUFFIX);
696     }
697 
isVerifyValidInHQFMode(Utility utility)698     private static boolean isVerifyValidInHQFMode(Utility utility) {
699         if (utility.getJsonPath().isEmpty()) {
700             LOG.error("must input patch.json file when pack hqf file.");
701             return false;
702         }
703         if (!utility.getEtsPath().isEmpty()) {
704             if (!isPathValid(utility.getEtsPath(), TYPE_DIR, null)) {
705                 LOG.error("must input valid ets path when pack hqf file.");
706                 return false;
707             }
708         }
709         if (!isPathValid(utility.getJsonPath(), TYPE_FILE, PATCH_PROFILE)) {
710             LOG.error("input patch.json is invalid when pack hqf file.");
711             return false;
712         }
713         if (!utility.getLibPath().isEmpty()) {
714             if (!isPathValid(utility.getLibPath(), TYPE_DIR, null)) {
715                 LOG.error("input lib path is invalid when pack hqf file.");
716                 return false;
717             }
718         }
719         if (!utility.getResourcesPath().isEmpty()) {
720             if (!isPathValid(utility.getResourcesPath(), TYPE_DIR, null)) {
721                 LOG.error("input resources path is invalid when pack hqf file.");
722                 return false;
723             }
724         }
725         File outFile = new File(utility.getOutPath());
726         if ((FALSE.equals(utility.getForceRewrite())) && (outFile.exists())) {
727             LOG.error(outFile.getName() + " already exist.");
728             return false;
729         }
730         if (!utility.getOutPath().endsWith(HQF_SUFFIX)) {
731             LOG.error("input out file must end with .hqf.");
732             return false;
733         }
734         return true;
735     }
736 
isVerifyValidInAPPQFMode(Utility utility)737     private static boolean isVerifyValidInAPPQFMode(Utility utility) {
738         if (utility.getHqfList().isEmpty()) {
739             LOG.error("input hqf list is empty.");
740             return false;
741         }
742         if (!compatibleProcess(utility, utility.getHqfList(), utility.getFormatedHQFList(), HQF_SUFFIX)) {
743             LOG.error("input hqf list is invalid.");
744             return false;
745         }
746         File outFile = new File(utility.getOutPath());
747         if ((FALSE.equals(utility.getForceRewrite())) && outFile.exists()) {
748             LOG.error("Error out file already existed.");
749             return false;
750         }
751         if (!outFile.getName().toLowerCase(Locale.ENGLISH).endsWith(APPQF_SUFFIX)) {
752             LOG.error("Error out-path must end with .app.");
753             return false;
754         }
755         return true;
756     }
757 
758     /**
759      * Compatible file input and directory input
760      *
761      * @param utility   common data
762      * @param inputPath input path
763      * @param fileList  save files' path with list
764      * @param suffix    process type
765      * @return Returns {@code true} if the compatible is successful; returns {@code false} otherwise.
766      */
compatibleProcess(Utility utility, String inputPath, List<String> fileList, String suffix)767     public static boolean compatibleProcess(Utility utility, String inputPath,
768         List<String> fileList, String suffix) {
769         if (isPathValid(inputPath, TYPE_DIR, null)) {
770             File inputFile = new File(inputPath);
771             File[] files = inputFile.listFiles();
772             if (files == null) {
773                 return true;
774             }
775             for (File fileItem : files) {
776                 if (fileItem.getName().toLowerCase(Locale.ENGLISH).endsWith(suffix)) {
777                     fileList.add(fileItem.toString());
778                 }
779             }
780             return true;
781         } else {
782             String formattedPathItem = "";
783             List<String> pathList = removeDuplicatePath(inputPath);
784             for (String pathItem : pathList) {
785                 formattedPathItem = utility.getFormattedPath(pathItem);
786                 if (!isPathValid(formattedPathItem, TYPE_FILE, suffix)) {
787                     return false;
788                 }
789                 fileList.add(formattedPathItem);
790             }
791             return true;
792         }
793     }
794 
handleHapAndHspInput(Utility utility, String inputPath, List<String> fileList)795     private static boolean handleHapAndHspInput(Utility utility, String inputPath, List<String> fileList) {
796         if (isPathValid(inputPath, TYPE_DIR, null)) {
797             File inputFile = new File(inputPath);
798             File[] files = inputFile.listFiles();
799             if (files == null) {
800                 return true;
801             }
802             for (File fileItem : files) {
803                 if (fileItem.getName().toLowerCase(Locale.ENGLISH).endsWith(HSP_SUFFIX) ||
804                     fileItem.getName().toLowerCase(Locale.ENGLISH).endsWith(HAP_SUFFIX)) {
805                     fileList.add(fileItem.toString());
806                 }
807             }
808             return true;
809         } else {
810             String formattedPathItem = "";
811             List<String> pathList = removeDuplicatePath(inputPath);
812             for (String pathItem : pathList) {
813                 formattedPathItem = utility.getFormattedPath(pathItem);
814                 if (!isPathValid(formattedPathItem, TYPE_FILE, HSP_SUFFIX) &&
815                     !isPathValid(formattedPathItem, TYPE_FILE, HAP_SUFFIX)) {
816                     LOG.error("input file " + formattedPathItem + " not valid");
817                     return false;
818                 }
819                 fileList.add(formattedPathItem);
820             }
821             return true;
822         }
823     }
824 
splitDirList(Utility utility, String dirList, List<String> fileList)825     private static boolean splitDirList(Utility utility, String dirList, List<String> fileList) {
826         List<String> pathList = removeDuplicatePath(dirList);
827         for (String pathItem : pathList) {
828             String formattedPathItem = utility.getFormattedPath(pathItem);
829             if (!isPathValid(formattedPathItem, TYPE_DIR, null)) {
830                 return false;
831             }
832             fileList.add(formattedPathItem);
833         }
834         return true;
835     }
836 
837     /**
838      * turn input path block to formatted path list
839      *
840      * @param utility common data
841      * @param suffix  used to determine type
842      * @return isVerifyValidInAppMode if verify valid in app mode.
843      */
isOutPathValid(Utility utility, String suffix)844     private static boolean isOutPathValid(Utility utility, String suffix) {
845         File outFile = new File(utility.getOutPath());
846 
847         if (("false".equals(utility.getForceRewrite())) && (outFile.exists())) {
848             LOG.error(PackingToolErrMsg.OUT_PATH_INVALID.toString("--out-path file already existed."));
849             return false;
850         }
851 
852         if (HAP_SUFFIX.equals(suffix)) {
853             if (!outFile.getName().toLowerCase(Locale.ENGLISH).endsWith(HAP_SUFFIX)) {
854                 LOG.error(PackingToolErrMsg.OUT_PATH_INVALID.toString("--out-path must end with .hap."));
855                 return false;
856             } else {
857                 return true;
858             }
859         }
860 
861         if (HAR_SUFFIX.equals(suffix)) {
862             if (!outFile.getName().toLowerCase(Locale.ENGLISH).endsWith(HAR_SUFFIX)) {
863                 LOG.error(PackingToolErrMsg.OUT_PATH_INVALID.toString("--out-path must end with .har."));
864                 return false;
865             } else {
866                 return true;
867             }
868         }
869 
870         if (APP_SUFFIX.equals(suffix)) {
871             if (!outFile.getName().toLowerCase(Locale.ENGLISH).endsWith(APP_SUFFIX)) {
872                 LOG.error(PackingToolErrMsg.OUT_PATH_INVALID.toString("--out-path must end with .app."));
873                 return false;
874             } else {
875                 return true;
876             }
877         }
878 
879         if (RES_SUFFIX.equals(suffix)) {
880             if (!outFile.getName().toLowerCase(Locale.ENGLISH).endsWith(RES_SUFFIX)) {
881                 LOG.error(PackingToolErrMsg.OUT_PATH_INVALID.toString("--out-path must end with .res."));
882                 return false;
883             } else {
884                 return true;
885             }
886         }
887 
888         if (HSP_SUFFIX.equals(suffix)) {
889             if (!outFile.getName().toLowerCase(Locale.ENGLISH).endsWith(HSP_SUFFIX)) {
890                 LOG.error(PackingToolErrMsg.OUT_PATH_INVALID.toString("--out-path must end with .hsp."));
891                 return false;
892             } else {
893                 return true;
894             }
895         }
896         return false;
897     }
898 
899     /**
900      * check path if valid
901      *
902      * @param path   path input
903      * @param isFile type input
904      * @param flag   flag input
905      * @return isPathValid if path verify
906      */
isPathValid(String path, boolean isFile, String flag)907     private static boolean isPathValid(String path, boolean isFile, String flag) {
908         File file = new File(path);
909         if (isFile && (file.isFile()) && file.getName().toLowerCase(Locale.ENGLISH).endsWith(flag)) {
910             return true;
911         }
912         return (!isFile) && file.isDirectory();
913     }
914 
isPathExists(String path)915     private static boolean isPathExists(String path) {
916         if (path != null && !path.isEmpty()) {
917             File filePath = new File(path);
918             return filePath.exists();
919         }
920         return false;
921     }
922 
isDirectoryValidStrictCase(String path, String directoryName)923     private static boolean isDirectoryValidStrictCase(String path, String directoryName) {
924         File file = new File(path);
925         if (!file.exists()) {
926             LOG.error("CompressVerify::isDirectoryValidStrictCase directory is not exist, directoryPath: "
927                 + path + ".");
928             return false;
929         }
930         if (file.isDirectory()) {
931             return directoryName.equals(file.getName());
932         }
933         return false;
934     }
935 
936     /**
937      * remove duplicate in path.
938      *
939      * @param path input path, use comma separate.
940      * @return result list
941      */
removeDuplicatePath(String path)942     private static List<String> removeDuplicatePath(String path) {
943         String[] array = path.split(COMMA_SPLIT);
944         List<String> list = new ArrayList<>();
945 
946         for (String item : array) {
947             if (!list.contains(item)) {
948                 list.add(item);
949             }
950         }
951         return list;
952     }
953 
isVerifyValidInHspMode(Utility utility)954     private static boolean isVerifyValidInHspMode(Utility utility) {
955         if (utility.getJsonPath().isEmpty()) {
956             String errMsg = "--json-path is empty.";
957             LOG.error(PackingToolErrMsg.HSP_MODE_ARGS_INVALID.toString(errMsg));
958             return false;
959         }
960 
961         if (!isPathValid(utility.getJsonPath(), TYPE_FILE, MODULE_PROFILE)) {
962             String errMsg = "--json-path must be the module.json file.";
963             LOG.error(PackingToolErrMsg.HSP_MODE_ARGS_INVALID.toString(errMsg));
964             return false;
965         }
966 
967         if ((isBundleTypeShared(utility) || isBundleTypeAppService(utility))) {
968             boolean hspHasAbilities = hspHasAbilities(utility);
969             boolean hspHasExtensionAbilities = hspHasExtensionAbilities(utility);
970             if (hspHasAbilities && hspHasExtensionAbilities) {
971                 String errMsg = "shared/appService hsp has abilities and extensionAbilities.";
972                 LOG.error(PackingToolErrMsg.HSP_MODE_ARGS_INVALID.toString(errMsg));
973                 return false;
974             }
975             if (hspHasAbilities) {
976                 LOG.error(PackingToolErrMsg.HSP_MODE_ARGS_INVALID.toString("shared/appService hsp has abilities."));
977                 return false;
978             }
979             if (hspHasExtensionAbilities) {
980                 LOG.error(PackingToolErrMsg.HSP_MODE_ARGS_INVALID.toString("shared/appService hsp has extensionAbilities."));
981                 return false;
982             }
983         }
984 
985         if(hasHomeAbility(utility)) {
986             LOG.error(PackingToolErrMsg.HSP_MODE_ARGS_INVALID.toString("hsp has entry ability."));
987             return false;
988         }
989 
990         if (hasHomeExtensionAbility(utility)) {
991             LOG.error(PackingToolErrMsg.HSP_MODE_ARGS_INVALID.toString("hsp has entry extensionAbility."));
992             return false;
993         }
994 
995         if (!utility.getJarPath().isEmpty()
996                 && !compatibleProcess(utility, utility.getJarPath(), utility.getFormattedJarPathList(), JAR_SUFFIX)) {
997             String errMsg = "--jar-path is invalid.";
998             LOG.error(PackingToolErrMsg.HSP_MODE_ARGS_INVALID.toString(errMsg));
999             return false;
1000         }
1001 
1002         if (!utility.getTxtPath().isEmpty()
1003                 && !compatibleProcess(utility, utility.getTxtPath(), utility.getFormattedTxtPathList(), TXT_SUFFIX)) {
1004             String errMsg = "--txt-path is invalid.";
1005             LOG.error(PackingToolErrMsg.HSP_MODE_ARGS_INVALID.toString(errMsg));
1006             return false;
1007         }
1008 
1009         if (!utility.getLibPath().isEmpty() && !isPathValid(utility.getLibPath(), TYPE_DIR, null)) {
1010             String errMsg = "--lib-path is invalid.";
1011             LOG.error(PackingToolErrMsg.HSP_MODE_ARGS_INVALID.toString(errMsg));
1012             return false;
1013         }
1014 
1015         if (!utility.getResPath().isEmpty() && !isPathValid(utility.getResPath(), TYPE_DIR, null)) {
1016             String errMsg = "--res-path is invalid.";
1017             LOG.error(PackingToolErrMsg.HSP_MODE_ARGS_INVALID.toString(errMsg));
1018             return false;
1019         }
1020 
1021         if (!utility.getResourcesPath().isEmpty() && !isPathValid(utility.getResourcesPath(), TYPE_DIR, null)) {
1022             String errMsg = "--resources-path is invalid.";
1023             LOG.error(PackingToolErrMsg.HSP_MODE_ARGS_INVALID.toString(errMsg));
1024             return false;
1025         }
1026 
1027         if (!utility.getAssetsPath().isEmpty() && !isPathValid(utility.getAssetsPath(), TYPE_DIR, null)) {
1028             String errMsg = "--assets-path is invalid.";
1029             LOG.error(PackingToolErrMsg.HSP_MODE_ARGS_INVALID.toString(errMsg));
1030             return false;
1031         }
1032 
1033         if (!utility.getDirList().isEmpty() && !splitDirList(utility, utility.getDirList(),
1034                 utility.getFormatedDirList())) {
1035             String errMsg = "--dir-list is invalid.";
1036             LOG.error(PackingToolErrMsg.HSP_MODE_ARGS_INVALID.toString(errMsg));
1037             return false;
1038         }
1039 
1040         if (isHapPathValid(utility.getAPPath())) {
1041             String errMsg = "--ap-path is invalid.";
1042             LOG.error(PackingToolErrMsg.HSP_MODE_ARGS_INVALID.toString(errMsg));
1043             return false;
1044         }
1045 
1046         if (isHapPathValid(utility.getANPath())) {
1047             String errMsg = "--an-path is invalid.";
1048             LOG.error(PackingToolErrMsg.HSP_MODE_ARGS_INVALID.toString(errMsg));
1049             return false;
1050         }
1051 
1052         if (!utility.getPkgContextPath().isEmpty()) {
1053             File file = new File(utility.getPkgContextPath());
1054             if (!file.isFile() || !PKG_CONTEXT_INFO.equals(file.getName())) {
1055                 String errMsg = "--pkg-context-path file must be the pkgContextInfo.json file.";
1056                 LOG.error(PackingToolErrMsg.HSP_MODE_ARGS_INVALID.toString(errMsg));
1057                 return false;
1058             }
1059         }
1060 
1061         if (!utility.getEtsPath().isEmpty() && !isPathExists(utility.getEtsPath())) {
1062             String errMsg = "--ets-path is invalid.";
1063             LOG.error(PackingToolErrMsg.HSP_MODE_ARGS_INVALID.toString(errMsg));
1064             return false;
1065         }
1066 
1067         return isOutPathValid(utility, HSP_SUFFIX);
1068     }
1069 
isVerifyValidInHapAdditionMode(Utility utility)1070     private static boolean isVerifyValidInHapAdditionMode(Utility utility) {
1071         if (utility.getHapPath().isEmpty()) {
1072             LOG.error("CompressVerify::isVerifyValidInHapAdditionMode hapPath is empty.");
1073             return false;
1074         }
1075         String hapPath = utility.getAbsoluteHapPath();
1076         File hapFile = new File(hapPath);
1077         if (hapFile.isDirectory()) {
1078             LOG.error("CompressVerify::isVerifyValidInHapAdditionMode hapPath cannot be a folder.");
1079             return false;
1080         }
1081         if (!(hapPath.endsWith(HAP_SUFFIX) || hapPath.endsWith(HSP_SUFFIX))) {
1082             LOG.error("CompressVerify::isVerifyValidInHapAdditionMode hapPath is invalid.");
1083             return false;
1084         }
1085         if (!hapFile.exists()) {
1086             LOG.error("CompressVerify::isVerifyValidInHapAdditionMode hap file does not exist.");
1087             return false;
1088         }
1089         if (utility.getJsonPath().isEmpty()) {
1090             LOG.error("CompressVerify::isVerifyValidInHapAdditionMode jsonPath is empty.");
1091             return false;
1092         }
1093         if (!utility.getJsonPath().endsWith(JSON_SUFFIX)) {
1094             LOG.error("CompressVerify::isVerifyValidInHapAdditionMode jsonPath is invalid.");
1095             return false;
1096         }
1097         File jsonFile = new File(utility.getJsonPath());
1098         if (!jsonFile.exists()) {
1099             LOG.error("CompressVerify::isVerifyValidInHapAdditionMode json file does not exist.");
1100             return false;
1101         }
1102         if (!checkJsonIsValid(jsonFile)) {
1103             LOG.error("CompressVerify::isVerifyValidInHapAdditionMode json format is incorrect.");
1104             return false;
1105         }
1106 
1107         if (utility.getOutPath().isEmpty()) {
1108             LOG.error("CompressVerify::isVerifyValidInHapAdditionMode outPath is empty.");
1109             return false;
1110         }
1111         File dir = new File(utility.getOutPath());
1112         if (dir.exists() && dir.isFile()) {
1113             LOG.error("CompressVerify::isVerifyValidInHapAdditionMode outPath is file.");
1114             return false;
1115         }
1116         File absoluteHapFile = new File(utility.getAbsoluteHapPath());
1117         String hapFileName = absoluteHapFile.getName();
1118         String destPath = utility.getOutPath() + LINUX_FILE_SEPARATOR + hapFileName;
1119         File destFile = new File(destPath);
1120         if ("false".equals(utility.getForceRewrite()) && destFile.exists()) {
1121             LOG.error("CompressVerify::isVerifyValidInHapAdditionMode target file already exists.");
1122             return false;
1123         }
1124         return true;
1125     }
1126 
checkJsonIsValid(File jsonFile)1127     private static boolean checkJsonIsValid(File jsonFile) {
1128         StringBuffer jsonData = new StringBuffer();
1129         try (FileReader fileReader = new FileReader(jsonFile);
1130              Reader reader = new InputStreamReader(new FileInputStream(jsonFile), StandardCharsets.UTF_8)) {
1131             int ch = 0;
1132             while ((ch = reader.read()) != -1) {
1133                 jsonData.append((char) ch);
1134             }
1135         } catch (IOException e) {
1136             LOG.error("CompressVerify::CheckJsonIsValid failed: " + e.getMessage());
1137             return false;
1138         }
1139         JSONValidator validator = JSONValidator.from(jsonData.toString());
1140         return validator.validate();
1141     }
1142 
isSharedApp(Utility utility)1143     private static boolean isSharedApp(Utility utility) {
1144         if (!utility.getHapPath().isEmpty()) {
1145             return false;
1146         }
1147         if (utility.getHspPath().isEmpty()) {
1148             return false;
1149         }
1150         List<String> tmpHspPathList = new ArrayList<>();
1151         if (compatibleProcess(utility, utility.getHspPath(), tmpHspPathList, HSP_SUFFIX)
1152             && verifyIsSharedApp(tmpHspPathList)) {
1153             utility.setIsSharedApp(true);
1154             return true;
1155         }
1156         return false;
1157     }
1158 
isAppService(Utility utility)1159     private static boolean isAppService(Utility utility) {
1160         if (!utility.getHapPath().isEmpty()) {
1161             List<String> tmpHapPathList = new ArrayList<>();
1162             if (compatibleProcess(utility, utility.getHapPath(), tmpHapPathList, HSP_SUFFIX)
1163                     && verifyIsAppService(tmpHapPathList)) {
1164                 utility.setIsAppService(true);
1165                 return true;
1166             }
1167         }
1168         if (utility.getHspPath().isEmpty()) {
1169             return false;
1170         }
1171         List<String> tmpHspPathList = new ArrayList<>();
1172         if (compatibleProcess(utility, utility.getHspPath(), tmpHspPathList, HSP_SUFFIX)
1173                 && verifyIsAppService(tmpHspPathList)) {
1174             utility.setIsAppService(true);
1175             return true;
1176         }
1177         return false;
1178     }
verifyIsAppService(List<String> modulePathList)1179     private static boolean verifyIsAppService(List<String> modulePathList) {
1180         if (modulePathList.isEmpty()) {
1181             return false;
1182         }
1183         try {
1184             for (String modulePath : modulePathList) {
1185                 HapVerifyInfo hapVerifyInfo = Compressor.parseStageHapVerifyInfo(modulePath);
1186                 if (!hapVerifyInfo.getBundleType().equals(BUNDLE_TYPE_APP_SERVICE)) {
1187                     return false;
1188                 }
1189             }
1190         } catch (BundleException e) {
1191             return false;
1192         }
1193         return true;
1194     }
verifyIsSharedApp(List<String> hspPath)1195     private static boolean verifyIsSharedApp(List<String> hspPath) {
1196         try {
1197             HapVerifyInfo hapVerifyInfo = Compressor.parseStageHapVerifyInfo(hspPath.get(0));
1198             return hapVerifyInfo.getBundleType().equals(BUNDLE_TYPE_SHARE);
1199         } catch (BundleException e) {
1200             return false;
1201         }
1202     }
1203 
isBundleTypeShared(Utility utility)1204     private static boolean isBundleTypeShared(Utility utility) {
1205         try {
1206             Optional<String> optional = FileUtils.getFileContent(utility.getJsonPath());
1207             if(optional.isPresent()) {
1208                 return ModuleJsonUtil.parseStageBundleType(optional.get()).equals(BUNDLE_TYPE_SHARE);
1209             } else {
1210                 String errMsg = "Parse --json-path content failed.";
1211                 LOG.error(PackingToolErrMsg.BUNDLE_TYPE_SHARED_INVALID.toString(errMsg));
1212                 return false;
1213             }
1214         } catch (BundleException e) {
1215             LOG.error(PackingToolErrMsg.BUNDLE_TYPE_SHARED_INVALID.toString("BundleException: " + e.getMessage()));
1216             return false;
1217         }
1218     }
1219 
isBundleTypeAppService(Utility utility)1220     private static boolean isBundleTypeAppService(Utility utility) {
1221         try {
1222             Optional<String> optional = FileUtils.getFileContent(utility.getJsonPath());
1223             if(optional.isPresent()) {
1224                 return ModuleJsonUtil.parseStageBundleType(optional.get()).equals(BUNDLE_TYPE_APP_SERVICE);
1225             } else {
1226                 String errMsg = "Parse --json-path content failed.";
1227                 LOG.error(PackingToolErrMsg.BUNDLE_TYPE_APPSERVICE_INVALID.toString(errMsg));
1228                 return false;
1229             }
1230         } catch (BundleException e) {
1231             LOG.error(PackingToolErrMsg.BUNDLE_TYPE_APPSERVICE_INVALID.toString("BundleException: " + e.getMessage()));
1232             return false;
1233         }
1234     }
1235 
hspHasAbilities(Utility utility)1236     private static boolean hspHasAbilities(Utility utility) {
1237         try {
1238             Optional<String> optional = FileUtils.getFileContent(utility.getJsonPath());
1239             if(optional.isPresent()) {
1240                 return ModuleJsonUtil.parseModuleType(optional.get()).equals(BUNDLE_TYPE_SHARE) && !ModuleJsonUtil.parseAbilityNames(optional.get()).isEmpty();
1241             } else {
1242                 String errMsg = "Parse --json-path content failed.";
1243                 LOG.error(PackingToolErrMsg.HSP_HAS_ABILITIES_FAILED.toString(errMsg));
1244                 return false;
1245             }
1246         } catch (BundleException e) {
1247             LOG.error(PackingToolErrMsg.HSP_HAS_ABILITIES_FAILED.toString("BundleException: " + e.getMessage()));
1248             return false;
1249         }
1250     }
1251 
hspHasExtensionAbilities(Utility utility)1252     private static boolean hspHasExtensionAbilities(Utility utility) {
1253         try {
1254             Optional<String> optional = FileUtils.getFileContent(utility.getJsonPath());
1255             if (optional.isPresent()) {
1256                 return ModuleJsonUtil.parseModuleType(optional.get()).equals(BUNDLE_TYPE_SHARE) &&
1257                         !ModuleJsonUtil.parseExtensionAbilityName(optional.get()).isEmpty();
1258             } else {
1259                 String errMsg = "Parse --json-path content failed.";
1260                 LOG.error(PackingToolErrMsg.HSP_HAS_EXTENSION_ABILITIES_FAILED.toString(errMsg));
1261             }
1262         } catch (BundleException e) {
1263             LOG.error(PackingToolErrMsg.HSP_HAS_EXTENSION_ABILITIES_FAILED.toString("BundleException: " + e.getMessage()));
1264         }
1265         return false;
1266     }
1267 
hasHomeAbility(Utility utility)1268     private static boolean hasHomeAbility(Utility utility) {
1269         try {
1270             boolean result = false;
1271             Optional<String> optional = FileUtils.getFileContent(utility.getJsonPath());
1272             if(!optional.isPresent()) {
1273                 String errMsg = "Parse --json-path content failed.";
1274                 LOG.error(PackingToolErrMsg.HAS_HOME_ABILITY_INVALID.toString(errMsg));
1275                 return false;
1276             }
1277             Map<String, Boolean> abilitiesMap = ModuleJsonUtil.parseAbilitySkillsMap(optional.get());
1278             if (abilitiesMap.containsValue(true)) {
1279                 result = true;
1280             }
1281             LOG.info("CompressVerify::hasHomeAbilities result = " + result);
1282             return result;
1283         } catch (BundleException e) {
1284             LOG.error(PackingToolErrMsg.HAS_HOME_ABILITY_INVALID.toString("BundleException: " + e.getMessage()));
1285             return false;
1286         }
1287     }
1288 
1289     /**
1290      * Indicates whether the "--encrypt-path" parameter is valid.
1291      *
1292      * @param utility - compress parameters
1293      * @return true if "--encrypt-path" param exists and the file name is encrypt.json, or the "--encrypt-path"
1294      *         param is empty, or has no "--encrypt-path" param
1295      *         false other situations
1296      */
isValidEncryptJsonFile(Utility utility)1297     private static boolean isValidEncryptJsonFile(Utility utility) {
1298         if (!utility.getEncryptPath().isEmpty()) {
1299             File fileEncryptJson = new File(utility.getEncryptPath());
1300             return fileEncryptJson.isFile() && Constants.FILE_ENCRYPT_JSON.equals(fileEncryptJson.getName());
1301         }
1302         return true;
1303     }
1304 
hasHomeExtensionAbility(Utility utility)1305     private static boolean hasHomeExtensionAbility(Utility utility) {
1306         try {
1307             boolean result = false;
1308             Optional<String> optional = FileUtils.getFileContent(utility.getJsonPath());
1309             if (!optional.isPresent()) {
1310                 String errMsg = "Parse --json-path content failed.";
1311                 LOG.error(PackingToolErrMsg.HAS_HOME_EXTENSION_ABILITY_INVALID.toString(errMsg));
1312                 return false;
1313             }
1314             Map<String, Boolean> extensionAbilitiesMap = ModuleJsonUtil.parseExtensionAbilitySkillsMap(optional.get());
1315             if (extensionAbilitiesMap.containsValue(true)) {
1316                 result = true;
1317             }
1318             LOG.info("CompressVerify::hasHomeExtensionAbility result = " + result);
1319             return result;
1320         } catch (BundleException e) {
1321             LOG.error(PackingToolErrMsg.HAS_HOME_EXTENSION_ABILITY_INVALID.toString("BundleException: " + e.getMessage()));
1322             return false;
1323         }
1324     }
1325 }
1326