• 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 java.io.BufferedInputStream;
19 import java.io.BufferedReader;
20 import java.io.ByteArrayOutputStream;
21 import java.io.File;
22 import java.io.FileInputStream;
23 import java.io.FileNotFoundException;
24 import java.io.FileOutputStream;
25 import java.io.IOException;
26 import java.io.InputStream;
27 import java.io.InputStreamReader;
28 
29 import java.nio.charset.StandardCharsets;
30 import java.nio.file.attribute.FileTime;
31 
32 import java.util.ArrayList;
33 import java.util.Enumeration;
34 import java.util.HashMap;
35 import java.util.List;
36 import java.util.Locale;
37 import java.util.stream.Collectors;
38 import java.util.zip.CRC32;
39 import java.util.zip.CheckedOutputStream;
40 import java.util.zip.ZipEntry;
41 import java.util.zip.ZipFile;
42 import java.util.zip.ZipInputStream;
43 import java.util.zip.ZipOutputStream;
44 
45 /**
46  * bundle uncompress.
47  *
48  */
49 public class Uncompress {
50     private static final String HAP_SUFFIX = ".hap";
51     private static final String APK_SUFFIX = ".apk";
52     private static final String JSON_SUFFIX = ".json";
53 
54     private static final String PACK_INFO = "pack.info";
55     private static final String HARMONY_PROFILE = "config.json";
56     private static final String MODULE_JSON = "module.json";
57     private static final String RESOURCE_INDEX = "resources.index";
58     private static final String RPCID_SC = "rpcid.sc";
59     private static final String LINUX_FILE_SEPARATOR = "/";
60     private static final String TEMP_PATH = "temp";
61     private static final String HAP_SUFFIXI = ".hap";
62     private static final String ENTRY_TYPE = "entry";
63     private static final String SYSTEM_ACTION = "action.system.home";
64     private static final String SYSTEM_WANT_HOME = "ohos.want.action.home";
65     private static final String SYSTEM_ENTITY = "entity.system.home";
66     private static final int READ_BUFFER_SIZE = 1024;
67     private static final int BUFFER_SIZE = 10 * 1024;
68     private static final long FILE_TIME = 1546272000000L;
69     private static final String LIBS_DIR_NAME = "libs";
70     private static final String CUT_ENTRY_FILENAME = "cut_entry.apk";
71     private static final String SO_SUFFIX = ".so";
72     private static final String RESOURCE_PATH = "resources/base/profile/";
73     private static final String TRUE = "true";
74     private static final String HQF_SUFFIX = ".hqf";
75     private static final String PATCH_JSON = "patch.json";
76     private static final String HAP_PREFIX = "HAP";
77     private static final String HSP_SUFFIX = ".hsp";
78 
79     private static final Log LOG = new Log(Uncompress.class.toString());
80 
81     /**
82      * unpackage entrance.
83      *
84      * @param utility common data
85      * @return unpackageProcess if unpackage succeed
86      */
unpackageProcess(Utility utility)87     static boolean unpackageProcess(Utility utility) {
88         if (utility == null) {
89             LOG.error("Uncompress::unpackageProcess utility is null.");
90             return false;
91         }
92         boolean unpackageResult = true;
93         File destFile = new File(utility.getOutPath());
94 
95         if (!destFile.exists()) {
96             if (!destFile.mkdirs()) {
97                 LOG.error("Uncompress::unpackageProcess create out file directory failed!");
98                 return false;
99             }
100         }
101         try {
102             if (!Utility.MODE_HAP.equals(utility.getMode()) || !TRUE.equals(utility.getRpcid())) {
103                 if (!utility.getForceRewrite().isEmpty() && "true".equals(utility.getForceRewrite())) {
104                     File outPath = new File(utility.getOutPath());
105                     deleteFile(outPath);
106                     outPath.mkdirs();
107                 }
108             }
109             switch (utility.getMode()) {
110                 case Utility.MODE_HAP:
111                     unpackageHapMode(utility);
112                     break;
113                 case Utility.MODE_HAR:
114                     dataTransferAllFiles(utility.getHarPath(), utility.getOutPath());
115                     break;
116                 case Utility.MODE_APP:
117                     dataTransferFilesByApp(utility, utility.getAppPath(), utility.getOutPath());
118                     break;
119                 case Utility.MODE_APPQF:
120                     uncompressAPPQFFile(utility);
121                     break;
122                 case Utility.MODE_HSP:
123                     dataTransferAllFiles(utility.getHspPath(), utility.getOutPath());
124                     break;
125                 default:
126                     LOG.error("Uncompress::unpackageProcess input wrong type!");
127                     throw new BundleException("Uncompress::unpackageProcess input wrong type!");
128             }
129         } catch (BundleException ignored) {
130             unpackageResult = false;
131             LOG.error("Uncompress::unpackageProcess Bundle exception");
132         }
133         // return uncompress information.
134         if (!unpackageResult) {
135             LOG.error("Uncompress::unpackageProcess unpackage failed!");
136         }
137         return unpackageResult;
138     }
139 
140     /**
141      * unpack hap.
142      *
143      * @param utility common data
144      */
unpackageHapMode(Utility utility)145     static void unpackageHapMode(Utility utility) throws BundleException {
146         if (!Utility.MODE_HAP.equals(utility.getMode())) {
147             throw new BundleException("Uncompress::unpackageHapMode input wrong unpack mode");
148         }
149         try {
150             if (TRUE.equals(utility.getRpcid())) {
151                 getRpcidFromHap(utility.getHapPath(), utility.getOutPath());
152                 return;
153             }
154             if (TRUE.equals(utility.getUnpackApk())) {
155                 unzip(utility, utility.getHapPath(), utility.getOutPath(), APK_SUFFIX);
156                 String[] temp = utility.getHapPath().replace("\\", "/").split("/");
157                 String hapName = temp[temp.length - 1];
158                 repackHap(utility.getHapPath(), utility.getOutPath(), hapName, utility.getUnpackApk());
159             } else {
160                 dataTransferAllFiles(utility.getHapPath(), utility.getOutPath());
161             }
162         } catch (BundleException e) {
163             LOG.error("Uncompress::unpackageHapMode failed");
164             throw new BundleException("Uncompress::unpackageHapMode failed");
165         }
166     }
167 
168     /**
169      * uncompress app.
170      *
171      * @param utility common data
172      * @return the uncompress result
173      */
uncompressAppByPath(Utility utility)174     static UncompressResult uncompressAppByPath(Utility utility) {
175         UncompressResult compressResult = new UncompressResult();
176         InputStream input = null;
177         String srcPath = utility.getAppPath();
178         String parseMode = utility.getParseMode();
179 
180         try {
181             if (UncompressEntrance.PARSE_MODE_HAPLIST.equals(parseMode)) {
182                 compressResult = uncompress(utility.getDeviceType(), srcPath, PACK_INFO);
183             } else if (UncompressEntrance.PARSE_MODE_HAPINFO.equals(parseMode)) {
184                 compressResult = uncompressHapAndHspFromAppPath(srcPath, utility);
185             } else if (UncompressEntrance.PARSE_MODE_ALL.equals(parseMode)) {
186                 compressResult = uncompressAllAppByPath(srcPath);
187             } else {
188                 LOG.error("Uncompress::uncompressApp parseMode is invalid!");
189                 compressResult.setResult(false);
190                 compressResult.setMessage("ParseApp parseMode is invalid");
191             }
192         } catch (BundleException e) {
193             LOG.error("Uncompress::uncompressApp Bundle exception");
194             compressResult.setResult(false);
195             compressResult.setMessage("ParseApp Bundle exception");
196         } finally {
197             Utility.closeStream(input);
198         }
199         return compressResult;
200     }
201 
uncompressHapAndHspFromAppPath( String srcPath, Utility utility)202     private static UncompressResult uncompressHapAndHspFromAppPath(
203             String srcPath, Utility utility) throws BundleException {
204         UncompressResult result = new UncompressResult();
205         String hapName = utility.getHapName();
206         if (!hapName.toLowerCase(Locale.ENGLISH).endsWith(HAP_SUFFIX)
207                 && !hapName.toLowerCase(Locale.ENGLISH).endsWith(HSP_SUFFIX)) {
208             hapName += HAP_SUFFIX;
209         }
210         ZipFile appFile = null;
211         ZipEntry entry = null;
212         InputStream stream = null;
213         try {
214             appFile = new ZipFile(srcPath);
215             Enumeration<? extends ZipEntry> entries = appFile.entries();
216             while (entries.hasMoreElements()) {
217                 entry = entries.nextElement();
218                 stream = appFile.getInputStream(entry);
219                 if (!hapName.equals(entry.getName().toLowerCase(Locale.ENGLISH))) {
220                     continue;
221                 }
222                 UncompressResult hapInfo = uncompressHapByStream("", stream, hapName);
223                 if (hapInfo.getProfileInfos() != null && hapInfo.getProfileInfos().size() > 0) {
224                     result.addProfileInfo(hapInfo.getProfileInfos().get(0));
225                     result.addProfileInfoStr(hapInfo.getProfileInfosStr().get(0));
226                 }
227                 break;
228             }
229         } catch (IOException | BundleException e) {
230             LOG.error("uncompressHapFromAppPath failed!");
231             throw new BundleException("uncompressHapFromAppPath failed!");
232         } finally {
233             Utility.closeStream(appFile);
234             Utility.closeStream(stream);
235         }
236         return result;
237     }
238 
uncompressAllAppByPath(String srcPath)239     private static UncompressResult uncompressAllAppByPath(String srcPath) throws BundleException {
240         UncompressResult result = new UncompressResult();
241         ZipFile appFile = null;
242         ZipEntry entry = null;
243         InputStream stream = null;
244         try {
245             appFile = new ZipFile(srcPath);
246             Enumeration<? extends ZipEntry> entries = appFile.entries();
247             while (entries.hasMoreElements()) {
248                 entry = entries.nextElement();
249                 stream = appFile.getInputStream(entry);
250                 if (PACK_INFO.equals(entry.getName().toLowerCase(Locale.ENGLISH))) {
251                     String packInfo = new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8))
252                             .lines().parallel().collect(Collectors.joining(System.lineSeparator()));
253                     List<PackInfo> packInfos = JsonUtil.parseHapList("", packInfo);
254                     result.setPackInfoStr(packInfo);
255                     result.setPackInfos(packInfos);
256                 }
257                 if (entry.getName().toLowerCase(Locale.ENGLISH).endsWith(HAP_SUFFIX)
258                         || entry.getName().toLowerCase(Locale.ENGLISH).endsWith(HSP_SUFFIX)) {
259                     UncompressResult hapInfo = uncompressHapByStream("", stream, entry.getName());
260                     if (hapInfo.getProfileInfos() != null && hapInfo.getProfileInfos().size() > 0) {
261                         result.addProfileInfo(hapInfo.getProfileInfos().get(0));
262                         result.addProfileInfoStr(hapInfo.getProfileInfosStr().get(0));
263                     }
264                 }
265             }
266             result = checkParseAllResult(result);
267             result = obtainLabelAndIcon(result);
268         } catch (IOException | BundleException e) {
269             LOG.error("uncompressAllAppByPath failed!");
270             throw new BundleException("uncompressAllAppByPath failed!");
271         } finally {
272             Utility.closeStream(appFile);
273             Utility.closeStream(stream);
274         }
275         return result;
276     }
277 
278 
279     /**
280      * uncompress app.
281      *
282      * @param utility common data
283      * @param input the InputStream about the app package.
284      * @return the uncompress result
285      */
uncompressAppByInput(Utility utility, InputStream input)286     static UncompressResult uncompressAppByInput(Utility utility, InputStream input) {
287         UncompressResult compressResult = new UncompressResult();
288         String parseMode = utility.getParseMode();
289         try {
290             if (!parseMode.isEmpty() && UncompressEntrance.PARSE_MODE_HAPLIST.equals(parseMode)) {
291                 compressResult = uncompressByInput(utility.getDeviceType(), input, PACK_INFO, "");
292             } else if (!parseMode.isEmpty() && UncompressEntrance.PARSE_MODE_HAPINFO.equals(parseMode)) {
293                 compressResult = uncompressHapFromAppStream(utility.getDeviceType(), input, utility.getHapName());
294             } else if (!parseMode.isEmpty() && UncompressEntrance.PARSE_MODE_ALL.equals(parseMode)) {
295                 compressResult = uncompressAllFromAppStream(input);
296             } else {
297                 LOG.error("Uncompress::uncompressAppByInput parseMode is invalid!");
298                 compressResult.setResult(false);
299                 compressResult.setMessage("ParseApp parseMode is invalid");
300             }
301         } catch (BundleException exception) {
302             LOG.error("Uncompress::uncompressAppByInput Bundle exception");
303             compressResult.setResult(false);
304             compressResult.setMessage("ParseApp Bundle exception");
305         }
306         return compressResult;
307     }
308 
uncompressHapFromAppStream(String deviceType, InputStream stream, String fileName)309     private static UncompressResult uncompressHapFromAppStream(String deviceType, InputStream stream, String fileName)
310             throws BundleException {
311         String hapFile = fileName;
312         if (!fileName.toLowerCase(Locale.ENGLISH).endsWith(HAP_SUFFIX)
313                 && !fileName.toLowerCase(Locale.ENGLISH).endsWith(HSP_SUFFIX)) {
314             hapFile += HAP_SUFFIX;
315         }
316         UncompressResult result = new UncompressResult();
317         ZipInputStream zipInputStream = null;
318         try {
319             zipInputStream = new ZipInputStream(stream);
320             ZipEntry appEntry;
321             while ((appEntry = zipInputStream.getNextEntry()) != null) {
322                 if (appEntry.getName().toLowerCase(Locale.ENGLISH).equals(hapFile)) {
323                     result = uncompressHapByStream("", zipInputStream, appEntry.getName());
324                 }
325             }
326         } catch (IOException e) {
327             LOG.error("uncompressHapFromAppStream failed!");
328             throw new BundleException("uncompressHapFromAppStream failed!");
329         } finally {
330             Utility.closeStream(zipInputStream);
331         }
332         return result;
333     }
334 
uncompressAllFromAppStream(InputStream stream)335     private static UncompressResult uncompressAllFromAppStream(InputStream stream) throws BundleException {
336         UncompressResult result = new UncompressResult();
337         ZipInputStream zipInputStream = null;
338         try {
339             zipInputStream = new ZipInputStream(stream);
340             ZipEntry entry;
341             while ((entry = zipInputStream.getNextEntry()) != null) {
342                 if (PACK_INFO.equals(entry.getName().toLowerCase(Locale.ENGLISH))) {
343                     String packInfo = new BufferedReader(new InputStreamReader(zipInputStream,
344                             StandardCharsets.UTF_8)).lines().parallel()
345                             .collect(Collectors.joining(System.lineSeparator()));
346                     List<PackInfo> packInfos = JsonUtil.parseHapList("", packInfo);
347                     result.setPackInfoStr(packInfo);
348                     result.setPackInfos(packInfos);
349                 }
350                 if (entry.getName().toLowerCase(Locale.ENGLISH).endsWith(HAP_SUFFIX)
351                         || entry.getName().toLowerCase(Locale.ENGLISH).endsWith(HSP_SUFFIX)) {
352                     UncompressResult hapResult = uncompressHapByStream("", zipInputStream, entry.getName());
353                     if (hapResult.getProfileInfos() != null && hapResult.getProfileInfos().size() > 0) {
354                         result.addProfileInfo(hapResult.getProfileInfos().get(0));
355                         result.addProfileInfoStr(hapResult.getProfileInfosStr().get(0));
356                     }
357                 }
358             }
359             result = checkParseAllResult(result);
360             result = obtainLabelAndIcon(result);
361         } catch (IOException | BundleException e) {
362             LOG.error("uncompressAllFromAppStream failed!");
363             throw new BundleException("uncompressAllFromAppStream failed!");
364         } finally {
365             Utility.closeStream(zipInputStream);
366         }
367         return result;
368     }
369 
370     /**
371      * uncompress hap.
372      *
373      * @param utility common data
374      * @return the uncompress result
375      */
uncompressHap(Utility utility)376     static UncompressResult uncompressHap(Utility utility) {
377         UncompressResult compressResult = new UncompressResult();
378         try {
379             compressResult = uncompressHapByPath(utility.getDeviceType(), utility.getHapPath());
380         } catch (BundleException ignored) {
381             LOG.error("Uncompress::uncompressHap Bundle exception");
382             compressResult.setResult(false);
383             compressResult.setMessage("uncompressHap Bundle exception");
384         }
385         return compressResult;
386     }
387 
388     /**
389      * uncompress hap by path, it can adapt stage module and fa module.
390      *
391      * @param deviceType indicates the device type of parse type.
392      * @param hapPath indicates the hap path of hap.
393      * @return the uncompress result
394      */
uncompressHapByPath(String deviceType, String hapPath)395     static UncompressResult uncompressHapByPath(String deviceType, String hapPath) throws BundleException {
396         UncompressResult compressResult = new UncompressResult();
397         try {
398             if (isModuleHap(hapPath, compressResult)) {
399                 compressResult = unCompressModuleHap(deviceType, hapPath, MODULE_JSON);
400             } else {
401                 compressResult = uncompress(deviceType, hapPath, HARMONY_PROFILE);
402                 compressResult = obtainLabelAndIcon(compressResult);
403             }
404         } catch (BundleException e) {
405             LOG.error("Uncompress::uncompressHapByPath Bundle exception");
406             throw new BundleException("Uncompress::uncompressHapByPath failed");
407         }
408         return compressResult;
409     }
410 
411     /**
412      * uncompress hap.
413      *
414      * @param utility common data
415      * @param input the InputStream about the app package.
416      * @return the uncompress result
417      */
uncompressHapByInput(Utility utility, InputStream input)418     static UncompressResult uncompressHapByInput(Utility utility, InputStream input) {
419         UncompressResult compressResult = new UncompressResult();
420         try {
421             compressResult = uncompressHapByStream(utility.getDeviceType(), input, "");
422         } catch (BundleException ignored) {
423             LOG.error("Uncompress::uncompressHapByInput Bundle exception");
424             compressResult.setResult(false);
425             compressResult.setMessage("uncompressHapByInput Bundle exception");
426         }
427         return compressResult;
428     }
429 
430     /**
431      * uncompress hap by InputStream, it can adapt stage module and fa module.
432      *
433      * @param deviceType indicates the device type of parse type.
434      * @param stream indicates the input stream of hap.
435      * @return the uncompress result
436      */
uncompressHapByStream(String deviceType, InputStream stream, String hapName)437     static UncompressResult uncompressHapByStream(String deviceType, InputStream stream,
438                                                   String hapName) throws BundleException {
439         UncompressResult compressResult = new UncompressResult();
440         compressResult = uncompressHapByBigStream(deviceType, stream, hapName);
441         return compressResult;
442     }
443 
uncompressHapByBigStream(String deviceType, InputStream stream, String hapName)444     static UncompressResult uncompressHapByBigStream(String deviceType, InputStream stream, String hapName)
445             throws BundleException {
446         UncompressResult compressResult = new UncompressResult();
447         InputStream fileStream = null;
448         InputStream parseStream = null;
449         File file = null;
450         try {
451             String releativePath = System.getProperty("user.dir");
452             File directory = new File(releativePath);
453             file = File.createTempFile(HAP_PREFIX, HAP_SUFFIX, directory);
454             writeToTempFile(stream, file);
455             fileStream = new FileInputStream(file);
456             boolean isModule = false;
457             if (isModuleInput(fileStream)) {
458                 isModule = true;
459             }
460             parseStream = new FileInputStream(file);
461             if (isModule) {
462                 compressResult = uncompressModuleHapByInput(deviceType, parseStream, MODULE_JSON, hapName);
463             } else {
464                 compressResult = uncompressByInput(deviceType, parseStream, HARMONY_PROFILE, hapName);
465                 compressResult = obtainLabelAndIcon(compressResult);
466             }
467         } catch (IOException e) {
468             LOG.error("uncompressHapByBigStream failed for IO exception!");
469             throw new BundleException("uncompressHapByBigStream failed for IO exception!");
470         } finally {
471             Utility.closeStream(fileStream);
472             Utility.closeStream(parseStream);
473             if (file != null) {
474                 FileUtils.deleteFile(file.getPath());
475             }
476         }
477         return compressResult;
478     }
479 
480     /**
481      * unzip process
482      *
483      * @param utility common data
484      * @param srcPath source file path
485      * @param destDirPath destination file path
486      * @param suffix suffix for judgment
487      * @throws BundleException FileNotFoundException|IOException.
488      */
unzip(Utility utility, String srcPath, String destDirPath, String suffix)489     private static void unzip(Utility utility, String srcPath, String destDirPath, String suffix)
490             throws BundleException {
491         if (utility == null) {
492             LOG.error("Uncompress::unzip utility is null!");
493             throw new BundleException("Unzip failed, utility is null");
494         }
495 
496         if (srcPath.isEmpty() || !UncompressVerify.isPathValid(srcPath, true, "")) {
497             LOG.error("Uncompress::unzip srcPath is invalid!");
498             throw new BundleException("Unzip failed, srcPath is invalid");
499         }
500 
501         if (destDirPath.isEmpty() || !UncompressVerify.isPathValid(destDirPath, false, null)) {
502             LOG.error("Uncompress::unzip destDirPath is invalid!");
503             throw new BundleException("Unzip failed, destDirPath is invalid");
504         }
505         unzipFromFile(utility, srcPath, destDirPath, suffix);
506     }
507 
508     /**
509      * unzip process from the file
510      *
511      * @param utility common data
512      * @param srcPath source file path
513      * @param destDirPath destination file path
514      * @param suffix suffix for judgment
515      * @throws BundleException FileNotFoundException|IOException.
516      */
unzipFromFile(Utility utility, String srcPath, String destDirPath, String suffix)517     private static void unzipFromFile(Utility utility, String srcPath, String destDirPath, String suffix)
518             throws BundleException {
519         ZipFile zipFile = null;
520         String hapNames = "";
521         try {
522             zipFile = new ZipFile(new File(srcPath));
523             if (utility != null && !utility.getDeviceType().isEmpty()
524                     && (HAP_SUFFIX.equals(suffix) || HSP_SUFFIX.equals(suffix))) {
525                 List<PackInfo> packInfos = uncompress(utility.getDeviceType(), srcPath, PACK_INFO).getPackInfos();
526                 for (PackInfo packinfo : packInfos) {
527                     hapNames += packinfo.name + ",";
528                 }
529             }
530 
531             int entriesNum = 0;
532             for (Enumeration<? extends ZipEntry> entries = zipFile.entries(); entries.hasMoreElements(); ) {
533                 entriesNum++;
534                 ZipEntry entry = entries.nextElement();
535                 String entryName = "";
536                 if (entry == null || entry.getName().isEmpty()) {
537                     continue;
538                 }
539                 if (entry.getName().toLowerCase().endsWith(CUT_ENTRY_FILENAME) &&
540                     "false".equals(utility.getUnpackCutEntryApk())) {
541                     continue;
542                 }
543                 entryName = entry.getName();
544                 if (!entryName.toLowerCase(Locale.ENGLISH).endsWith(suffix) ||
545                         (!hapNames.isEmpty() && !hapNames.contains(entryName.replace(suffix, "")))) {
546                     continue;
547                 }
548                 String tempDir = destDirPath.replace(File.separator, LINUX_FILE_SEPARATOR);
549                 if (HAP_SUFFIX.equals(suffix) && "true".equals(utility.getUnpackApk())) {
550                     tempDir = tempDir + LINUX_FILE_SEPARATOR + entryName.replace(suffix, "");
551                     File destFileDir = new File(tempDir);
552                     if (!destFileDir.exists()) {
553                         destFileDir.mkdir();
554                     }
555                 }
556                 if (APK_SUFFIX.equals(suffix) && "true".equals(utility.getUnpackApk())
557                     && entryName.contains(LINUX_FILE_SEPARATOR)) {
558                     // only unpack shell apk which in the root directory
559                     continue;
560                 }
561                 String tempPath = tempDir + LINUX_FILE_SEPARATOR + entryName;
562                 if (!FileUtils.matchPattern(tempPath)) {
563                     throw new BundleException("Input invalid file " + tempPath);
564                 }
565                 File destFile = new File(tempPath);
566                 dataTransfer(zipFile, entry, destFile);
567                 if (JSON_SUFFIX.equals(suffix)) {
568                     break;
569                 } else if (HAP_SUFFIX.equals(suffix) && "true".equals(utility.getUnpackApk())) {
570                     unzip(utility, tempPath, tempDir, APK_SUFFIX);
571                     repackHap(tempPath, tempDir, entryName, utility.getUnpackApk());
572                 }
573             }
574         } catch (IOException | BundleException exception) {
575             LOG.error("Uncompress::unzipInHapMode failed: " + exception.getMessage());
576             throw new BundleException("Unzip in hap mode failed");
577         } finally {
578             Utility.closeStream(zipFile);
579         }
580     }
581 
582     /**
583      * uncompress dataTransfer
584      *
585      * @param zipFile input zip file
586      * @param entry input file in zip
587      * @param destFile output file path
588      * @throws BundleException FileNotFoundException|IOException.
589      */
dataTransfer(ZipFile zipFile, ZipEntry entry, File destFile)590     private static void dataTransfer(ZipFile zipFile, ZipEntry entry, File destFile) throws BundleException {
591         InputStream fileInputStream = null;
592         FileOutputStream fileOutStream = null;
593         try {
594             if (!FileUtils.matchPattern(destFile.getCanonicalPath())) {
595                 LOG.error("Input invalid file " + destFile);
596                 throw new BundleException("Input invalid file" + destFile.getCanonicalPath());
597             }
598             fileInputStream = zipFile.getInputStream(entry);
599             fileOutStream = new FileOutputStream(destFile);
600             byte[] data = new byte[BUFFER_SIZE];
601             int count = fileInputStream.read(data);
602             int total = 0;
603             while (count > 0) {
604                 fileOutStream.write(data, 0, count);
605                 total += count;
606                 count = fileInputStream.read(data);
607             }
608         } catch (IOException | BundleException exception) {
609             LOG.error("Uncompress::dataTransfer file " + exception.getMessage());
610             throw new BundleException("DataTransfer failed");
611         } finally {
612             Utility.closeStream(fileOutStream);
613             Utility.closeStream(fileInputStream);
614         }
615     }
616 
617     /**
618      * uncompress dataTransfer all files.
619      *
620      * @param srcPath source file path
621      * @param destDirPath destination file path
622      * @throws BundleException FileNotFoundException|IOException.
623      */
dataTransferAllFiles(String srcPath, String destDirPath)624     private static void dataTransferAllFiles(String srcPath, String destDirPath) throws BundleException {
625         ZipFile zipFile = null;
626         try {
627             if (!FileUtils.matchPattern(srcPath)) {
628                 throw new BundleException("Input invalid file " + srcPath);
629             }
630             zipFile = new ZipFile(new File(srcPath));
631             int entriesNum = 0;
632             for (Enumeration<? extends ZipEntry> entries = zipFile.entries(); entries.hasMoreElements(); ) {
633                 entriesNum++;
634                 ZipEntry entry = entries.nextElement();
635                 if (entry == null) {
636                     continue;
637                 }
638                 String tempPath = destDirPath + LINUX_FILE_SEPARATOR + entry.getName();
639                 File destFile = new File(tempPath);
640                 if (destFile != null && destFile.getParentFile() != null && !destFile.getParentFile().exists()) {
641                     destFile.getParentFile().mkdirs();
642                 }
643                 dataTransfer(zipFile, entry, destFile);
644             }
645         } catch (FileNotFoundException ignored) {
646             LOG.error("Uncompress::unzipApk file not found exception");
647             throw new BundleException("Unzip Apk failed");
648         } catch (IOException exception) {
649             LOG.error("Uncompress::unzipApk io exception: " + exception.getMessage());
650             throw new BundleException("Unzip Apk failed");
651         } finally {
652             Utility.closeStream(zipFile);
653         }
654     }
655 
dataTransferFilesByApp(Utility utility, String srcPath, String destDirPath)656     private static void dataTransferFilesByApp(Utility utility, String srcPath, String destDirPath)
657             throws BundleException {
658         ZipFile zipFile = null;
659         try {
660             zipFile = new ZipFile(new File(srcPath));
661             int entriesNum = 0;
662             for (Enumeration<? extends ZipEntry> entries = zipFile.entries(); entries.hasMoreElements(); ) {
663                 entriesNum++;
664                 ZipEntry entry = entries.nextElement();
665                 if (entry == null) {
666                     continue;
667                 }
668                 String filePath = destDirPath + LINUX_FILE_SEPARATOR + entry.getName();
669                 if (!FileUtils.matchPattern(filePath)) {
670                     throw new BundleException("Input invalid path " + filePath);
671                 }
672                 File destFile = new File(filePath);
673                 if (destFile != null && destFile.getParentFile() != null && !destFile.getParentFile().exists()) {
674                     destFile.getParentFile().mkdirs();
675                 }
676                 boolean isUnpackApk = "true".equals(utility.getUnpackApk());
677                 if (isUnpackApk && filePath.toLowerCase().endsWith(HAP_SUFFIX)) {
678                     dataTransfer(zipFile, entry, destFile);
679                     unzip(utility, filePath, destDirPath, APK_SUFFIX);
680                     String[] temp = filePath.replace("\\", "/").split("/");
681                     String hapName = "";
682                     if (temp.length > 0) {
683                         hapName = temp[temp.length - 1];
684                     }
685                     repackHap(filePath, destDirPath, hapName, utility.getUnpackApk());
686                 } else {
687                     dataTransfer(zipFile, entry, destFile);
688                 }
689             }
690         } catch (IOException | BundleException exception) {
691             LOG.error("Uncompress::unzipApk file failed " + exception.getMessage());
692             throw new BundleException("Unzip Apk failed");
693         } finally {
694             Utility.closeStream(zipFile);
695         }
696     }
697 
getResourceDataFromHap(ZipFile zipFile)698     private static byte[] getResourceDataFromHap(ZipFile zipFile) throws BundleException, IOException {
699         int entriesNum = 0;
700         InputStream indexInputStream = null;
701         try {
702             for (Enumeration<? extends ZipEntry> entries = zipFile.entries(); entries.hasMoreElements(); ) {
703                 entriesNum++;
704                 ZipEntry indexEntry = entries.nextElement();
705                 if (indexEntry == null) {
706                     continue;
707                 }
708                 if (indexEntry != null && !"".equals(indexEntry.getName()) &&
709                     indexEntry.getName().toLowerCase().endsWith(RESOURCE_INDEX)) {
710                     indexInputStream = zipFile.getInputStream(indexEntry);
711                     return getByte(indexInputStream);
712                 }
713             }
714         } finally {
715             Utility.closeStream(indexInputStream);
716         }
717         return null;
718     }
719 
unZipHapFileFromHapFile(String srcPath)720     private static HapZipInfo unZipHapFileFromHapFile(String srcPath)
721         throws BundleException, IOException {
722         HapZipInfo hapZipInfo = new HapZipInfo();
723         ZipFile zipFile = null;
724         if (!FileUtils.matchPattern(srcPath)) {
725             LOG.error("Input invalid path " + srcPath);
726             throw new BundleException("Input invalid path " + srcPath);
727         }
728         try {
729             File srcFile = new File(srcPath);
730             zipFile = new ZipFile(srcFile);
731             hapZipInfo.setHarmonyProfileJsonStr(FileUtils.getFileStringFromZip(HARMONY_PROFILE, zipFile));
732             hapZipInfo.setResDataBytes(getResourceDataFromHap(zipFile));
733             hapZipInfo.setPackInfoJsonStr(FileUtils.getFileStringFromZip(PACK_INFO, zipFile));
734             hapZipInfo.setHapFileName(getHapNameWithoutSuffix(srcFile.getName()));
735         }  finally {
736             Utility.closeStream(zipFile);
737         }
738         return hapZipInfo;
739     }
740 
741     /**
742      * uncompress from specified file name
743      *
744      * @param deviceType device type
745      * @param srcPath source file path
746      * @param fileName uncompress file name
747      * @return the uncompress result
748      * @throws BundleException FileNotFoundException|IOException.
749      */
uncompress(String deviceType, String srcPath, String fileName)750     private static UncompressResult uncompress(String deviceType, String srcPath, String fileName)
751             throws BundleException {
752         if (srcPath.isEmpty() || fileName.isEmpty()) {
753             LOG.error("Uncompress::uncompress srcPath, fileName is empty!");
754             throw new BundleException("Uncompress failed, srcPath or fileName is empty");
755         }
756 
757         UncompressResult result = new UncompressResult();
758         try {
759             HapZipInfo hapZipInfo = unZipHapFileFromHapFile(srcPath);
760             if (isPackInfo(fileName)) {
761                 uncompressPackInfo(deviceType, hapZipInfo, result);
762             } else {
763                 uncompressProfileInfo(hapZipInfo, result);
764             }
765         } catch (IOException exception) {
766             LOG.error("Uncompress::uncompress io exception: " + exception.getMessage());
767             throw new BundleException("Uncompress failed");
768         }
769         return result;
770     }
771 
uncompressPackInfo(String deviceType, HapZipInfo hapZipInfo, UncompressResult uncomperssResult)772     private static void uncompressPackInfo(String deviceType, HapZipInfo hapZipInfo, UncompressResult uncomperssResult)
773         throws BundleException {
774         List<PackInfo> packInfos = JsonUtil.parseHapList(deviceType, hapZipInfo.getPackInfoJsonStr());
775         uncomperssResult.setPackInfoStr(hapZipInfo.getPackInfoJsonStr());
776         uncomperssResult.setPackInfos(packInfos);
777     }
778 
uncompressProfileInfo(HapZipInfo hapZipInfo, UncompressResult uncomperssResult)779     private static void uncompressProfileInfo(HapZipInfo hapZipInfo, UncompressResult uncomperssResult)
780         throws BundleException {
781         ProfileInfo profileInfo = JsonUtil.parseProfileInfo(hapZipInfo.getHarmonyProfileJsonStr(),
782             hapZipInfo.getResDataBytes(), hapZipInfo.getPackInfoJsonStr(), hapZipInfo.getHapFileName());
783         profileInfo.hapName = hapZipInfo.getHapFileName();
784         profileInfo.appInfo.setBundleType(getFABundleType(profileInfo));
785         uncomperssResult.addProfileInfoStr(hapZipInfo.getHarmonyProfileJsonStr());
786         uncomperssResult.addProfileInfo(profileInfo);
787     }
788 
getFABundleType(ProfileInfo profileInfo)789     private static String getFABundleType(ProfileInfo profileInfo) {
790         String bundleType = "app";
791         if (profileInfo.hapInfo.distro.installationFree == 1) {
792             bundleType = "atomicService";
793         }
794         return bundleType;
795     }
796 
unZipHapFileFromInputStream(InputStream input)797     private static HapZipInfo unZipHapFileFromInputStream(InputStream input) throws BundleException, IOException {
798         BufferedInputStream bufIn = null;
799         ZipInputStream zipIn = null;
800         BufferedReader bufferedReader = null;
801         HapZipInfo hapZipInfo = new HapZipInfo();
802         try {
803             ZipEntry entry = null;
804             bufIn = new BufferedInputStream(input);
805             zipIn = new ZipInputStream(bufIn);
806             int entriesNum = 0;
807             while ((entry = zipIn.getNextEntry()) != null) {
808                 entriesNum++;
809                 if (entry.getName().toLowerCase().endsWith(RESOURCE_INDEX)) {
810                     hapZipInfo.setResDataBytes(getByte(zipIn));
811                     continue;
812                 }
813                 if (isPackInfo(entry.getName())) {
814                     bufferedReader = new BufferedReader(new InputStreamReader(zipIn));
815                     hapZipInfo.setPackInfoJsonStr(readStringFromInputStream(zipIn, bufferedReader));
816                     continue;
817                 }
818                 if (isHarmonyProfile(entry.getName())) {
819                     bufferedReader = new BufferedReader(new InputStreamReader(zipIn));
820                     hapZipInfo.setHarmonyProfileJsonStr(readStringFromInputStream(zipIn, bufferedReader));
821                 }
822             }
823         } finally {
824             Utility.closeStream(bufferedReader);
825             Utility.closeStream(bufIn);
826             Utility.closeStream(zipIn);
827         }
828         return hapZipInfo;
829     }
830 
readStringFromInputStream(ZipInputStream zipIn, BufferedReader bufferedReader)831     private static String readStringFromInputStream(ZipInputStream zipIn, BufferedReader bufferedReader)
832         throws IOException {
833         String line;
834         StringBuilder sb = new StringBuilder();
835         while ((line = bufferedReader.readLine()) != null) {
836             sb.append(line);
837         }
838         return sb.toString();
839     }
840 
841     /**
842      * uncompress process by InputStream
843      *
844      * @param deviceType device type
845      * @param input the InputStream about the package.
846      * @param fileName uncompress file name
847      * @return the uncompress result
848      * @throws BundleException FileNotFoundException|IOException.
849      */
uncompressByInput(String deviceType, InputStream input, String fileName, String hapName)850     private static UncompressResult uncompressByInput(String deviceType, InputStream input,
851                                                       String fileName, String hapName) throws BundleException {
852         UncompressResult result = new UncompressResult();
853         try {
854             HapZipInfo hapZipInfo = unZipHapFileFromInputStream(input);
855             hapZipInfo.setHapFileName(hapName);
856             if (isPackInfo(fileName)) {
857                 uncompressPackInfo(deviceType, hapZipInfo, result);
858             } else {
859                 uncompressProfileInfo(hapZipInfo, result);
860             }
861         } catch (IOException exception) {
862             LOG.error("Uncompress::uncompressByInput io exception: " + exception.getMessage());
863             throw new BundleException("Uncompress by input failed");
864         }
865         return result;
866     }
867 
868     /**
869      * uncompress process by InputStream
870      *
871      * @param deviceType device type
872      * @param input the InputStream about the package.
873      * @param fileName uncompress file name
874      * @return the module uncompress result
875      * @throws BundleException FileNotFoundException|IOException.
876      */
uncompressModuleByInput(String deviceType, InputStream input, String fileName, String hapName)877     private static ModuleResult uncompressModuleByInput(String deviceType, InputStream input,
878                                                         String fileName, String hapName) throws BundleException {
879         ModuleResult result = new ModuleResult();
880         try {
881             HapZipInfo hapZipInfo = unZipModuleHapFileFromInputStream(input);
882             hapZipInfo.setHapFileName(hapName);
883             if (isPackInfo(fileName)) {
884                 // for parse app
885             } else {
886                 uncompressModuleJsonInfo(hapZipInfo, result);
887             }
888         } catch (BundleException exception) {
889             LOG.error("Uncompress::uncompressByInput io exception: " + exception.getMessage());
890             throw new BundleException("Uncompress by input failed");
891         }
892         return result;
893     }
894 
895     /**
896      * Get entry byte array.
897      *
898      * @param zis the InputStream about the entry.
899      * @return Return the entry byte array.
900      * @throws BundleException FileNotFoundException|IOException.
901      */
getByte(InputStream zis)902     private static byte[] getByte(InputStream zis) throws BundleException {
903         ByteArrayOutputStream bos = new ByteArrayOutputStream();
904         byte[] buf = null;
905         try {
906             byte[] temp = new byte[READ_BUFFER_SIZE];
907             int length = 0;
908 
909             while ((length = zis.read(temp, 0, READ_BUFFER_SIZE)) != -1) {
910                 bos.write(temp, 0, length);
911             }
912 
913             buf = bos.toByteArray();
914         } catch (IOException e) {
915             LOG.error("Uncompress::getByte io exception: " + e.getMessage());
916             throw new BundleException("Get byte failed");
917         } finally {
918             Utility.closeStream(bos);
919         }
920         return buf;
921     }
922 
923     /**
924      * repack hap
925      *
926      * @param srcPath source file path
927      * @param destDirPath destination file path
928      * @param fileName target file name
929      * @param unpackApk unpackApk flag
930      * @throws BundleException FileNotFoundException|IOException.
931      */
repackHap(String srcPath, String destDirPath, String fileName, String unpackApk)932     private static void repackHap(String srcPath, String destDirPath, String fileName, String unpackApk)
933             throws BundleException {
934         if (srcPath.isEmpty() || destDirPath.isEmpty() || fileName.isEmpty()) {
935             LOG.error("Uncompress::repackHap srcPath, destDirPath or fileName is empty!");
936             throw new BundleException("Repack hap failed, srcPath, destDirPath or fileName is empty");
937         }
938 
939         if (!UncompressVerify.isPathValid(srcPath, true, "")) {
940             LOG.error("Uncompress::repackHap srcPath is invalid!");
941             throw new BundleException("Repack hap failed, srcPath is invalid");
942         }
943 
944         if (!UncompressVerify.isPathValid(destDirPath, false, null)) {
945             LOG.error("Uncompress::repackHap destDirPath is invalid!");
946             throw new BundleException("Repack hap failed, destDirPath is invalid");
947         }
948 
949         String tempDir = destDirPath.replace(File.separator, LINUX_FILE_SEPARATOR) + LINUX_FILE_SEPARATOR +
950                 TEMP_PATH;
951         dataTransferAllFiles(srcPath, tempDir);
952         packFilesByPath(tempDir, destDirPath, fileName, unpackApk);
953         File deleteFile = new File(tempDir);
954         deleteFile(deleteFile);
955     }
956 
957     /**
958      * compress file directory.
959      *
960      * @param srcPath source file path
961      * @param destDirPath destination file path
962      * @param fileName target file name
963      * @param unpackApk unpackApk flag
964      * @throws BundleException FileNotFoundException|IOException.
965      */
packFilesByPath(String srcPath, String destDirPath, String fileName, String unpackApk)966     private static void packFilesByPath(String srcPath, String destDirPath, String fileName, String unpackApk)
967             throws BundleException {
968         if (srcPath.isEmpty() || destDirPath.isEmpty() || fileName.isEmpty()) {
969             LOG.error("Uncompress::packFilesByPath srcPath, destDirPath or fileName is empty!");
970             throw new BundleException("Pack files by path failed, srcPath, destDirPath or fileName is empty");
971         }
972 
973         if (!UncompressVerify.isPathValid(srcPath, false, null) ||
974                 !UncompressVerify.isPathValid(destDirPath, false, null)) {
975             LOG.error("Uncompress::packFilesByPath srcPath or destDirPath is invalid!");
976             throw new BundleException("Pack files by path failed, srcPath or destDirPath is invalid");
977         }
978 
979         File srcDir = new File(srcPath);
980         File[] srcFiles = srcDir.listFiles();
981         if (srcFiles == null) {
982             return;
983         }
984         FileOutputStream fileOut = null;
985         CheckedOutputStream checkedOut = null;
986         ZipOutputStream zipOut = null;
987 
988         try {
989             String zipPath = destDirPath + LINUX_FILE_SEPARATOR + fileName;
990             if (!FileUtils.matchPattern(zipPath)) {
991                 throw new BundleException("Input invalid file" + zipPath);
992             }
993             File zipFile = new File(zipPath);
994             fileOut = new FileOutputStream(zipFile);
995             checkedOut = new CheckedOutputStream(fileOut, new CRC32());
996             zipOut = new ZipOutputStream(checkedOut);
997             for (int i = 0; i < srcFiles.length; i++) {
998                 File srcFile = srcFiles[i];
999                 if (srcFile.isDirectory()) {
1000                     if (srcFile.getPath().toLowerCase(Locale.ENGLISH).endsWith(LIBS_DIR_NAME)) {
1001                         compressDirectory(srcFile, "", zipOut, true);
1002                     } else {
1003                         compressDirectory(srcFile, "", zipOut, false);
1004                     }
1005                 } else {
1006                     if (srcFile.getPath().toLowerCase(Locale.ENGLISH).endsWith(APK_SUFFIX) &&
1007                         "true".equals(unpackApk)) {
1008                         continue;
1009                     }
1010                     compressFile(srcFile, "", zipOut, false);
1011                 }
1012             }
1013         } catch (FileNotFoundException | BundleException exception) {
1014             LOG.error("Uncompress::packFilesByPath " + exception.getMessage());
1015             throw new BundleException("Pack files by path failed");
1016         } finally {
1017             Utility.closeStream(zipOut);
1018             Utility.closeStream(checkedOut);
1019             Utility.closeStream(fileOut);
1020         }
1021     }
1022 
1023     /**
1024      * compress file directory.
1025      *
1026      * @param dir file directory
1027      * @param baseDir base path for file
1028      * @param zipOut zip outPutStream
1029      * @param isCompression if need compression
1030      * @throws BundleException FileNotFoundException|IOException.
1031      */
compressDirectory(File dir, String baseDir, ZipOutputStream zipOut, boolean isCompression)1032     private static void compressDirectory(File dir, String baseDir, ZipOutputStream zipOut, boolean isCompression)
1033             throws BundleException {
1034         File[] files = dir.listFiles();
1035         if (files == null) {
1036             return;
1037         }
1038         for (File file : files) {
1039             if (file.isDirectory()) {
1040                 compressDirectory(file, baseDir + dir.getName() + File.separator, zipOut, isCompression);
1041             } else {
1042                 compressFile(file, baseDir + dir.getName() + File.separator, zipOut, isCompression);
1043             }
1044         }
1045     }
1046 
1047     /**
1048      * compress process.
1049      *
1050      * @param srcFile source file to zip
1051      * @param baseDir base path for file
1052      * @param zipOut zip outPutStream
1053      * @param isCompression if need compression
1054      * @throws BundleException FileNotFoundException|IOException.
1055      */
compressFile(File srcFile, String baseDir, ZipOutputStream zipOut, boolean isCompression)1056     private static void compressFile(File srcFile, String baseDir, ZipOutputStream zipOut, boolean isCompression)
1057             throws BundleException {
1058         FileInputStream fileInputStream = null;
1059         BufferedInputStream bufferedInputStream = null;
1060 
1061         try {
1062             String entryName = (baseDir + srcFile.getName()).replace(File.separator, LINUX_FILE_SEPARATOR);
1063             ZipEntry zipEntry = new ZipEntry(entryName);
1064 	    boolean isNeedCompress = isCompression;
1065 	    if (srcFile.isFile() && srcFile.getName().toLowerCase(Locale.ENGLISH).endsWith(SO_SUFFIX)) {
1066                 isNeedCompress = false;
1067             }
1068             if (isNeedCompress) {
1069                 zipEntry.setMethod(ZipEntry.DEFLATED);
1070             } else {
1071                 zipEntry.setMethod(ZipEntry.STORED);
1072                 zipEntry.setCompressedSize(srcFile.length());
1073                 zipEntry.setSize(srcFile.length());
1074                 CRC32 crc = getCrcFromFile(srcFile);
1075                 zipEntry.setCrc(crc.getValue());
1076             }
1077             FileTime fileTime = FileTime.fromMillis(FILE_TIME);
1078             zipEntry.setLastAccessTime(fileTime);
1079             zipEntry.setLastModifiedTime(fileTime);
1080             zipOut.putNextEntry(zipEntry);
1081             byte[] data = new byte[BUFFER_SIZE];
1082             fileInputStream = new FileInputStream(srcFile);
1083             bufferedInputStream = new BufferedInputStream(fileInputStream);
1084             int count = bufferedInputStream.read(data);
1085             while (count > 0) {
1086                 zipOut.write(data, 0, count);
1087                 count = bufferedInputStream.read(data);
1088             }
1089         } catch (FileNotFoundException ignored) {
1090             LOG.error("Uncompress::compressFile file not found exception");
1091             throw new BundleException("Compress file failed");
1092         } catch (IOException exception) {
1093             LOG.error("Uncompress::compressFile io exception: " + exception.getMessage());
1094             throw new BundleException("Compress file failed");
1095         } finally {
1096             Utility.closeStream(fileInputStream);
1097             Utility.closeStream(bufferedInputStream);
1098         }
1099     }
1100 
1101     /**
1102      * get CRC32 from file.
1103      *
1104      * @param file source file
1105      * @return CRC32
1106      * @throws BundleException FileNotFoundException|IOException.
1107      */
getCrcFromFile(File file)1108     private static CRC32 getCrcFromFile(File file) throws BundleException {
1109         FileInputStream fileInputStream = null;
1110         CRC32 crc = new CRC32();
1111         try {
1112             fileInputStream = new FileInputStream(file);
1113             byte[] buffer = new byte[BUFFER_SIZE];
1114 
1115             int count = fileInputStream.read(buffer);
1116             while (count > 0) {
1117                 crc.update(buffer, 0, count);
1118                 count = fileInputStream.read(buffer);
1119             }
1120         } catch (FileNotFoundException ignored) {
1121             LOG.error("Uncompressor::getCrcFromFile file not found exception");
1122             throw new BundleException("Get Crc from file failed");
1123         } catch (IOException exception) {
1124             LOG.error("Uncompressor::getCrcFromFile io exception: " + exception.getMessage());
1125             throw new BundleException("Get Crc from file failed");
1126         } finally {
1127             Utility.closeStream(fileInputStream);
1128         }
1129         return crc;
1130     }
1131 
1132     /**
1133      * delete file
1134      *
1135      * @param file the file to be deleted
1136      */
deleteFile(File file)1137     private static void deleteFile(File file) {
1138         if (file.exists()) {
1139             if (file.isDirectory()) {
1140                 File[] files = file.listFiles();
1141                 for (int i = 0; i < files.length; i++) {
1142                     deleteFile(files[i]);
1143                 }
1144             }
1145             file.delete();
1146         }
1147     }
1148 
1149     /**
1150      * check
1151      *
1152      * @param result the result of parse app all mode
1153      * @return return the result of checkParseAllResult.
1154      */
checkParseAllResult(UncompressResult result)1155     private static UncompressResult checkParseAllResult(UncompressResult result) {
1156         UncompressResult errorResult = new UncompressResult();
1157         errorResult.setResult(false);
1158         errorResult.setMessage("App package is invalid.");
1159         if (result == null || result.getPackInfos() == null || result.getProfileInfos() == null) {
1160             return errorResult;
1161         }
1162 
1163         List<PackInfo> packInfos = result.getPackInfos();
1164         List<ProfileInfo> profileInfos = result.getProfileInfos();
1165         int packInfoSize = packInfos.size();
1166         int profileInfoSize = profileInfos.size();
1167         if (packInfoSize == 0 || profileInfoSize == 0 || packInfoSize != profileInfoSize) {
1168             LOG.error("Uncompress::checkParseAllResult error, hapNum is invalid in app");
1169             return errorResult;
1170         }
1171 
1172         for (int i = 0; i < packInfoSize; i++) {
1173             if (packInfos.get(i) == null || packInfos.get(i).name.isEmpty()) {
1174                 return errorResult;
1175             }
1176             boolean isHave = false;
1177             for (int j = 0; j < profileInfoSize; j++) {
1178                 if (profileInfos.get(j) == null || profileInfos.get(j).hapName.isEmpty()) {
1179                     return errorResult;
1180                 }
1181                 if (comparePackAndProfile(packInfos.get(i), profileInfos.get(j))) {
1182                     isHave = true;
1183                     break;
1184                 }
1185             }
1186             if (!isHave) {
1187                 return errorResult;
1188             }
1189         }
1190 
1191         return result;
1192     }
1193 
1194     /**
1195      * get label and icon for application
1196      *
1197      * @param result the result of parse app all mode
1198      * @return return the result which contains icon and label
1199      */
obtainLabelAndIcon(UncompressResult result)1200     private static UncompressResult obtainLabelAndIcon(UncompressResult result) {
1201         List<ProfileInfo> profileInfos = result.getProfileInfos();
1202         if (profileInfos.isEmpty()) {
1203             return result;
1204         }
1205         for (ProfileInfo profileInfo : profileInfos) {
1206             if (profileInfo == null) {
1207                 continue;
1208             }
1209             HapInfo hapInfo = profileInfo.hapInfo;
1210             if (hapInfo == null) {
1211                 continue;
1212             }
1213             Distro distro = hapInfo.distro;
1214             if (distro == null) {
1215                 continue;
1216             }
1217             String moduleType = distro.moduleType;
1218             if (ENTRY_TYPE.equals(moduleType.toLowerCase(Locale.ENGLISH))) {
1219                 return obtainInnerLabelAndIcon(result, hapInfo, distro);
1220             }
1221         }
1222         return result;
1223     }
1224 
1225     /**
1226      * get label and icon for application
1227      *
1228      * @param result the result of parse app all mode
1229      * @param hapInfo hap info of entry hap
1230      * @return return the result which contains icon and label
1231      */
obtainInnerLabelAndIcon(UncompressResult result, HapInfo hapInfo, Distro distro)1232     private static UncompressResult obtainInnerLabelAndIcon(UncompressResult result, HapInfo hapInfo, Distro distro) {
1233         List<AbilityInfo> abilities = hapInfo.abilities;
1234         if ((abilities == null) || (abilities.isEmpty())) {
1235             result.setLabel(distro.moduleName);
1236             return result;
1237         }
1238         int size = 0;
1239         for (AbilityInfo info : abilities) {
1240             if (info == null) {
1241                 size++;
1242                 continue;
1243             }
1244             if ((info.skills == null) || (info.skills.isEmpty())) {
1245                 continue;
1246             }
1247             for (SkillInfo skill : info.skills) {
1248                 if (skill == null) {
1249                     continue;
1250                 }
1251                 List<String> actions = skill.actions;
1252                 List<String> entities = skill.entities;
1253                 if ((!actions.isEmpty()) && (actions.contains(SYSTEM_ACTION) || actions.contains(SYSTEM_WANT_HOME))) {
1254                     if ((!entities.isEmpty()) && (entities.contains(SYSTEM_ENTITY))) {
1255                         result.setLabel(info.label);
1256                         result.setIcon(info.icon);
1257                         return result;
1258                     }
1259                 }
1260             }
1261         }
1262         if (size == abilities.size()) {
1263             result.setLabel(distro.moduleName);
1264             return result;
1265         }
1266         for (AbilityInfo info : abilities) {
1267             if (info != null) {
1268                 result.setLabel(info.label);
1269                 result.setIcon(info.icon);
1270                 break;
1271             }
1272         }
1273         return result;
1274     }
1275 
1276 
isHarmonyProfile(String fileName)1277     private static boolean isHarmonyProfile(String fileName) {
1278         return HARMONY_PROFILE.equals(fileName);
1279     }
1280 
isPackInfo(String fileName)1281     private static boolean isPackInfo(String fileName) {
1282         return PACK_INFO.equals(fileName);
1283     }
1284 
getHapNameWithoutSuffix(String hapFileName)1285     private static String getHapNameWithoutSuffix(String hapFileName) {
1286         if (hapFileName == null || hapFileName.isEmpty() || hapFileName.lastIndexOf(".") == -1) {
1287             return "";
1288         }
1289         return hapFileName.substring(0, hapFileName.lastIndexOf("."));
1290     }
1291 
unZipModuleHapFile(String srcPath)1292     private static HapZipInfo unZipModuleHapFile(String srcPath)
1293             throws BundleException, IOException {
1294         HapZipInfo hapZipInfo = new HapZipInfo();
1295         ZipFile zipFile = null;
1296         try {
1297             File srcFile = new File(srcPath);
1298             zipFile = new ZipFile(srcFile);
1299             getProfileJson(zipFile, hapZipInfo.resourcemMap);
1300             hapZipInfo.setHarmonyProfileJsonStr(FileUtils.getFileStringFromZip(MODULE_JSON, zipFile));
1301             hapZipInfo.setPackInfoJsonStr(FileUtils.getFileStringFromZip(PACK_INFO, zipFile));
1302             hapZipInfo.setResDataBytes(getResourceDataFromHap(zipFile));
1303             hapZipInfo.setHapFileName(getHapNameWithoutSuffix(srcFile.getName()));
1304         } finally {
1305             Utility.closeStream(zipFile);
1306         }
1307         return hapZipInfo;
1308     }
1309 
1310     /**
1311      * uncompress from HapZipInfo
1312      *
1313      * @param hapZipInfo hap zip info
1314      * @return the parse moduleResult
1315      * @throws BundleException FileNotFoundException|IOException.
1316      */
uncompressModuleJsonInfo(HapZipInfo hapZipInfo, ModuleResult moduleResult)1317     private static void uncompressModuleJsonInfo(HapZipInfo hapZipInfo, ModuleResult moduleResult)
1318             throws BundleException {
1319         ModuleProfileInfo moduleProfileInfo = JsonUtil.parseModuleProfileInfo(hapZipInfo.getHarmonyProfileJsonStr(),
1320                 hapZipInfo.getResDataBytes(), hapZipInfo.getPackInfoJsonStr(), hapZipInfo.getHapFileName(),
1321                 hapZipInfo.resourcemMap);
1322         moduleProfileInfo.hapName = hapZipInfo.getHapFileName();
1323         moduleResult.addModuleProfileInfo(moduleProfileInfo);
1324         moduleResult.moduleProfileStr.add(hapZipInfo.getHarmonyProfileJsonStr());
1325     }
1326 
1327     /**
1328      * uncompress from specified file name
1329      *
1330      * @param deviceType device type
1331      * @param srcPath source file path
1332      * @param fileName uncompress file name
1333      * @return the uncompress result
1334      * @throws BundleException FileNotFoundException|IOException.
1335      */
uncompressModule(String deviceType, String srcPath, String fileName)1336     private static ModuleResult uncompressModule(String deviceType, String srcPath, String fileName)
1337             throws BundleException {
1338         if (srcPath.isEmpty() || fileName.isEmpty()) {
1339             LOG.error("Uncompress::uncompressModule srcPath, fileName is empty!");
1340             throw new BundleException("uncompressModule failed, srcPath or fileName is empty");
1341         }
1342         ModuleResult moduleResult = new ModuleResult();
1343         try {
1344             HapZipInfo hapZipInfo = unZipModuleHapFile(srcPath);
1345             uncompressModuleJsonInfo(hapZipInfo, moduleResult);
1346             if (moduleResult.packInfos.isEmpty() && !hapZipInfo.getPackInfoJsonStr().isEmpty()) {
1347                 moduleResult.packInfos = JsonUtil.parsePackInfos(hapZipInfo.getPackInfoJsonStr());
1348             }
1349         } catch (IOException exception) {
1350             moduleResult.setResult(false);
1351             LOG.error("Uncompress::uncompressModule parseMode is invalid!");
1352         }
1353         return moduleResult;
1354     }
1355 
1356     /**
1357      * uncompress module hap.
1358      *
1359      * @param deviceType indicates the device type of uncompress mode.
1360      * @param srcPath indicates the path type of hap.
1361      * @param fileName indicates json file name.
1362      * @return the uncompress result
1363      */
unCompressModuleHap(String deviceType, String srcPath, String fileName)1364     static UncompressResult unCompressModuleHap(String deviceType, String srcPath, String fileName)
1365             throws BundleException{
1366         if (srcPath.isEmpty() || fileName.isEmpty()) {
1367             LOG.error("Uncompress::uncompress srcPath, fileName is empty!");
1368             throw new BundleException("Uncompress failed, srcPath or fileName is empty");
1369         }
1370         UncompressResult uncomperssResult = new UncompressResult();
1371         ModuleResult moduleResult = new ModuleResult();
1372         try {
1373             moduleResult = uncompressModule(deviceType, srcPath, fileName);
1374             ModuleAdaption moduleAdaption = new ModuleAdaption();
1375             uncomperssResult = moduleAdaption.convertToUncompressResult(moduleResult);
1376         } catch (BundleException ignored) {
1377             LOG.error("Uncompress::uncompressHap Bundle exception");
1378             uncomperssResult.setResult(false);
1379             uncomperssResult.setMessage("uncompressHap Bundle exception");
1380         }
1381         return uncomperssResult;
1382     }
1383     /**
1384      * get all resource in profile.
1385      *
1386      * @param zipFile is the hap file
1387      * @return the parse resource result
1388      */
getProfileJson(ZipFile zipFile, HashMap<String, String> resourceMap)1389     static void getProfileJson(ZipFile zipFile, HashMap<String, String> resourceMap) throws BundleException {
1390         try {
1391             final Enumeration<? extends ZipEntry> entries = zipFile.entries();
1392             while (entries.hasMoreElements()) {
1393                 final ZipEntry entry = entries.nextElement();
1394                 if (entry.getName().contains(RESOURCE_PATH)) {
1395                     String filePath = entry.getName();
1396                     String fileName = filePath.replaceAll(RESOURCE_PATH, "");
1397                     String fileContent = FileUtils.getFileStringFromZip(filePath, zipFile);
1398                     resourceMap.put(fileName, fileContent);
1399                 }
1400             }
1401         } catch (IOException e) {
1402             LOG.error("Uncompress::getProfileJson IOException");
1403             throw new BundleException("Uncompress::getProfileJson failed");
1404         }
1405     }
1406 
1407     /**
1408      * uncompress module hap.
1409      *
1410      * @param deviceType indicates the deviceType of parse hap.
1411      * @param input the InputStream about the app package.
1412      * @param fileName the file name of json file.
1413      * @return the uncompress result
1414      */
uncompressModuleHapByInput(String deviceType, InputStream input, String fileName, String hapName)1415     static UncompressResult uncompressModuleHapByInput(String deviceType,
1416                                                        InputStream input, String fileName, String hapName) {
1417         UncompressResult uncompressResult = new UncompressResult();
1418         ModuleResult moduleResult = new ModuleResult();
1419         try {
1420             moduleResult = uncompressModuleByInput(deviceType, input, MODULE_JSON, hapName);
1421             ModuleAdaption moduleAdaption = new ModuleAdaption();
1422             uncompressResult = moduleAdaption.convertToUncompressResult(moduleResult);
1423         } catch (BundleException ignored) {
1424             LOG.error("Uncompress::uncompressHapByInput Bundle exception");
1425             uncompressResult.setResult(false);
1426             uncompressResult.setMessage("uncompressHapByInput Bundle exception");
1427         }
1428         return uncompressResult;
1429     }
1430 
1431     /**
1432      * unzip module hap from zip file.
1433      *
1434      * @param input Indicates the InputStream about the package.
1435      * @return Return the uncomperss result of parseHap
1436      */
unZipModuleHapFileFromInputStream(InputStream input)1437     private static HapZipInfo unZipModuleHapFileFromInputStream(InputStream input) throws BundleException {
1438         BufferedInputStream bufIn = null;
1439         ZipInputStream zipIn = null;
1440         BufferedReader bufferedReader = null;
1441         HapZipInfo hapZipInfo = new HapZipInfo();
1442         try {
1443             ZipEntry entry = null;
1444             bufIn = new BufferedInputStream(input);
1445             zipIn = new ZipInputStream(bufIn);
1446             while ((entry = zipIn.getNextEntry()) != null) {
1447                 if (entry.getName().toLowerCase().endsWith(RESOURCE_INDEX)) {
1448                     hapZipInfo.setResDataBytes(getByte(zipIn));
1449                     continue;
1450                 }
1451                 if (isPackInfo(entry.getName())) {
1452                     bufferedReader = new BufferedReader(new InputStreamReader(zipIn));
1453                     hapZipInfo.setPackInfoJsonStr(readStringFromInputStream(zipIn, bufferedReader));
1454                     continue;
1455                 }
1456                 if (MODULE_JSON.equals(entry.getName())) {
1457                     bufferedReader = new BufferedReader(new InputStreamReader(zipIn));
1458                     hapZipInfo.setHarmonyProfileJsonStr(readStringFromInputStream(zipIn, bufferedReader));
1459                 }
1460                 if (entry.getName().contains(RESOURCE_PATH)) {
1461                     bufferedReader = new BufferedReader(new InputStreamReader(zipIn));
1462                     String filePath = entry.getName();
1463                     String fileName = filePath.replaceAll(RESOURCE_PATH, "");
1464                     String fileContent = readStringFromInputStream(zipIn, bufferedReader);
1465                     hapZipInfo.pushResourceMap(fileName, fileContent);
1466                 }
1467             }
1468         } catch (BundleException | IOException e) {
1469             LOG.error("unZipModuleHapFileFromInputStream failed!");
1470             throw new BundleException("unZipModuleHapFileFromInputStream failed!");
1471         } finally {
1472             Utility.closeStream(bufferedReader);
1473             Utility.closeStream(bufIn);
1474             Utility.closeStream(zipIn);
1475         }
1476         return hapZipInfo;
1477     }
1478 
1479     /**
1480      * Parse the hap type.
1481      *
1482      * @param hapPath Indicates the hap path.
1483      * @param compressResult Indicates the result of parse hap.
1484      * @return Return the type result of isModuleHap
1485      */
isModuleHap(String hapPath, UncompressResult compressResult)1486     public static boolean isModuleHap(String hapPath, UncompressResult compressResult) {
1487         ZipFile zipFile = null;
1488         try {
1489             zipFile = new ZipFile(new File(hapPath));
1490             final Enumeration<? extends ZipEntry> entries = zipFile.entries();
1491             while (entries.hasMoreElements()) {
1492                 final ZipEntry entry = entries.nextElement();
1493                 if (MODULE_JSON.equals(entry.getName())) {
1494                     return true;
1495                 }
1496             }
1497         } catch (FileNotFoundException ignored) {
1498             LOG.error("Uncompress::isModuleHap file not found exception");
1499             compressResult.setResult(false);
1500             compressResult.setMessage("judge is module failed");
1501         } catch (IOException exception) {
1502             LOG.error("Uncompress::isModuleHap io exception: " + exception.getMessage());
1503             compressResult.setResult(false);
1504             compressResult.setMessage("judge is module failed");
1505         } finally {
1506             Utility.closeStream(zipFile);
1507         }
1508         return false;
1509     }
1510 
1511     /**
1512      * Parse the hap type.
1513      *
1514      * @param input Indicates the hap FileInputStream.
1515      * @return Return the type result of isModuleHap.
1516      */
isModuleInput(InputStream input)1517     public static boolean isModuleInput(InputStream input) throws BundleException {
1518         BufferedInputStream bufIn = null;
1519         ZipInputStream zipIn = null;
1520         BufferedReader bufferedReader = null;
1521         try {
1522             ZipEntry entry = null;
1523             bufIn = new BufferedInputStream(input);
1524             zipIn = new ZipInputStream(bufIn);
1525             while((entry = zipIn.getNextEntry()) != null) {
1526                 if (entry.getName().toLowerCase().endsWith(MODULE_JSON)) {
1527                     return true;
1528                 }
1529             }
1530         } catch (IOException ignored) {
1531             LOG.error("Uncompress::isModuleHap judge failed!");
1532             throw new BundleException("Uncompress::isModuleHap judge failed!");
1533         } finally {
1534             Utility.closeStream(bufferedReader);
1535             Utility.closeStream(bufIn);
1536             Utility.closeStream(zipIn);
1537         }
1538         return false;
1539     }
1540 
1541     /**
1542      * create file output stream from InputStream .
1543      *
1544      * @param stream Indicates the input stream of hap.
1545      * @param file Indicates the temp file to save input stream.
1546      */
writeToTempFile(InputStream stream, File file)1547     static void writeToTempFile(InputStream stream, File file) throws BundleException {
1548         FileOutputStream fileOutputStream = null;
1549         try {
1550             if (file == null) {
1551                 LOG.error("file not exist!");
1552             }
1553             fileOutputStream = new FileOutputStream(file);
1554             int bytesRead = 0;
1555             byte[] buffer = new byte[1024];
1556             while ((bytesRead = stream.read(buffer)) != -1) {
1557                 fileOutputStream.write(buffer, 0, bytesRead);
1558             }
1559         } catch (IOException e) {
1560             LOG.error("writeToTempFile failed!");
1561             throw new BundleException("writeToTempFile failed!");
1562         } finally {
1563             Utility.closeStream(fileOutputStream);
1564         }
1565     }
1566 
1567     /**
1568      * copy rpcid.sc file.
1569      *
1570      * @param srcFile Indicates the path of hap.
1571      * @param rpcidPath Indicates the output path of rpcid.sc file.
1572      */
getRpcidFromHap(String srcFile, String rpcidPath)1573     static void getRpcidFromHap(String srcFile, String rpcidPath) throws BundleException {
1574         ZipFile zipFile = null;
1575         InputStream inputStream = null;
1576         FileOutputStream outputStream = null;
1577         try {
1578             zipFile = new ZipFile(srcFile);
1579             String filePath = null;
1580             final Enumeration<? extends ZipEntry> entries = zipFile.entries();
1581             while (entries.hasMoreElements()) {
1582                 final ZipEntry entry = entries.nextElement();
1583                 if (RPCID_SC.equals(entry.getName())) {
1584                     filePath = entry.getName();
1585                     break;
1586                 }
1587             }
1588             if (filePath != null) {
1589                 File rpcidFile = new File(rpcidPath, RPCID_SC);
1590                 if (rpcidFile.getParentFile() != null && !rpcidFile.getParentFile().exists()) {
1591                     rpcidFile.getParentFile().mkdirs();
1592                 }
1593                 ZipEntry rpcidEntry = zipFile.getEntry(filePath);
1594                 inputStream = zipFile.getInputStream(rpcidEntry);
1595                 byte[] buffer = new byte[1024];
1596                 int noBytes = 0;
1597                 outputStream = new FileOutputStream(rpcidFile);
1598                 while((noBytes = inputStream.read(buffer)) != -1) {
1599                     outputStream.write(buffer, 0, noBytes);
1600                 }
1601             } else {
1602                 LOG.error("Uncompress::getRpcidFromHap hap has no rpcid.sc file");
1603                 throw new BundleException("Uncompress::getRpcidFromHap hap has no rpcid.sc file");
1604             }
1605         } catch (IOException e) {
1606             LOG.error("Uncompress::getRpcidFromHap IOException " + e.getMessage());
1607             throw new BundleException("Uncompress::getRpcidFromHap failed");
1608         } finally {
1609             Utility.closeStream(zipFile);
1610             Utility.closeStream(inputStream);
1611             Utility.closeStream(outputStream);
1612         }
1613     }
1614 
1615     /**
1616      * parse resource.index file.
1617      *
1618      * @param srcPath Indicates the path of hap.
1619      */
getResourceFromHap(String srcPath)1620     static List<ResourceIndexResult> getResourceFromHap(String srcPath) throws BundleException, IOException {
1621         ZipFile zipFile = null;
1622         try {
1623             File srcFile = new File(srcPath);
1624             zipFile = new ZipFile(srcFile);
1625             byte[] data = getResourceDataFromHap(zipFile);
1626             return ResourcesParser.getAllDataItem(data);
1627         } finally {
1628             Utility.closeStream(zipFile);
1629         }
1630     }
1631 
1632     /**
1633      * uncompress appqf file.
1634      *
1635      * @param utility is the common args for input.
1636      * @throws BundleException if uncompress failed.
1637      */
uncompressAPPQFFile(Utility utility)1638     private static void uncompressAPPQFFile(Utility utility) throws BundleException {
1639         ZipFile zipFile = null;
1640         try {
1641             zipFile = new ZipFile(new File(utility.getAPPQFPath()));
1642             int entriesNum = 0;
1643             for (Enumeration<? extends ZipEntry> entries = zipFile.entries(); entries.hasMoreElements();) {
1644                 entriesNum++;
1645                 ZipEntry entry = entries.nextElement();
1646                 if (entry == null) {
1647                     continue;
1648                 }
1649                 String filePath = utility.getOutPath() + File.separator + entry.getName();
1650                 if (!FileUtils.matchPattern(filePath)) {
1651                     LOG.error("uncompressAPPQFFile: Input invalid file" + filePath);
1652                     throw new BundleException("uncompressAPPQFFile: Input invalid file" + filePath);
1653                 }
1654                 File destFile = new File(filePath);
1655                 if (destFile != null && destFile.getParentFile() != null && !destFile.getParentFile().exists()) {
1656                     destFile.getParentFile().mkdirs();
1657                 }
1658                 dataTransfer(zipFile, entry, destFile);
1659             }
1660         } catch (FileNotFoundException ignored) {
1661             LOG.error("Uncompress::uncompressAPPQFFile file not found exception");
1662             throw new BundleException("Uncompress::uncompressAPPQFFile file not found");
1663         } catch (IOException exception) {
1664             LOG.error("Uncompress::uncompressAPPQFFile io exception");
1665             throw new BundleException("Uncompress::uncompressAPPQFFile io exception");
1666         } finally {
1667             Utility.closeStream(zipFile);
1668         }
1669     }
1670 
1671     /**
1672      * parse appqf file, .
1673      *
1674      * @param appqfPath is the path of appqf file.
1675      * @throws BundleException if uncompress failed.
1676      * @throws IOException if IOException happened.
1677      */
parseAPPQFFile(String appqfPath)1678     public static List<HQFInfo> parseAPPQFFile(String appqfPath) throws BundleException {
1679         List<String> patchList = new ArrayList<>();
1680         ZipFile zipFile = null;
1681         InputStream stream = null;
1682         ZipInputStream zipInputStream = null;
1683         try {
1684             zipFile = new ZipFile(appqfPath);
1685             Enumeration<? extends ZipEntry> entries = zipFile.entries();
1686             while (entries.hasMoreElements()) {
1687                 ZipEntry appqfEntry = entries.nextElement();
1688                 stream = zipFile.getInputStream(appqfEntry);
1689                 if (!appqfEntry.getName().endsWith(HQF_SUFFIX)) {
1690                     continue;
1691                 }
1692                 zipInputStream = new ZipInputStream(stream);
1693                 String patchJson = readPatchJson(zipInputStream);
1694                 if (patchJson == null) {
1695                     continue;
1696                 }
1697                 patchList.add(patchJson);
1698             }
1699         } catch (IOException e) {
1700             LOG.error("parseAPPQFFile failed!");
1701             throw new BundleException("parseAPPQFFile failed!");
1702         } finally {
1703             Utility.closeStream(zipFile);
1704             Utility.closeStream(stream);
1705             Utility.closeStream(zipInputStream);
1706         }
1707         return parsePatchJson(patchList);
1708     }
1709 
readPatchJson(ZipInputStream zipInputStream)1710     private static String readPatchJson(ZipInputStream zipInputStream) throws BundleException {
1711         String patchJson = null;
1712         ZipEntry hqfEntry;
1713         try {
1714             while ((hqfEntry = zipInputStream.getNextEntry()) != null) {
1715                 if (!PATCH_JSON.equals(hqfEntry.getName())) {
1716                     continue;
1717                 }
1718                 patchJson = new BufferedReader(new InputStreamReader(zipInputStream,
1719                         StandardCharsets.UTF_8)).lines().parallel()
1720                         .collect(Collectors.joining(System.lineSeparator()));
1721             }
1722         } catch (IOException e) {
1723             LOG.error("readPatchJson failed!");
1724             throw new BundleException("readPatchJson failed!");
1725         }
1726         return patchJson;
1727     }
1728 
parsePatchJson(List<String> patchList)1729     private static List<HQFInfo> parsePatchJson(List<String> patchList) throws BundleException {
1730         List<HQFInfo> hqfInfoList = new ArrayList<>();
1731         for (String patchJson : patchList) {
1732             hqfInfoList.add(JsonUtil.parsePatch(patchJson));
1733         }
1734         return hqfInfoList;
1735     }
1736 
comparePackAndProfile(PackInfo packInfo, ProfileInfo profileInfo)1737     private static boolean comparePackAndProfile(PackInfo packInfo, ProfileInfo profileInfo) {
1738         if (profileInfo.hapName.replace(HAP_SUFFIXI, "").equals(packInfo.name.replace(HAP_SUFFIXI, ""))) {
1739             return true;
1740         }
1741         if (profileInfo.hapName.replace(HSP_SUFFIX, "").equals(packInfo.name.replace(HSP_SUFFIX, ""))) {
1742             return true;
1743         }
1744         return false;
1745     }
1746 }
1747