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()) {
+ // check stat-file-size is number
+ if (!checkNumber(utility.getStatFileSize())) {
+ LOG.error("Scan::scanExcute stat-file-size parameter is invalid.");
+ } else {
+ 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 static Boolean checkNumber(String str) {
+ Pattern pattern = Pattern.compile("[0-9]*");
+ Matcher isNum = pattern.matcher(str);
+ return isNum.matches();
+ }
+
+ 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)) {
+ // copy file and delete file
+ String absolutePath = f.getAbsolutePath();
+ 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 String statDuplicate(Utility utility, List jsonList)
+ throws BundleException, IOException {
+ DuplicateResult duplicateResult = new DuplicateResult();
+ // set start time
+ duplicateResult.setStartTime(getCurrentTime());
+ String currentDir = System.getProperty("user.dir");
+ String targetPath = currentDir + LINUX_FILE_SEPARATOR + DUPLICATE_FOLDER_NAME;
+
+ // scan all files
+ List fileList = getAllInputFileList(utility, targetPath);
+ 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(filePath);
+ 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(filePath);
+ resList.add(model);
+ }
+ }
+ File ParentFile = new File(utility.getOutPath());
+ if (!ParentFile.exists()) {
+ if (!ParentFile.mkdirs()) {
+ LOG.error("Compressor::compressHapAddition create target file parent directory failed.");
+ }
+ }
+ duplicateResult.setResult(resList);
+ String jsonStr = JSON.toJSONString(duplicateResult, new SerializerFeature[]{
+ SerializerFeature.PrettyFormat, SerializerFeature.WriteMapNullValue,
+ SerializerFeature.WriteDateUseDateFormat});
+ // set stop time
+ 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);
+ 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;
+
+ // scan all files
+ List fileList = getAllInputFileList(utility, targetPath);
+ HashMap> hashMap = new HashMap<>();
+ for (String filePath: fileList) {
+ hashMap = accountFileType(hashMap,filePath);
+ }
+ Iterator iterator = hashMap.keySet().iterator();
+ List resulList = new ArrayList<>();
+ String outPath = currentDir + LINUX_FILE_SEPARATOR + TMP_FOLDER_NAME;
+ unpackHap(utility.getInput(), outPath);
+ List pathList = new ArrayList<>();
+ ArrayList soList = new ArrayList<>();
+ FileUtils.getFileList(outPath, soList);
+ for (String file: soList) {
+ if(file.contains(HAP)||file.contains(HSP)){
+ pathList.add(file);
+ }
+ }
+ suffixResult.setPathList(pathList);
+
+ while (iterator.hasNext()){
+ String next = iterator.next();
+ ParamModelSuffix paramModelSuffix = new ParamModelSuffix();
+ paramModelSuffix.setSuffix(next);
+ if(next.equalsIgnoreCase(FILE_TYPE_SO)){
+ List paramModelSuffixSos = new ArrayList<>();
+ List paramModelSuffixSons = hashMap.get(next);
+ long sum = ZERO;
+ for(ParamModelSuffixSon param:paramModelSuffixSons){
+ ParamModelSuffixSo paramModelSuffixSo = new ParamModelSuffixSo();
+ paramModelSuffixSo.setSize(param.getSize());
+ String soFilePath = param.getFile();
+ paramModelSuffixSo.setFile(soFilePath);
+ int i = soFilePath.indexOf(LINUX_REVERSE_SEPARATOR + LIBS_NAME);
+ String hapPath = soFilePath.substring(NUM_ZERO,i);
+ File hapFile = new File(hapPath);
+ long oldSize = hapFile.length();
+ long newSize = ZERO;
+ for (String file: soList) {
+ File tmp = new File(file);
+ if(tmp.getName().equals(hapFile.getName())){
+ oldSize = tmp.length();
+ }
+ }
+ for(ParamModelSuffixSon so:paramModelSuffixSons){
+ if(so.getFile().contains(hapFile.getPath())){
+ File tmp = new File(so.getFile());
+ newSize+=tmp.length();
+ }
+ }
+ paramModelSuffixSo.setCompress(oldSize < newSize?TRUE:FALSE);
+ paramModelSuffixSos.add(paramModelSuffixSo);
+ sum+=param.getSize();
+ }
+ deleteFile(outPath);
+ paramModelSuffix.setTotalSize(sum);
+ paramModelSuffixSos = paramModelSuffixSos.stream().sorted(Comparator.comparing(
+ ParamModelSuffixSon::getSize,Comparator.reverseOrder())).collect(Collectors.toList());
+ paramModelSuffix.setFiles(paramModelSuffixSos);
+ }else{
+ List paramModelSuffixSons = hashMap.get(next);
+ paramModelSuffixSons = paramModelSuffixSons.stream().sorted(Comparator.comparing(
+ ParamModelSuffixSon::getSize,Comparator.reverseOrder())).collect(Collectors.toList());
+ paramModelSuffix.setFiles(paramModelSuffixSons);
+ long sum = paramModelSuffixSons.stream().mapToLong(ParamModelSuffixSon::getSize).sum();
+ paramModelSuffix.setTotalSize(sum);
+ }
+ resulList.add(paramModelSuffix);
+ }
+ resulList = resulList.stream().sorted(Comparator.comparing(
+ ParamModelSuffix::getTotalSize,Comparator.reverseOrder()))
+ .collect(Collectors.toList());//sorted by totalSize
+ suffixResult.setResult(resulList);
+ File ParentFile = new File(utility.getOutPath());
+ if (!ParentFile.exists()) {
+ if (!ParentFile.mkdirs()) {
+ LOG.error("Compressor::compressHapAddition create target file parent directory failed.");
+ }
+ }
+ suffixResult.setStopTime(getCurrentTime());
+ String jsonStr = JSON.toJSONString(suffixResult, new SerializerFeature[]{
+ SerializerFeature.PrettyFormat, SerializerFeature.WriteMapNullValue,
+ SerializerFeature.WriteDateUseDateFormat});
+ 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 pathHtml = EMPTY_STRING;
+ if(suffixResult.getPathList() != null && !suffixResult.getPathList().isEmpty()){
+ pathHtml = getPathListHtml(suffixResult.getPathList());
+ }
+ String pathListHtml = EMPTY_STRING;
+ if(!pathHtml.isBlank()){
+ pathListHtml = getHtmlRow(PATH_LIST, pathHtml);
+ }
+ String resultValue = getResultHtmlOfSuffix(suffixResult.getResult());
+ String resultHtml = getHtmlRow(RESULT, resultValue);
+ String htmlStr = "" + taskTypeHtml + taskDescHtml + paramHtml +
+ startTimeHtml + stopTimeHtml + pathListHtml + resultHtml + "
";
+ deleteFile(targetPath);
+ jsonList.add(jsonStr);
+ return htmlStr;
+ }
+
+ private String statFileSize(Utility utility, List jsonList) throws BundleException, IOException {
+ FileSizeResult fileSizeResult = new FileSizeResult();
+ // set start time
+ fileSizeResult.setStartTime(getCurrentTime());
+ String currentDir = System.getProperty("user.dir");
+ String targetPath = currentDir + LINUX_FILE_SEPARATOR + FILE_SIZE_FOLDER_NAME;
+
+ // scan all files
+ 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(filePath);
+ model.setSize(size);
+ resList.add(model);
+ }
+ }
+ // order by size from large to small
+ resList.sort(Comparator.comparing(ParamModelFileSize::getSize).reversed());
+ fileSizeResult.setResult(resList);
+ // set param input size
+ fileSizeResult.setParam(String.format(fileSizeResult.getParam(), utility.getStatFileSize()));
+ // set stop time
+ fileSizeResult.setStopTime(getCurrentTime());
+ File ParentFile = new File(utility.getOutPath());
+ if (!ParentFile.exists()) {
+ if (!ParentFile.mkdirs()) {
+ LOG.error("Compressor::compressHapAddition create target file parent directory failed.");
+ }
+ }
+ // output json result
+ String jsonStr = JSON.toJSONString(fileSizeResult, new SerializerFeature[]{
+ SerializerFeature.PrettyFormat, SerializerFeature.WriteMapNullValue,
+ SerializerFeature.WriteDateUseDateFormat});
+ // output html result
+ 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 = getHtmlRow(RESULT, resultValue);
+ String htmlStr = "" + taskTypeHtml + taskDescHtml + paramHtml +
+ startTimeHtml + stopTimeHtml + resultHtml + "
";
+ deleteFile(targetPath);
+ jsonList.add(jsonStr);
+ return htmlStr;
+ }
+
+ private static HashMap> accountFileType(HashMap> hashMap,String f) {
+ File file = new File(f);
+ String[] split = file.getName().split("\\.");
+ if (split.length == 2) {
+ 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_UNKOWN)) {
+ putValueIntoHashmap(hashMap,file,SUFFIX_TYPE_UNKOWN);
+ }else {
+ putValueIntoHashmapnew(hashMap,file,SUFFIX_TYPE_UNKOWN);
+ }
+ }
+ return hashMap;
+ }
+
+ private static void putValueIntoHashmap(HashMap> hashMap,File file,String key){
+ ParamModelSuffixSon paramModel2 = setModelValue(file);
+ List paramModel2s = hashMap.get(key);
+ paramModel2s.add(paramModel2);
+ hashMap.put(key, paramModel2s);
+ }
+
+ private static void putValueIntoHashmapnew(HashMap> hashMap,File file,String key){
+ ParamModelSuffixSon paramModel2 = setModelValue(file);
+ List fileNew = new ArrayList<>();
+ fileNew.add(paramModel2);
+ hashMap.put(key, fileNew);
+ }
+
+ private static ParamModelSuffixSon setModelValue(File file){
+ ParamModelSuffixSon paramModel2 = new ParamModelSuffixSon();
+ paramModel2.setFile(file.getPath());
+ long size = FileUtils.getFileSize(file.getPath());
+ paramModel2.setSize(size);
+ return paramModel2;
+ }
+
+ 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 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 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 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(ParamModelSuffixSon so:files){
+ resValve.insert(0, RESULT_FILE + ":" + so.getFile() + "
");
+ resValve.insert(0, RESULT_SIZE + ":" + so.getSize() + "
");
+ }
+ return "" + key + " | " + resValve + " |
";
+ }
+ private static String getHtmlRowSonSo(String key, List files) {
+ StringBuilder resValve = new StringBuilder(EMPTY_STRING);
+ for(ParamModelSuffixSo 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)) != -1) {
+ 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) {
+ String md5 = "";
+ try {
+ InputStream fis = new FileInputStream(filePath);
+ MessageDigest md = MessageDigest.getInstance(MD5);
+ byte[] buffer = new byte[MD5_BUFFER_SIZE];
+ int length = -1;
+ while ((length = fis.read(buffer, 0, MD5_BUFFER_SIZE)) != -1) {
+ md.update(buffer, 0, length);
+ }
+ fis.close();
+ byte[] md5Bytes = md.digest();
+ BigInteger bigInt = new BigInteger(1, md5Bytes);
+ md5 = bigInt.toString(16);
+ } catch (Exception exception) {
+ LOG.error("Scan::md5HashCode exception" + exception);
+ }
+ return md5;
+ }
+
+ /**
+ * delete file
+ *
+ * @param path file path which will be deleted
+ */
+ 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..5d71b6949a6a4d1069f3703f5400b7b840d5cf85
--- /dev/null
+++ b/adapter/ohos/ScanEntrance.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2021 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;
+
+/**
+ * bundle scan.
+ * step1: parse arguments
+ * step2: verity arguments
+ * step3: uncompress arguments
+ *
+ */
+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..2503884b109d96cef1b44e2c258bba9c7d3438a3
--- /dev/null
+++ b/adapter/ohos/ScanVerify.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2021 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;
+
+/**
+ * scan comment,command parser.
+ *
+ */
+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 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 (!(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 5c31cd7b93cd2701d807e4fcb7fc9f3f4620e926..8b88d3b188754d89d8f971dfd614ddc858cc9c41 100644
--- a/adapter/ohos/ShowHelp.java
+++ b/adapter/ohos/ShowHelp.java
@@ -127,4 +127,36 @@ 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("\nSTAT DUPLICATE USAGE:\n" +
+ "java -jar hmos_app_check_tool.jar --input [options] --out-path [option]\n" +
+ "--stat-duplicate [option]\n" +
+ "OPTIONS:\n" +
+ " --input not null must be hap or hsp or app.\n" +
+ " --out-path not null must be folder.\n" +
+ " --stat-duplicate not null default false; must be true or false.\n" +
+ " if true, count duplicate files.\n" +
+ "----------------------------------------------------------------------------------\n" +
+ "STAT FILE SIZE USAGE:\n" +
+ "java -jar hmos_app_check_tool.jar --input [options] --out-path [option]\n" +
+ "--stat-file-size [option]\n" +
+ "OPTIONS:\n" +
+ " --input not null must be hap or hsp or app.\n" +
+ " --out-path not null must be folder.\n" +
+ " --stat-file-size not null must be an number.\n" +
+ " count files exceeding the specified size.\n" +
+ "----------------------------------------------------------------------------------\n" +
+ "STAT SUFFIX USAGE:\n" +
+ "java -jar hmos_app_check_tool.jar --input [options] --out-path [option]\n" +
+ "--stat-suffix [option]\n" +
+ "OPTIONS:\n" +
+ " --input not null must be hap or hsp or app.\n" +
+ " --out-path not null must be folder.\n" +
+ " --stat-suffix not null default false; must be true or false;\n" +
+ " if true, calculate the proportion of various types of files.");
+ }
}
diff --git a/adapter/ohos/Utility.java b/adapter/ohos/Utility.java
index 40e8713c319234809656e71f436300b9464ececa..4ce2667bb03b1c0032ce707584503581a27131c5 100644
--- a/adapter/ohos/Utility.java
+++ b/adapter/ohos/Utility.java
@@ -122,6 +122,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;
@@ -791,4 +795,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/build.py b/build.py
index 5a776bc8af26929e289873f8f188eb2760910c4c..d56ba64c01c329d3c8c179546907db6efc326b91 100755
--- a/build.py
+++ b/build.py
@@ -30,6 +30,7 @@ def main():
parser.add_argument('--haptobinOutput', required=True)
parser.add_argument('--unpackOutput', required=True)
parser.add_argument('--packOutput', required=True)
+ parser.add_argument('--checkOutput', required=True)
parser.add_argument('--outpath', required=True)
parser.add_argument('--toolchain', required=True)
parser.add_argument('--compileTarget', required=True)
@@ -37,6 +38,7 @@ def main():
print(args.haptobinOutput)
print(args.unpackOutput)
print(args.packOutput)
+ print(args.checkOutput)
print(args.outpath)
print(args.compileTarget)
root_dir = os.path.dirname(os.path.realpath(__file__))
@@ -85,6 +87,16 @@ def main():
print(pack_out.decode('utf-8'))
print(pack_err.decode('utf-8'))
raise Exception("compile packing tool java class failed!")
+
+ #compile app_check_tool.jar
+ check_tool_shell_path = os.path.join(root_dir, "checkTool.sh")
+ command_check = ['bash', check_tool_shell_path, root_dir, args.checkOutput, args.outpath, toolchain]
+ child_check = subprocess.Popen(command_check, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ check_out, check_err = child_check.communicate(timeout=time_out)
+ if child_check.returncode != 0:
+ print(check_out.decode('utf-8'))
+ print(check_err.decode('utf-8'))
+ raise Exception("compile check tool java class failed!")
if __name__ == '__main__':
sys.exit(main())
diff --git a/checkTool.sh b/checkTool.sh
new file mode 100644
index 0000000000000000000000000000000000000000..e06f1b561981cd1bcaf80319702a2a9723613950
--- /dev/null
+++ b/checkTool.sh
@@ -0,0 +1,113 @@
+#!/usr/bin/env bash
+# Copyright (c) 2022 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.
+set -e
+root_path=$1
+pack_build_out_jar_path=$2
+pack_build_out_path=$3
+toolchain=$4
+final_path=$(pwd)
+
+jar_dir="jar"
+pack_jar_file="app_check_tool.jar"
+fastjson_jar_file="fastjson-1.2.83.jar"
+jar_directory="${root_path}/jar"
+pack_jar_path="${root_path}/${jar_dir}/${pack_jar_file}"
+manifest_path="${root_path}/META-INF/check_tool/MANIFEST.MF"
+
+out_dir="${root_path}/out/${toolchain}/check_tool"
+if [ -d "${out_dir}/ohos" ]
+ then
+ echo "${out_dir}/ohos exist"
+ else
+ mkdir -p "${out_dir}/ohos"
+fi
+
+jar_path="${root_path}/jar"
+fastjson_jar_path="${root_path}/jar/fastjson-1.2.83.jar"
+java_suffix=".java"
+java_collection=""
+declare -a compile_class=(
+ "BundleException"
+ "CommandParser"
+ "ScanEntrance"
+ "Scan"
+ "ScanVerify"
+ "Log"
+ "PackFormatter"
+ "ShowHelp"
+ "Utility"
+ "FileUtils"
+ )
+compile_class_length=${#compile_class[@]}
+for ((i=0; i<${compile_class_length};++i))
+do
+ java_collection="${java_collection} ${root_path}/adapter/ohos/${compile_class[$i]}${java_suffix}"
+done
+compile_command="javac -source 1.8 -target 1.8 -cp ${fastjson_jar_path} -d ${out_dir} ${java_collection}"
+eval ${compile_command}
+
+temp_dir="$root_path/jar/temp_${toolchain}"
+if [ -d "${temp_dir}" ]
+ then
+ echo "${temp_dir} exit"
+ else
+ mkdir ${temp_dir}
+fi
+
+cd ${out_dir}
+product_pack_jar_command="jar -cvfm ${temp_dir}/${pack_jar_file} ${manifest_path} ./ohos"
+eval ${product_pack_jar_command}
+
+# merge app_packing_tool.jar and fastjson
+cp ${fastjson_jar_path} "${temp_dir}/${fastjson_jar_file}"
+detach_pack_jar_command="jar -xvf ${pack_jar_file}"
+detach_fastjson_jar_command="jar -xvf ${fastjson_jar_file}"
+cd ${temp_dir}
+eval ${detach_pack_jar_command}
+eval ${detach_fastjson_jar_command}
+rm ${pack_jar_file}
+rm ${fastjson_jar_file}
+
+cd ${jar_directory}
+temp_pack_jar_dir="${root_path}/jar/packtool_${toolchain}"
+temp_pack_jar_path="${root_path}/jar/packtool_${toolchain}/${pack_jar_file}"
+merge_pack_fast_jar_command="jar -cvfm ${temp_pack_jar_path} ${manifest_path} -C ${temp_dir} ."
+if [ -d "${temp_pack_jar_dir}" ]
+ then
+ echo "${temp_pack_jar_dir} exist"
+ else
+ mkdir -p ${temp_pack_jar_dir}
+fi
+eval ${merge_pack_fast_jar_command}
+
+# make out dir
+final_pack_out_path="${final_path}/${pack_build_out_path}"
+final_pack_jar_path="${final_path}/${pack_build_out_jar_path}"
+if [ -d "$final_pack_out_path" ]
+ then
+ echo "${final_pack_out_path} exist"
+ else
+ mkdir -p ${final_pack_out_path}
+fi
+copy_command="cp ${temp_pack_jar_path} ${final_pack_jar_path}"
+eval ${copy_command}
+if [ -f "${pack_jar_file}"]
+ then
+ echo "${pack_jar_file} exist"
+ else
+ cp ${temp_pack_jar_path} ${pack_jar_file}
+fi
+rm -rf ${temp_pack_jar_dir}
+rm -rf ${temp_dir}
+rm -rf "${root_path}/out"
diff --git a/packingtool.gni b/packingtool.gni
index 9a9b38d301fa64cc46c0c646e0e60de36e33ed70..bd21b05e6803efea23c26f786bbd2ca25a252328 100755
--- a/packingtool.gni
+++ b/packingtool.gni
@@ -33,6 +33,8 @@ template("packing_tool") {
rebase_path(outputs[2], root_build_dir),
"--outpath",
rebase_path(outputs[3], root_build_dir),
+ "--checkOutput",
+ rebase_path(outputs[4], root_build_dir),
"--toolchain",
current_toolchain,
]