jsonList = new ArrayList<>();
+ String htmlStr = HTML_START + HTML_HEAD + "" + "" + HTML_FUNCTION;
+ if (TRUE.equals(utility.getStatDuplicate())) {
+ String duplicateHtml = statDuplicate(utility, jsonList);
+ htmlStr = htmlStr + duplicateHtml;
+ }
+ if (null != utility.getStatFileSize() && !utility.getStatFileSize().isEmpty()) {
+ String fileSizeHtml = statFileSize(utility, jsonList);
+ htmlStr = htmlStr + fileSizeHtml;
+ }
+ if (TRUE.equals(utility.getStatSuffix())) {
+ String suffixHtml = statSuffix(utility, jsonList);
+ htmlStr = htmlStr + suffixHtml;
+ }
+ if (!((FALSE.equals(utility.getStatDuplicate())) && FALSE.equals(utility.getStatSuffix())
+ && EMPTY_STRING.equals(utility.getStatFileSize()))) {
+ htmlStr = htmlStr + "
" + "" + HTML_END;
+ String jsonPath = utility.getOutPath() + LINUX_FILE_SEPARATOR + STAT_JSON;
+ String htmlPath = utility.getOutPath() + LINUX_FILE_SEPARATOR + STAT_HTML;
+ String cssPath = utility.getOutPath() + LINUX_FILE_SEPARATOR + STAT_CSS;
+ writeFile(jsonPath, jsonList.toString());
+ writeFile(htmlPath, htmlStr);
+ writeFile(cssPath, CSS_TEMPLATE);
+ }
+ }
+ private List getAllInputFileList(Utility utility, String path) throws BundleException, IOException {
+ ArrayList fileList = new ArrayList<>();
+ unpackHap(utility.getInput(), path);
+ File file = new File(path);
+ File[] files = file.listFiles();
+ if (files == null) {
+ LOG.error("getAllInputFileList: no file in this file path.");
+ return fileList;
+ }
+ String copyPath = path + LINUX_FILE_SEPARATOR + BACKUPS;
+ for (File f : files) {
+ String fName = f.getName();
+ if (fName.endsWith(HSP) || fName.endsWith(HAP)) {
+ String absolutePath = f.getCanonicalPath();
+ File destDir = new File(copyPath);
+ if (!destDir.exists()) {
+ destDir.mkdirs();
+ }
+ String targetPath = copyPath + LINUX_FILE_SEPARATOR + fName;
+ File targetFile = new File(targetPath);
+ File sourceFile = new File(absolutePath);
+ FileUtils.copyFile(sourceFile, targetFile);
+ deleteFile(absolutePath);
+ String outPath = path + LINUX_FILE_SEPARATOR + fName;
+ File outDir = new File(outPath);
+ if (!outDir.exists()) {
+ outDir.mkdirs();
+ }
+ unpackHap(targetPath, outPath);
+ }
+ }
+ deleteFile(copyPath);
+ FileUtils.getFileList(path, fileList);
+ return fileList;
+ }
+ private List getDuplicateResList(List fileList) throws IOException, NoSuchAlgorithmException {
+ List resList = new ArrayList<>();
+ for (String filePath : fileList) {
+ boolean addFlag = true;
+ String md5 = md5HashCode(filePath);
+ for (ParamModel element : resList) {
+ String eleMd5 = element.getMd5();
+ if (eleMd5.equals(md5)) {
+ List eleFiles = element.getFiles();
+ eleFiles.add(cutPath(filePath, DUPLICATE_FOLDER_NAME));
+ element.setFiles(eleFiles);
+ addFlag = false;
+ }
+ }
+ if (addFlag) {
+ ParamModel model = new ParamModel();
+ long size = FileUtils.getFileSize(filePath);
+ model.setMd5(md5);
+ model.setSize(size);
+ List files = model.getFiles();
+ files.add(cutPath(filePath, DUPLICATE_FOLDER_NAME));
+ resList.add(model);
+ }
+ }
+ return resList;
+ }
+ private String statDuplicate(Utility utility, List jsonList)
+ throws BundleException, IOException, NoSuchAlgorithmException {
+ DuplicateResult duplicateResult = new DuplicateResult();
+ duplicateResult.setStartTime(getCurrentTime());
+ String currentDir = System.getProperty("user.dir");
+ String targetPath = currentDir + LINUX_FILE_SEPARATOR + DUPLICATE_FOLDER_NAME;
+ List fileList = getAllInputFileList(utility, targetPath);
+ List resList = getDuplicateResList(fileList);
+ File parentFile = new File(utility.getOutPath());
+ if (!parentFile.exists() && !parentFile.mkdirs()) {
+ LOG.error("Compressor::compressHapAddition create target file parent directory failed.");
+ }
+ List filterList = new ArrayList<>();
+ for (ParamModel m : resList) {
+ List files = m.getFiles();
+ if (files.size() > 1) {
+ filterList.add(m);
+ }
+ }
+ duplicateResult.setResult(filterList);
+ duplicateResult.setStopTime(getCurrentTime());
+ String taskTypeHtml = getHtmlRow(TASK_TYPE, duplicateResult.getTaskType());
+ String taskDescHtml = getHtmlRow(TASK_DESC, duplicateResult.getTaskDesc());
+ String paramHtml = getHtmlRow(PARAM, duplicateResult.getParam());
+ String startTimeHtml = getHtmlRow(START_TIME, duplicateResult.getStartTime());
+ String stopTimeHtml = getHtmlRow(STOP_TIME, duplicateResult.getStopTime());
+ String resultValue = getResultHtml(duplicateResult.getResult());
+ String resultHtml = getHtmlRowResultClass(RESULT, resultValue);
+ String htmlStr = "" + taskTypeHtml + taskDescHtml + paramHtml
+ + startTimeHtml + stopTimeHtml + resultHtml + "
";
+ deleteFile(targetPath);
+ String jsonStr = JSON.toJSONString(duplicateResult, new SerializerFeature[]{
+ SerializerFeature.PrettyFormat, SerializerFeature.WriteMapNullValue,
+ SerializerFeature.WriteDateUseDateFormat});
+ jsonList.add(jsonStr);
+ return htmlStr;
+ }
+ private String statSuffix(Utility utility, List jsonList)
+ throws BundleException, IOException {
+ SuffixResult suffixResult = new SuffixResult();
+ suffixResult.setStartTime(getCurrentTime());
+ String currentDir = System.getProperty("user.dir");
+ String targetPath = currentDir + LINUX_FILE_SEPARATOR + SUFFIX_FOLDER_NAME;
+ String outPath = currentDir + LINUX_FILE_SEPARATOR + TMP_FOLDER_NAME;
+ String packageName = utility.getInput();
+ unpackHap(packageName, outPath);
+ ArrayList soList = new ArrayList<>();
+ suffixResult.setPathList(setPathListData(outPath, packageName, soList));
+ List fileList = getAllInputFileList(utility, targetPath);
+ List resulList = setMapData(outPath, fileList, soList);
+ resulList.sort(Comparator.comparing(ParamModelSuffix::getTotalSize).reversed());
+ suffixResult.setResult(resulList);
+ File parentFile = new File(utility.getOutPath());
+ if (!parentFile.exists() && !parentFile.mkdirs()) {
+ LOG.error("Compressor::compressHapAddition create target file parent directory failed.");
+ }
+ deleteFile(outPath);
+ suffixResult.setStopTime(getCurrentTime());
+ String htmlStr = setHtmlData(suffixResult);
+ deleteFile(targetPath);
+ String jsonStr = JSON.toJSONString(suffixResult, new SerializerFeature[] {
+ SerializerFeature.PrettyFormat, SerializerFeature.WriteMapNullValue,
+ SerializerFeature.WriteDateUseDateFormat});
+ jsonList.add(jsonStr);
+ return htmlStr;
+ }
+ private List setPathListData(String outPath, String packageName, ArrayList soList) {
+ List pathList = new ArrayList<>();
+ FileUtils.getFileList(outPath, soList);
+ File pack = new File(packageName);
+ for (String file : soList) {
+ if (file.contains(HAP) || file.contains(HSP)) {
+ file = cutPath(file, TMP_FOLDER_NAME);
+ pathList.add(pack.getName() + file);
+ }
+ }
+ return pathList;
+ }
+ private List setMapData(String outPath, List fileList, ArrayList soList) {
+ HashMap> hashMap = new HashMap<>();
+ List resulList = new ArrayList<>();
+ for (String filePath : fileList) {
+ hashMap = accountFileType(hashMap, filePath);
+ }
+ String osName = System.getProperty(OS_NAME);
+ Iterator iterator = hashMap.keySet().iterator();
+ while (iterator.hasNext()) {
+ String next = iterator.next();
+ ParamModelSuffix paramModelSuffix = new ParamModelSuffix();
+ paramModelSuffix.setSuffix(next);
+ if (next.equalsIgnoreCase(FILE_TYPE_SO)) {
+ List soFiles = new ArrayList<>();
+ List fileInfoList = hashMap.get(next);
+ long sum = ZERO;
+ for (FileInfo param : fileInfoList) {
+ SoFile soFile = new SoFile();
+ soFile.setSize(param.getSize());
+ String soFilePath = param.getFile();
+ soFilePath = cutPath(soFilePath, SUFFIX_FOLDER_NAME);
+ soFile.setFile(soFilePath);
+ int i = judgeValue(osName, soFilePath);
+ String hapPath = soFilePath.substring(NUM_ZERO, i);
+ File hapFile = new File(hapPath);
+ long oldSize = setOldValue(soList, hapFile);
+ long newSize = setNewValue(fileInfoList, hapFile);
+ soFile.setCompress(oldSize < newSize ? TRUE : FALSE);
+ soFiles.add(soFile);
+ sum += param.getSize();
+ }
+ deleteFile(outPath);
+ paramModelSuffix.setTotalSize(sum);
+ soFiles.sort(Comparator.comparing(SoFile::getSize).reversed());
+ paramModelSuffix.setFiles(soFiles);
+ } else {
+ List fileInfoList = hashMap.get(next);
+ for (FileInfo fileInfo : fileInfoList) {
+ String sonFilePath = fileInfo.getFile();
+ fileInfo.setFile(cutPath(sonFilePath, SUFFIX_FOLDER_NAME));
+ }
+ fileInfoList.sort(Comparator.comparing(FileInfo::getSize).reversed());
+ paramModelSuffix.setFiles(fileInfoList);
+ long sum = fileInfoList.stream().mapToLong(FileInfo::getSize).sum();
+ paramModelSuffix.setTotalSize(sum);
+ }
+ resulList.add(paramModelSuffix);
+ }
+ return resulList;
+ }
+ private String setHtmlData(SuffixResult suffixResult) {
+ String pathHtml = EMPTY_STRING;
+ if (suffixResult.getPathList() != null && !suffixResult.getPathList().isEmpty()) {
+ pathHtml = getPathListHtml(suffixResult.getPathList());
+ }
+ String pathListHtml = EMPTY_STRING;
+ if (!pathHtml.isEmpty() || !EMPTY_STRING.equals(pathHtml)) {
+ pathListHtml = getHtmlRow(PATH_LIST, pathHtml);
+ }
+ String taskTypeHtml = getHtmlRow(TASK_TYPE, suffixResult.getTaskType());
+ String taskDescHtml = getHtmlRow(TASK_DESC, suffixResult.getTaskDesc());
+ String paramHtml = getHtmlRow(PARAM, suffixResult.getParam());
+ String startTimeHtml = getHtmlRow(START_TIME, suffixResult.getStartTime());
+ String stopTimeHtml = getHtmlRow(STOP_TIME, suffixResult.getStopTime());
+ String resultValue = getResultHtmlOfSuffix(suffixResult.getResult());
+ String resultHtml = getHtmlRowResultClass(RESULT, resultValue);
+ return "" + taskTypeHtml + taskDescHtml + paramHtml
+ + startTimeHtml + stopTimeHtml + pathListHtml + resultHtml + "
";
+ }
+ private String statFileSize(Utility utility, List jsonList)
+ throws BundleException, IOException {
+ FileSizeResult fileSizeResult = new FileSizeResult();
+ fileSizeResult.setStartTime(getCurrentTime());
+ String currentDir = System.getProperty("user.dir");
+ String targetPath = currentDir + LINUX_FILE_SEPARATOR + FILE_SIZE_FOLDER_NAME;
+ List fileList = getAllInputFileList(utility, targetPath);
+ List resList = new ArrayList<>();
+ for (String filePath : fileList) {
+ long statFileSize = Long.parseLong(utility.getStatFileSize());
+ long size = FileUtils.getFileSize(filePath);
+ if (size > statFileSize) {
+ ParamModelFileSize model = new ParamModelFileSize();
+ model.setFile(cutPath(filePath, FILE_SIZE_FOLDER_NAME));
+ model.setSize(size);
+ resList.add(model);
+ }
+ }
+ resList.sort(Comparator.comparing(ParamModelFileSize::getSize).reversed());
+ fileSizeResult.setResult(resList);
+ fileSizeResult.setParam(String.format(fileSizeResult.getParam(), utility.getStatFileSize()));
+ fileSizeResult.setStopTime(getCurrentTime());
+ File parentFile = new File(utility.getOutPath());
+ if (!parentFile.exists() && !parentFile.mkdirs()) {
+ LOG.error("Compressor::compressHapAddition create target file parent directory failed.");
+ }
+ String jsonStr = JSON.toJSONString(fileSizeResult, new SerializerFeature[]{
+ SerializerFeature.PrettyFormat, SerializerFeature.WriteMapNullValue,
+ SerializerFeature.WriteDateUseDateFormat});
+ String taskTypeHtml = getHtmlRow(TASK_TYPE, fileSizeResult.getTaskType());
+ String taskDescHtml = getHtmlRow(TASK_DESC, fileSizeResult.getTaskDesc());
+ String paramHtml = getHtmlRow(PARAM, fileSizeResult.getParam());
+ String startTimeHtml = getHtmlRow(START_TIME, fileSizeResult.getStartTime());
+ String stopTimeHtml = getHtmlRow(STOP_TIME, fileSizeResult.getStopTime());
+ String resultValue = getResultHtmlFileSize(fileSizeResult.getResult());
+ String resultHtml = getHtmlRowResultClass(RESULT, resultValue);
+ String htmlStr = "" + taskTypeHtml + taskDescHtml + paramHtml
+ + startTimeHtml + stopTimeHtml + resultHtml + "
";
+ deleteFile(targetPath);
+ jsonList.add(jsonStr);
+ return htmlStr;
+ }
+ private String cutPath(String path, String packageName) {
+ String[] split = path.split(packageName);
+ return split[1];
+ }
+ private int judgeValue(String osName, String soFilePath) {
+ int i = NUM_ZERO;
+ if (osName.startsWith(WIN)) {
+ i = soFilePath.indexOf(WIN_FILE_SEPARATOR + LIBS_NAME);
+ } else {
+ i = soFilePath.indexOf(LINUX_FILE_SEPARATOR + LIBS_NAME);
+ }
+ return i;
+ }
+ private long setOldValue(List soList, File hapFile) {
+ long oldSize = ZERO;
+ for (String file : soList) {
+ File tmp = new File(file);
+ if (tmp.getName().equals(hapFile.getName())) {
+ oldSize = tmp.length();
+ }
+ }
+ return oldSize;
+ }
+ private long setNewValue(List fileInfoList, File hapFile) {
+ long newSize = ZERO;
+ for (FileInfo fileInfo : fileInfoList) {
+ if (fileInfo.getFile().contains(hapFile.getPath())) {
+ File tmp = new File(fileInfo.getFile());
+ newSize += tmp.length();
+ }
+ }
+ return newSize;
+ }
+ private static HashMap> accountFileType(HashMap> hashMap, String f) {
+ File file = new File(f);
+ String[] split = file.getName().split("\\.");
+ if (split.length == SCAN_LEVEL) {
+ if (hashMap.containsKey(split[1])) {
+ putValueIntoHashmap(hashMap, file, split[1]);
+ } else {
+ putValueIntoHashMapNew(hashMap, file, split[1]);
+ }
+ } else if (split.length == 1) { // no suffix
+ if (hashMap.containsKey(SUFFIX_TYPE_UNKNOWN)) {
+ putValueIntoHashmap(hashMap, file, SUFFIX_TYPE_UNKNOWN);
+ } else {
+ putValueIntoHashMapNew(hashMap, file, SUFFIX_TYPE_UNKNOWN);
+ }
+ }
+ return hashMap;
+ }
+ private static void putValueIntoHashmap(HashMap> hashMap, File file, String key) {
+ FileInfo fileInfo = setModelValue(file);
+ List paramModel2s = hashMap.get(key);
+ paramModel2s.add(fileInfo);
+ hashMap.put(key, paramModel2s);
+ }
+ private static void putValueIntoHashMapNew(HashMap> hashMap,
+ File file, String key) {
+ FileInfo fileInfo = setModelValue(file);
+ List fileNew = new ArrayList<>();
+ fileNew.add(fileInfo);
+ hashMap.put(key, fileNew);
+ }
+ private static FileInfo setModelValue(File file) {
+ FileInfo fileInfo = new FileInfo();
+ fileInfo.setFile(file.getPath());
+ long size = FileUtils.getFileSize(file.getPath());
+ fileInfo.setSize(size);
+ return fileInfo;
+ }
+ private static String getResultHtml(List models) {
+ StringBuilder resultHtml = new StringBuilder(EMPTY_STRING);
+ resultHtml.append("");
+ for (int i = 0; i < models.size(); i++) {
+ ParamModel model = models.get(i);
+ String md5Html = getHtmlRowResult(RESULT_MD5, model.getMd5(),
+ " class=\"duplicateLayout\"", " class=\"duplicateKey\"", " class=\"duplicateValue\"");
+ String sizeHtml = getHtmlRowResult(RESULT_SIZE, model.getSize(),
+ " class=\"duplicateLayout\"", " class=\"duplicateKey\"", " class=\"duplicateValue\"");
+ String filesHtml = getHtmlRowResult(RESULT_FILES, model.getFiles());
+ String liHtml;
+ if (SHOW_SIZE > i) {
+ liHtml = "- ";
+ } else {
+ liHtml = "
- ";
+ }
+ String modelHtml = liHtml + "
"
+ + md5Html + sizeHtml + filesHtml + "
";
+ resultHtml.append(modelHtml);
+ }
+ resultHtml.append("
");
+ if (models.size() > SHOW_SIZE) {
+ resultHtml.append(String.format(HTML_BUTTON_SHOW, DUPLICATE_FOLDER_NAME, DUPLICATE_FOLDER_NAME));
+ resultHtml.append(String.format(HTML_BUTTON_HIDE, DUPLICATE_FOLDER_NAME, DUPLICATE_FOLDER_NAME));
+ }
+ return resultHtml.toString();
+ }
+ private static String getPathListHtml(List models) {
+ StringBuilder pathListHtml = new StringBuilder(EMPTY_STRING);
+ for (String strHtml : models) {
+ pathListHtml.append(strHtml).append("
");
+ }
+ return pathListHtml.toString();
+ }
+ private static String getResultHtmlOfSuffix(List models) {
+ StringBuilder resultHtml = new StringBuilder(EMPTY_STRING);
+ resultHtml.append("");
+ for (int i = 0; i < models.size(); i++) {
+ ParamModelSuffix model = models.get(i);
+ String filesHtml;
+ if (model.getSuffix().equalsIgnoreCase(FILE_TYPE_SO)) {
+ filesHtml = getHtmlRowSonSo(RESULT_FILES, model.getFiles());
+ } else {
+ filesHtml = getHtmlRowSon(RESULT_FILES, model.getFiles());
+ }
+ String liHtml;
+ if (SHOW_SIZE > i) {
+ liHtml = "- ";
+ } else {
+ liHtml = "
- ";
+ }
+ String suffixHtml = getHtmlRowResult(SUFFIX_FOLDER_NAME, model.getSuffix(),
+ " class=\"suffixLayout\"", " class=\"suffixKey\"", " class=\"suffixValue\"");
+ String totalSizeHtml = getHtmlRowResult(RESULT_TOTAL_SIZE, model.getTotalSize(),
+ " class=\"suffixLayout\"", " class=\"suffixKey\"", " class=\"suffixValue\"");
+ String modelHtml = liHtml + "
"
+ + suffixHtml + totalSizeHtml + filesHtml + "
";
+ resultHtml.append(modelHtml);
+ }
+ resultHtml.append("
");
+ if (models.size() > SHOW_SIZE) {
+ resultHtml.append(String.format(HTML_BUTTON_SHOW, SUFFIX_FOLDER_NAME, SUFFIX_FOLDER_NAME));
+ resultHtml.append(String.format(HTML_BUTTON_HIDE, SUFFIX_FOLDER_NAME, SUFFIX_FOLDER_NAME));
+ }
+ return resultHtml.toString();
+ }
+ private static String getResultHtmlFileSize(List models) {
+ StringBuilder resultHtml = new StringBuilder(EMPTY_STRING);
+ resultHtml.append("");
+ String resultFieldHtml = getHtmlRowResult(FILE_SIZE_RESULT_FILE, FILE_SIZE_RESULT_SIZE,
+ " class=\"fileSizeLayout\"", " class=\"fileSizeKey\"", " class=\"fileSizeValue\"");
+ resultHtml.append(resultFieldHtml);
+ for (int i = 0; i < models.size(); i++) {
+ ParamModelFileSize model = models.get(i);
+ String resultRowHtml;
+ if (SHOW_SIZE > i) {
+ resultRowHtml = getHtmlRowResult(model.getFile(), model.getSize(),
+ " class=\"fileSizeLayout\"", " class=\"fileSizeKey\"", " class=\"fileSizeValue\"");
+ } else {
+ resultRowHtml = getHtmlRowResult(model.getFile(), model.getSize(),
+ " class=\"fileSize\"", " class=\"fileSizeKey\"", " class=\"fileSizeValue\"");
+ }
+ resultHtml.append(resultRowHtml);
+ }
+ resultHtml.append("
");
+ if (models.size() > SHOW_SIZE) {
+ resultHtml.append(String.format(HTML_BUTTON_SHOW, FILE_SIZE_FOLDER_NAME, FILE_SIZE_FOLDER_NAME));
+ resultHtml.append(String.format(HTML_BUTTON_HIDE, FILE_SIZE_FOLDER_NAME, FILE_SIZE_FOLDER_NAME));
+ }
+ return resultHtml.toString();
+ }
+ private static String getHtmlRow(String key, String valve) {
+ return "" + key + " | " + valve + " |
";
+ }
+ private static String getHtmlRow(String key, long valve) {
+ return "" + key + " | " + valve + " |
";
+ }
+ private static String getHtmlRowResultClass(String key, String valve) {
+ return "" + key + " | " + valve + " |
";
+ }
+ private static String getHtmlRowResult(String key, String valve,
+ String trClass, String tdClassKey, String tdClassValue) {
+ return String.format("" + key + " | " + valve + " |
",
+ trClass, tdClassKey, tdClassValue);
+ }
+ private static String getHtmlRowResult(String key, long valve,
+ String trClass, String tdClassKey, String tdClassValue) {
+ return String.format("" + key + " | " + valve + " |
",
+ trClass, tdClassKey, tdClassValue);
+ }
+ private static String getHtmlRowResult(String key, List valve) {
+ StringBuilder resValve = new StringBuilder(EMPTY_STRING);
+ for (String ele : valve) {
+ resValve.insert(0, "" + ele + "");
+ }
+ return "" + key
+ + " | |
";
+ }
+ private static String getHtmlRowSon(String key, List files) {
+ StringBuilder resValve = new StringBuilder(EMPTY_STRING);
+ for (FileInfo son : files) {
+ resValve.insert(0, RESULT_FILE + ":" + son.getFile() + "
");
+ resValve.insert(0, RESULT_SIZE + ":" + son.getSize() + "
");
+ }
+ return "" + key
+ + " | " + resValve + " |
";
+ }
+ private static String getHtmlRowSonSo(String key, List files) {
+ StringBuilder resValve = new StringBuilder(EMPTY_STRING);
+ for (SoFile so : files) {
+ resValve.insert(0, RESULT_FILE + ":" + so.getFile() + "
");
+ resValve.insert(0, RESULT_SIZE + ":" + so.getSize() + "
");
+ resValve.insert(0, RESULT_COMPRESS + ":" + so.getCompress() + "
");
+ }
+ return "" + key
+ + " | " + resValve + " |
";
+ }
+ private static String getCurrentTime() {
+ long currentTimeMillis = System.currentTimeMillis();
+ return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS").format(currentTimeMillis);
+ }
+ private static void unpackHap(String srcPath, String outPath) throws BundleException {
+ try (FileInputStream fis = new FileInputStream(srcPath);
+ ZipInputStream zipInputStream = new ZipInputStream(new BufferedInputStream(fis))) {
+ File destDir = new File(outPath);
+ if (!destDir.exists()) {
+ destDir.mkdirs();
+ }
+ ZipEntry entry;
+ while ((entry = zipInputStream.getNextEntry()) != null) {
+ String entryName = entry.getName();
+ File entryFile = new File(outPath, entryName);
+
+ if (entry.isDirectory()) {
+ entryFile.mkdirs();
+ zipInputStream.closeEntry();
+ continue;
+ }
+ File parent = entryFile.getParentFile();
+ if (!parent.exists()) {
+ parent.mkdirs();
+ }
+
+ FileOutputStream fos = new FileOutputStream(entryFile);
+ byte[] buffer = new byte[BUFFER_SIZE];
+ int bytesRead;
+ while ((bytesRead = zipInputStream.read(buffer)) != MINUS_ONE) {
+ fos.write(buffer, 0, bytesRead);
+ }
+ fos.close();
+ zipInputStream.closeEntry();
+ }
+ } catch (IOException e) {
+ LOG.error("unpack hap failed IOException " + e.getMessage());
+ throw new BundleException("unpack hap failed IOException " + e.getMessage());
+ }
+ }
+ private String md5HashCode(String filePath) throws IOException, NoSuchAlgorithmException {
+ MessageDigest md = MessageDigest.getInstance(SHA_256);
+ InputStream fis = new FileInputStream(filePath);
+ byte[] buffer = new byte[MD5_BUFFER_SIZE];
+ int length = MINUS_ONE;
+ while ((length = fis.read(buffer, 0, MD5_BUFFER_SIZE)) != MINUS_ONE) {
+ md.update(buffer, 0, length);
+ }
+ fis.close();
+ byte[] md5Bytes = md.digest();
+ BigInteger bigInt = new BigInteger(1, md5Bytes);
+ return bigInt.toString(MD5_LENGTH);
+ }
+ private static void deleteFile(final String path) {
+ File file = new File(path);
+ if (file.exists()) {
+ if (file.isDirectory()) {
+ File[] files = file.listFiles();
+ for (int i = 0; i < files.length; i++) {
+ deleteFile(files[i].toString());
+ }
+ }
+ file.delete();
+ }
+ }
+ private static void writeFile(String targetPath, String data) throws IOException {
+ FileWriter fileWriter = new FileWriter(targetPath);
+ fileWriter.write(data);
+ fileWriter.flush();
+ fileWriter.close();
+ }
+}
diff --git a/adapter/ohos/ScanEntrance.java b/adapter/ohos/ScanEntrance.java
new file mode 100644
index 0000000000000000000000000000000000000000..4b282415af0642e0d2051c72ac77f4d1d0ae6abf
--- /dev/null
+++ b/adapter/ohos/ScanEntrance.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ohos;
+
+/**
+ * scanEntrance info
+ *
+ * @since 2023/11/23
+ */
+
+public class ScanEntrance {
+ private static final int EXIT_STATUS_NORMAL = 0;
+ private static final int EXIT_STATUS_EXCEPTION = 1;
+ private static final Log LOG = new Log(ScanEntrance.class.toString());
+
+
+ /**
+ * scan tool main function.
+ *
+ * @param args command line
+ */
+
+ public static void main(String[] args) {
+ Utility utility = new Utility();
+
+ if (!CommandParser.commandParser(utility, args)) {
+ LOG.error("ScanEntrance::main exit, parser failed");
+ ShowHelp.scanHelp();
+ System.exit(EXIT_STATUS_EXCEPTION);
+ }
+
+ if (!ScanVerify.commandVerify(utility)) {
+ LOG.error("ScanEntrance::main exit, verify failed");
+ ShowHelp.scanHelp();
+ System.exit(EXIT_STATUS_EXCEPTION);
+ }
+
+ Scan scan = new Scan();
+ if (!scan.scanProcess(utility)) {
+ LOG.error("ScanEntrance::main exit, compress failed");
+ ShowHelp.scanHelp();
+ System.exit(EXIT_STATUS_EXCEPTION);
+ }
+
+ System.exit(EXIT_STATUS_NORMAL);
+ }
+}
\ No newline at end of file
diff --git a/adapter/ohos/ScanVerify.java b/adapter/ohos/ScanVerify.java
new file mode 100644
index 0000000000000000000000000000000000000000..23e60adb74523174c40ad473deb0bb1b730052b4
--- /dev/null
+++ b/adapter/ohos/ScanVerify.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ohos;
+
+import java.math.BigDecimal;
+import java.util.regex.Pattern;
+
+/**
+ * scanVerify info
+ *
+ * @since 2023/11/23
+ */
+
+public class ScanVerify {
+
+ static final String HAP = ".hap";
+ static final String HSP = ".hsp";
+ static final String APP = ".app";
+ private static final String TRUE = "true";
+ private static final String FALSE = "false";
+ private static final String EMPTY_STRING = "";
+ private static final Pattern PATTERN = Pattern.compile("[0-9]*");
+
+ private static final Log LOG = new Log(ScanVerify.class.toString());
+
+ /**
+ * if args valid.
+ *
+ * @param utility common data
+ * @return commandVerify if command valid.
+ */
+ public static boolean commandVerify(Utility utility) {
+ if (utility == null) {
+ LOG.error("ScanVerify::commandVerify utility is null.");
+ return false;
+ }
+
+ if (utility.getInput().isEmpty()) {
+ LOG.error("ScanVerify::commandVerify input is null.");
+ return false;
+ }
+
+ if (!(utility.getInput().endsWith(HAP) || utility.getInput().endsWith(HSP)
+ || utility.getInput().endsWith(APP))) {
+ LOG.error("ScanVerify::commandVerify input is invalid!");
+ return false;
+ }
+
+ if (utility.getOutPath().isEmpty()) {
+ LOG.error("ScanVerify::commandVerify outPath is null.");
+ return false;
+ }
+
+ if (!(TRUE.equals(utility.getStatDuplicate()) || FALSE.equals(utility.getStatDuplicate()))) {
+ LOG.error("ScanVerify::commandVerify statDuplicate is invalid! Must be true or false.");
+ return false;
+ }
+
+ if (!utility.getStatFileSize().isEmpty()) {
+ if (!PATTERN.matcher(utility.getStatFileSize()).matches()) {
+ LOG.error("ScanVerify::commandVerify statFileSize is invalid!"
+ + " Must be integer in [0, Integer.MAX]");
+ return false;
+ }
+ if (new BigDecimal(utility.getStatFileSize()).compareTo(BigDecimal.ZERO) < 0
+ || new BigDecimal(utility.getStatFileSize()).compareTo(new BigDecimal(Integer.MAX_VALUE)) > 0) {
+ LOG.error("ScanVerify::commandVerify statFileSize is invalid!"
+ + " Must be integer in [0, Integer.MAX]");
+ return false;
+ }
+ }
+
+ if (!(TRUE.equals(utility.getStatSuffix()) || FALSE.equals(utility.getStatSuffix()))) {
+ LOG.error("ScanVerify::commandVerify statSuffix is invalid! Must be true or false.");
+ return false;
+ }
+
+ if (FALSE.equals(utility.getStatSuffix()) && FALSE.equals(utility.getStatDuplicate())
+ && EMPTY_STRING.equals(utility.getStatFileSize())) {
+ LOG.error("ScanVerify::commandVerify stat parameter is null.");
+ }
+
+
+ return true;
+ }
+}
diff --git a/adapter/ohos/ShowHelp.java b/adapter/ohos/ShowHelp.java
index a0afce8c834bb05c9878305427b3e81ed098d333..5da1a16bd2b7b8848f2b2d7f9a7e0b0d6036844e 100644
--- a/adapter/ohos/ShowHelp.java
+++ b/adapter/ohos/ShowHelp.java
@@ -127,4 +127,38 @@ public interface ShowHelp {
" --unpackapk default false; if true, unpack apk files from hap\n" +
" in the app.");
}
+
+ /**
+ * content of scan command help menu.
+ */
+ static void scanHelp() {
+ log.info(System.lineSeparator() + "STAT DUPLICATE USAGE:" + System.lineSeparator() +
+ "java -jar app_check_tool.jar --input [options] --out-path [option]" + System.lineSeparator() +
+ "--stat-duplicate [option]" + System.lineSeparator() +
+ "OPTIONS:" + System.lineSeparator() +
+ " --input not null must be hap or hsp or app." + System.lineSeparator() +
+ " --out-path not null must be folder." + System.lineSeparator() +
+ " --stat-duplicate not null default false; must be true or false." + System.lineSeparator() +
+ " if true, count duplicate files." + System.lineSeparator() +
+ "----------------------------------------------------------------------------------"
+ + System.lineSeparator() +
+ "STAT FILE SIZE USAGE:" + System.lineSeparator() +
+ "java -jar app_check_tool.jar --input [options] --out-path [option]" + System.lineSeparator() +
+ "--stat-file-size [option]" + System.lineSeparator() +
+ "OPTIONS:" + System.lineSeparator() +
+ " --input not null must be hap or hsp or app." + System.lineSeparator() +
+ " --out-path not null must be folder." + System.lineSeparator() +
+ " --stat-file-size not null must be an number." + System.lineSeparator() +
+ " count files exceeding the specified size." + System.lineSeparator() +
+ "----------------------------------------------------------------------------------"
+ + System.lineSeparator() +
+ "STAT SUFFIX USAGE:" + System.lineSeparator() +
+ "java -jar app_check_tool.jar --input [options] --out-path [option]" + System.lineSeparator() +
+ "--stat-suffix [option]" + System.lineSeparator() +
+ "OPTIONS:" + System.lineSeparator() +
+ " --input not null must be hap or hsp or app." + System.lineSeparator() +
+ " --out-path not null must be folder." + System.lineSeparator() +
+ " --stat-suffix not null default false; must be true or false;" + System.lineSeparator() +
+ " if true, calculate the proportion of various types of files.");
+ }
}
diff --git a/adapter/ohos/Utility.java b/adapter/ohos/Utility.java
index 2f55295e6a2db9584576ee603ef76643d50ab417..dfba31d654d46d9ed5aed2db0253cda258ed1b41 100644
--- a/adapter/ohos/Utility.java
+++ b/adapter/ohos/Utility.java
@@ -124,6 +124,10 @@ public class Utility {
private String hqfList = "";
private String hspList = "";
private String inputList = "";
+ private String input = "";
+ private String statDuplicate = "false";
+ private String statSuffix = "false";
+ private String statFileSize = "";
public void setIsParse(boolean isParse) {
this.isParse = isParse;
@@ -804,4 +808,35 @@ public class Utility {
public void setInputList(String inputList) {
this.inputList = inputList;
}
+
+ public String getInput() {
+ return input;
+ }
+
+ public void setInput(String input) {
+ this.input = getFormattedPath(input);
+ }
+
+ public String getStatDuplicate() {
+ return statDuplicate;
+ }
+
+ public void setStatDuplicate(String statDuplicate) {
+ this.statDuplicate = statDuplicate;
+ }
+
+ public String getStatSuffix() {
+ return statSuffix;
+ }
+
+ public void setStatSuffix(String statSuffix) {
+ this.statSuffix = statSuffix;
+ }
+ public String getStatFileSize() {
+ return statFileSize;
+ }
+
+ public void setStatFileSize(String statFileSize) {
+ this.statFileSize = statFileSize;
+ }
}
diff --git a/adapter/scanner/README_zh.md b/adapter/scanner/README_zh.md
new file mode 100644
index 0000000000000000000000000000000000000000..2f839344e07b7a6a5ba43b43673f856f842c6261
--- /dev/null
+++ b/adapter/scanner/README_zh.md
@@ -0,0 +1,401 @@
+# 扫描工具使用说明
+
+## 简介
+
+app_check_tool用于扫描指定路径的hap、hsp、app包,统计重复文件、统计超出指定大小的文件、统计各类型文件大小占比,输出html结果文件和json结果文件。
+
+### 扫描工具系统架构图
+
+
+
+### 1. 扫描工具使用指令
+
+#### 1.1 示例
+
+- 统计重复文件命令示例:
+
+
+```
+java -jar app_check_tool.jar --input