• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package ohos;
18 
19 import java.io.BufferedInputStream;
20 import java.io.BufferedReader;
21 import java.io.File;
22 import java.io.FileInputStream;
23 import java.io.FileNotFoundException;
24 import java.io.FileOutputStream;
25 import java.io.FileWriter;
26 import java.io.IOException;
27 import java.io.InputStreamReader;
28 import java.net.URL;
29 import java.nio.charset.StandardCharsets;
30 import java.security.NoSuchAlgorithmException;
31 import java.util.ArrayList;
32 import java.util.List;
33 import java.util.zip.ZipEntry;
34 import java.util.zip.ZipInputStream;
35 
36 /**
37  * scan info
38  *
39  * @since 2023/11/23
40  */
41 
42 public class Scan {
43     private static final String LINUX_FILE_SEPARATOR = "/";
44     private static final String EMPTY_STRING = "";
45     private static final String HTML_START = "<!DOCTYPE html><html lang=\"en\">";
46     private static final String HTML_END = "</html>";
47     private static final String STAT_JSON = "stat.json";
48     private static final String STAT_HTML = "stat.html";
49     private static final String STAT_CSS = "stat.css";
50     private static final String HTML_HEAD = "<head><meta charset=\"UTF-8\" name=\"stat\">"
51             + "<title>stat</title><link rel=\"stylesheet\" href=\"./stat.css\"></head>";
52     private static final String UNPACK_NAME = "unpack";
53     private static final String BACKUPS = "backups";
54     private static final String HAP = ".hap";
55     private static final String HSP = ".hsp";
56     private static final String TEMPLATE_HTML = "ohos/scan_template.html";
57     private static final String TEMPLATE_CSS = "ohos/scan_template.css";
58     private static final String DIV_BOX = "<div id=\"box\">";
59     private static final String HTML_BODY = "<body>";
60     private static final String HTML_DIV_END = "</div>";
61     private static final String HTML_BODY_END = "</body>";
62     private static final String USER_DIR = "user.dir";
63     private static final String HTML_BR = "<br/>";
64     private static final int BUFFER_SIZE = 10 * 1024;
65     private static final Log LOG = new Log(Scan.class.toString());
66 
67 
68     /**
69      * start scan.
70      *
71      * @param utility common data
72      * @return scanProcess if scan succeed
73      */
scanProcess(Utility utility)74     public boolean scanProcess(Utility utility) {
75         File destFile = new File(utility.getOutPath());
76         File outParentFile = destFile.getParentFile();
77         if ((outParentFile != null) && (!outParentFile.exists())) {
78             if (!outParentFile.mkdirs()) {
79                 LOG.error(ScanErrorEnum.SCAN_MKDIRS_ERROR.toString());
80                 return false;
81             }
82         }
83         boolean scanResult = true;
84         try {
85             scanExecute(utility);
86         } catch (FileNotFoundException exception) {
87             scanResult = false;
88             LOG.error(ScanErrorEnum.SCAN_NOT_FOUND_ERROR + exception.getMessage());
89         } catch (BundleException | NoSuchAlgorithmException | IOException exception) {
90             scanResult = false;
91             LOG.error(ScanErrorEnum.SCAN_REMIND_ERROR + exception.getMessage());
92         } finally {
93             if (!scanResult) {
94                 LOG.error(ScanErrorEnum.SCAN_COMPRESS_ERROR.toString());
95                 if (!destFile.delete()) {
96                     LOG.error(ScanErrorEnum.SCAN_DELETE_ERROR.toString());
97                 }
98             }
99         }
100         return scanResult;
101     }
102 
scanExecute(Utility utility)103     private void scanExecute(Utility utility) throws BundleException, IOException, NoSuchAlgorithmException {
104         List<String> jsonList = new ArrayList<>();
105         String templateHtml = getJsTemplate(TEMPLATE_HTML);
106         templateHtml = templateHtml.replace(HTML_BR, System.lineSeparator());
107         String htmlStr = HTML_START + HTML_HEAD + DIV_BOX + HTML_BODY + templateHtml;
108         String currentDir = System.getProperty(USER_DIR);
109         String targetPath = currentDir + LINUX_FILE_SEPARATOR + UNPACK_NAME;
110         List<String> fileList = getAllInputFileList(utility, targetPath);
111         if (utility.getStatDuplicate()) {
112             ScanStatDuplicate scanStatDuplicate = new ScanStatDuplicate();
113             String duplicateHtml = scanStatDuplicate.statDuplicate(utility, jsonList, fileList);
114             htmlStr = htmlStr + duplicateHtml;
115         }
116         if (null != utility.getStatFileSize() && !utility.getStatFileSize().isEmpty()) {
117             ScanStatFileSize scanStatFileSize = new ScanStatFileSize();
118             String fileSizeHtml = scanStatFileSize.statFileSize(utility, jsonList, fileList);
119             htmlStr = htmlStr + fileSizeHtml;
120         }
121         if (utility.getStatSuffix()) {
122             ScanStatSuffix scanStatSuffix = new ScanStatSuffix();
123             String suffixHtml = scanStatSuffix.statSuffix(utility, jsonList, fileList);
124             htmlStr = htmlStr + suffixHtml;
125         }
126         if (!((!utility.getStatDuplicate()) && !utility.getStatSuffix()
127                 && EMPTY_STRING.equals(utility.getStatFileSize()))) {
128             htmlStr = htmlStr + HTML_DIV_END + HTML_BODY_END + HTML_END;
129             String jsonPath = utility.getOutPath() + LINUX_FILE_SEPARATOR + STAT_JSON;
130             String htmlPath = utility.getOutPath() + LINUX_FILE_SEPARATOR + STAT_HTML;
131             String cssPath = utility.getOutPath() + LINUX_FILE_SEPARATOR + STAT_CSS;
132             writeFile(jsonPath, jsonList.toString());
133             writeFile(htmlPath, htmlStr);
134             String templateCss = getJsTemplate(TEMPLATE_CSS);
135             writeFile(cssPath, templateCss);
136         }
137         File deleteFile = new File(targetPath);
138         deleteFile(deleteFile);
139     }
140 
getAllInputFileList(Utility utility, String path)141     private List<String> getAllInputFileList(Utility utility, String path) throws BundleException, IOException {
142         ArrayList<String> fileList = new ArrayList<>();
143         unpackHap(utility.getInput(), path);
144         File file = new File(path);
145         File[] files = file.listFiles();
146         if (files == null) {
147             LOG.error(ScanErrorEnum.SCAN_NO_FILE_ERROR.toString());
148             return fileList;
149         }
150         String copyPath = path + LINUX_FILE_SEPARATOR + BACKUPS;
151         for (File f : files) {
152             String fileName = f.getName();
153             if (fileName.endsWith(HSP) || fileName.endsWith(HAP)) {
154                 String absolutePath = f.getCanonicalPath();
155                 File destDir = new File(copyPath);
156                 if (!destDir.exists()) {
157                     destDir.mkdirs();
158                 }
159                 String targetPath = copyPath + LINUX_FILE_SEPARATOR + fileName;
160                 File targetFile = new File(targetPath);
161                 File sourceFile = new File(absolutePath);
162                 FileUtils.copyFile(sourceFile, targetFile);
163                 File deleteFile = new File(absolutePath);
164                 deleteFile(deleteFile);
165                 String outPath = path + LINUX_FILE_SEPARATOR + fileName;
166                 File outDir = new File(outPath);
167                 if (!outDir.exists()) {
168                     outDir.mkdirs();
169                 }
170                 unpackHap(targetPath, outPath);
171             }
172         }
173         File deleteFile = new File(copyPath);
174         deleteFile(deleteFile);
175         FileUtils.getFileList(path, fileList);
176         return fileList;
177     }
178 
unpackHap(String srcPath, String outPath)179     private static void unpackHap(String srcPath, String outPath) throws BundleException {
180         try (FileInputStream fis = new FileInputStream(srcPath);
181              ZipInputStream zipInputStream = new ZipInputStream(new BufferedInputStream(fis))) {
182             File destDir = new File(outPath);
183             if (!destDir.exists()) {
184                 destDir.mkdirs();
185             }
186             unpackEntryToFile(zipInputStream, outPath);
187         } catch (IOException e) {
188             LOG.error(ScanErrorEnum.SCAN_UNPACK_ERROR + e.getMessage());
189             throw new BundleException(ScanErrorEnum.SCAN_UNPACK_ERROR.msg + e.getMessage());
190         }
191     }
192 
unpackEntryToFile(ZipInputStream zipInputStream, String outPath)193     private static void unpackEntryToFile(ZipInputStream zipInputStream, String outPath)
194             throws BundleException, IOException {
195         ZipEntry entry;
196         while ((entry = zipInputStream.getNextEntry()) != null) {
197             String entryName = entry.getName();
198             File entryFile = new File(outPath, entryName);
199 
200             if (entry.isDirectory()) {
201                 entryFile.mkdirs();
202                 zipInputStream.closeEntry();
203                 continue;
204             }
205             File parent = entryFile.getParentFile();
206             if (!parent.exists()) {
207                 parent.mkdirs();
208             }
209             try (FileOutputStream fos = new FileOutputStream(entryFile)) {
210                 byte[] buffer = new byte[BUFFER_SIZE];
211                 int bytesRead;
212                 while ((bytesRead = zipInputStream.read(buffer)) != -1) {
213                     fos.write(buffer, 0, bytesRead);
214                 }
215             } catch (IOException e) {
216                 LOG.error(ScanErrorEnum.SCAN_UNPACK_ERROR + e.getMessage());
217                 throw new BundleException(ScanErrorEnum.SCAN_UNPACK_ERROR.msg + e.getMessage());
218             }
219             zipInputStream.closeEntry();
220         }
221     }
222 
deleteFile(File file)223     private static void deleteFile(File file) {
224         if (file == null || !file.exists()) {
225             return;
226         }
227         if (file.isDirectory()) {
228             File[] files = file.listFiles();
229             for (File fileTmp : files) {
230                 deleteFile(fileTmp);
231             }
232         }
233         file.delete();
234     }
235 
getJsTemplate(String fileName)236     private static String getJsTemplate(String fileName) throws IOException {
237         ClassLoader classLoader = Scan.class.getClassLoader();
238         URL resource = classLoader.getResource(fileName);
239         try (BufferedReader bufferedReader = new BufferedReader(
240                 new InputStreamReader(resource.openStream(), StandardCharsets.UTF_8))) {
241             StringBuilder template = new StringBuilder();
242             String line;
243             while ((line = bufferedReader.readLine()) != null) {
244                 template.append(line);
245             }
246             return template.toString();
247         } catch (IOException e) {
248             LOG.error(ScanErrorEnum.SCAN_GET_JS_TEMPLATE_ERROR + e.getMessage());
249             throw new IOException(ScanErrorEnum.SCAN_GET_JS_TEMPLATE_ERROR.msg + e.getMessage());
250         }
251     }
252 
writeFile(String targetPath, String data)253     private static void writeFile(String targetPath, String data) throws IOException {
254         try (FileWriter fileWriter = new FileWriter(targetPath)) {
255             fileWriter.write(data);
256             fileWriter.flush();
257         } catch (IOException e) {
258             LOG.error(ScanErrorEnum.SCAN_WRITEFILE_ERROR + e.getMessage());
259             throw new IOException(ScanErrorEnum.SCAN_WRITEFILE_ERROR.msg + e.getMessage());
260         }
261     }
262 }
263