1b8a72a62Sopenharmony_ci/*
2b8a72a62Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
3b8a72a62Sopenharmony_ci *
4b8a72a62Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
5b8a72a62Sopenharmony_ci * you may not use this file except in compliance with the License.
6b8a72a62Sopenharmony_ci * You may obtain a copy of the License at
7b8a72a62Sopenharmony_ci *
8b8a72a62Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
9b8a72a62Sopenharmony_ci *
10b8a72a62Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
11b8a72a62Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
12b8a72a62Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b8a72a62Sopenharmony_ci * See the License for the specific language governing permissions and
14b8a72a62Sopenharmony_ci * limitations under the License.
15b8a72a62Sopenharmony_ci */
16b8a72a62Sopenharmony_ci
17b8a72a62Sopenharmony_cipackage ohos;
18b8a72a62Sopenharmony_ci
19b8a72a62Sopenharmony_ciimport com.alibaba.fastjson.JSON;
20b8a72a62Sopenharmony_ciimport com.alibaba.fastjson.serializer.SerializerFeature;
21b8a72a62Sopenharmony_ci
22b8a72a62Sopenharmony_ciimport java.io.File;
23b8a72a62Sopenharmony_ciimport java.io.FileInputStream;
24b8a72a62Sopenharmony_ciimport java.io.IOException;
25b8a72a62Sopenharmony_ciimport java.io.InputStream;
26b8a72a62Sopenharmony_ciimport java.math.BigInteger;
27b8a72a62Sopenharmony_ciimport java.security.MessageDigest;
28b8a72a62Sopenharmony_ciimport java.security.NoSuchAlgorithmException;
29b8a72a62Sopenharmony_ciimport java.text.SimpleDateFormat;
30b8a72a62Sopenharmony_ciimport java.util.ArrayList;
31b8a72a62Sopenharmony_ciimport java.util.List;
32b8a72a62Sopenharmony_ci
33b8a72a62Sopenharmony_ci/**
34b8a72a62Sopenharmony_ci * scanDuplicate info
35b8a72a62Sopenharmony_ci *
36b8a72a62Sopenharmony_ci * @since 2023/11/27
37b8a72a62Sopenharmony_ci */
38b8a72a62Sopenharmony_ci
39b8a72a62Sopenharmony_cipublic class ScanStatDuplicate {
40b8a72a62Sopenharmony_ci    private static final String UNPACK_NAME = "unpack";
41b8a72a62Sopenharmony_ci    private static final String DUPLICATE_FOLDER_NAME = "duplicate";
42b8a72a62Sopenharmony_ci    private static final String EMPTY_STRING = "";
43b8a72a62Sopenharmony_ci    private static final String SHA_256 = "SHA-256";
44b8a72a62Sopenharmony_ci    private static final String RESULT_MD5 = "md5";
45b8a72a62Sopenharmony_ci    private static final String RESULT_SIZE = "size";
46b8a72a62Sopenharmony_ci    private static final String RESULT_FILES = "files";
47b8a72a62Sopenharmony_ci    private static final String DUPLICATE_DESC = "find the duplicated files";
48b8a72a62Sopenharmony_ci    private static final String DUPLICATE_PARAM = "--stat-duplicate";
49b8a72a62Sopenharmony_ci    private static final String TASK_TYPE = "taskType";
50b8a72a62Sopenharmony_ci    private static final String TASK_DESC = "taskDesc";
51b8a72a62Sopenharmony_ci    private static final String PARAM = "param";
52b8a72a62Sopenharmony_ci    private static final String START_TIME = "startTime";
53b8a72a62Sopenharmony_ci    private static final String STOP_TIME = "stopTime";
54b8a72a62Sopenharmony_ci    private static final String RESULT = "result";
55b8a72a62Sopenharmony_ci    private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss:SSS";
56b8a72a62Sopenharmony_ci    private static final int MD5_BUFFER_SIZE = 1024;
57b8a72a62Sopenharmony_ci    private static final long DUPLICATE_TYPE = 1L;
58b8a72a62Sopenharmony_ci    private static final int MD5_LENGTH = 16;
59b8a72a62Sopenharmony_ci    private static final long SHOW_SIZE = 10L;
60b8a72a62Sopenharmony_ci    private static final String HTML_BUTTON_SHOW = "<button id=\"show_%s\" type=\"button\" "
61b8a72a62Sopenharmony_ci            + "onclick=\"show_%s()\" style=\"display: block\">more</button>";
62b8a72a62Sopenharmony_ci    private static final String HTML_BUTTON_HIDE = "<button id=\"hide_%s\" type=\"button\" "
63b8a72a62Sopenharmony_ci            + "onclick=\"hide_%s()\" style=\"display: none\">close</button>";
64b8a72a62Sopenharmony_ci    private static final String HTML_TABLE_BOX = "<table class=\"boxTable\">";
65b8a72a62Sopenharmony_ci    private static final String HTML_TABLE_END = "</table>";
66b8a72a62Sopenharmony_ci    private static final String HTML_TR_TD_LAYOUT = "<tr class=\"layout\"><td class=\"key\">";
67b8a72a62Sopenharmony_ci    private static final String HTML_TR_TD_VALUE = "</td><td class=\"value\">";
68b8a72a62Sopenharmony_ci    private static final String HTML_TR_TD_END = "</td></tr>";
69b8a72a62Sopenharmony_ci    private static final String HTML_TR_TD_RESULT = "<tr class=\"result\"><td class=\"key\">";
70b8a72a62Sopenharmony_ci    private static final String HTML_TR_TD = "<tr%s><td%s>";
71b8a72a62Sopenharmony_ci    private static final String HTML_TD_END_TD = "</td><td%s>";
72b8a72a62Sopenharmony_ci    private static final String HTML_LI_CIRCLE = "<li type=\"circle\">";
73b8a72a62Sopenharmony_ci    private static final String HTML_LI_END = "</li>";
74b8a72a62Sopenharmony_ci    private static final String HTML_TR_TD_DUPLICATE_KEY = "<tr class=\"duplicateLayout\"><td class=\"duplicateKey\">";
75b8a72a62Sopenharmony_ci    private static final String HTML_TD_DUPLICATE_VALUE = "</td><td class=\"duplicateValue\"><ul>";
76b8a72a62Sopenharmony_ci    private static final String HTML_UL_TD_TR_END = "</ul></td></tr>";
77b8a72a62Sopenharmony_ci    private static final String HTML_UL_HEAD = "<ul>";
78b8a72a62Sopenharmony_ci    private static final String CLASS_DUPLICATE_LAYOUT = " class=\"duplicateLayout\"";
79b8a72a62Sopenharmony_ci    private static final String CLASS_DUPLICATE_KEY = " class=\"duplicateKey\"";
80b8a72a62Sopenharmony_ci    private static final String CLASS_DUPLICATE_VALUE = " class=\"duplicateValue\"";
81b8a72a62Sopenharmony_ci    private static final String HTML_LI_HEAD = "<li>";
82b8a72a62Sopenharmony_ci    private static final String HTML_LI_DUPLICATE = "<li class=\"duplicate\">";
83b8a72a62Sopenharmony_ci    private static final String HTML_TABLE_DUPLICATE = "<table class=\"duplicateTable\">";
84b8a72a62Sopenharmony_ci    private static final String HTML_TABLE_LI_END = "</table></li>";
85b8a72a62Sopenharmony_ci    private static final String HTML_UL_END = "</ul>";
86b8a72a62Sopenharmony_ci    private static final Log LOG = new Log(ScanStatDuplicate.class.toString());
87b8a72a62Sopenharmony_ci
88b8a72a62Sopenharmony_ci    private static class ParamModel {
89b8a72a62Sopenharmony_ci        private String md5 = EMPTY_STRING;
90b8a72a62Sopenharmony_ci        private long size;
91b8a72a62Sopenharmony_ci        private List<String> files = new ArrayList<>();
92b8a72a62Sopenharmony_ci
93b8a72a62Sopenharmony_ci        public String getMd5() {
94b8a72a62Sopenharmony_ci            return this.md5;
95b8a72a62Sopenharmony_ci        }
96b8a72a62Sopenharmony_ci        public void setMd5(String md5) {
97b8a72a62Sopenharmony_ci            this.md5 = md5;
98b8a72a62Sopenharmony_ci        }
99b8a72a62Sopenharmony_ci        public long getSize() {
100b8a72a62Sopenharmony_ci            return this.size;
101b8a72a62Sopenharmony_ci        }
102b8a72a62Sopenharmony_ci        public void setSize(long size) {
103b8a72a62Sopenharmony_ci            this.size = size;
104b8a72a62Sopenharmony_ci        }
105b8a72a62Sopenharmony_ci        public List<String> getFiles() {
106b8a72a62Sopenharmony_ci            return this.files;
107b8a72a62Sopenharmony_ci        }
108b8a72a62Sopenharmony_ci        public void setFiles(List<String> files) {
109b8a72a62Sopenharmony_ci            this.files = files;
110b8a72a62Sopenharmony_ci        }
111b8a72a62Sopenharmony_ci    }
112b8a72a62Sopenharmony_ci
113b8a72a62Sopenharmony_ci    private static class DuplicateResult {
114b8a72a62Sopenharmony_ci        private long taskType = DUPLICATE_TYPE;
115b8a72a62Sopenharmony_ci        private String taskDesc = DUPLICATE_DESC;
116b8a72a62Sopenharmony_ci        private String param = DUPLICATE_PARAM;
117b8a72a62Sopenharmony_ci        private String startTime = EMPTY_STRING;
118b8a72a62Sopenharmony_ci        private String stopTime = EMPTY_STRING;
119b8a72a62Sopenharmony_ci        private List<ParamModel> result = new ArrayList<>();
120b8a72a62Sopenharmony_ci
121b8a72a62Sopenharmony_ci        public long getTaskType() {
122b8a72a62Sopenharmony_ci            return this.taskType;
123b8a72a62Sopenharmony_ci        }
124b8a72a62Sopenharmony_ci        public void setTaskType(long taskType) {
125b8a72a62Sopenharmony_ci            this.taskType = taskType;
126b8a72a62Sopenharmony_ci        }
127b8a72a62Sopenharmony_ci        public String getTaskDesc() {
128b8a72a62Sopenharmony_ci            return this.taskDesc;
129b8a72a62Sopenharmony_ci        }
130b8a72a62Sopenharmony_ci        public void setTaskDesc(String taskDesc) {
131b8a72a62Sopenharmony_ci            this.taskDesc = taskDesc;
132b8a72a62Sopenharmony_ci        }
133b8a72a62Sopenharmony_ci        public String getParam() {
134b8a72a62Sopenharmony_ci            return this.param;
135b8a72a62Sopenharmony_ci        }
136b8a72a62Sopenharmony_ci        public void setParam(String param) {
137b8a72a62Sopenharmony_ci            this.param = param;
138b8a72a62Sopenharmony_ci        }
139b8a72a62Sopenharmony_ci        public String getStartTime() {
140b8a72a62Sopenharmony_ci            return this.startTime;
141b8a72a62Sopenharmony_ci        }
142b8a72a62Sopenharmony_ci        public void setStartTime(String startTime) {
143b8a72a62Sopenharmony_ci            this.startTime = startTime;
144b8a72a62Sopenharmony_ci        }
145b8a72a62Sopenharmony_ci        public String getStopTime() {
146b8a72a62Sopenharmony_ci            return this.stopTime;
147b8a72a62Sopenharmony_ci        }
148b8a72a62Sopenharmony_ci        public void setStopTime(String stopTime) {
149b8a72a62Sopenharmony_ci            this.stopTime = stopTime;
150b8a72a62Sopenharmony_ci        }
151b8a72a62Sopenharmony_ci        public List<ParamModel> getResult() {
152b8a72a62Sopenharmony_ci            return this.result;
153b8a72a62Sopenharmony_ci        }
154b8a72a62Sopenharmony_ci        public void setResult(List<ParamModel> result) {
155b8a72a62Sopenharmony_ci            this.result = result;
156b8a72a62Sopenharmony_ci        }
157b8a72a62Sopenharmony_ci    }
158b8a72a62Sopenharmony_ci
159b8a72a62Sopenharmony_ci    /**
160b8a72a62Sopenharmony_ci     * scan statDuplicate.
161b8a72a62Sopenharmony_ci     *
162b8a72a62Sopenharmony_ci     * @param utility utility data
163b8a72a62Sopenharmony_ci     * @param jsonList List<String> data
164b8a72a62Sopenharmony_ci     * @param fileList List<String> data
165b8a72a62Sopenharmony_ci     * @return duplicate html
166b8a72a62Sopenharmony_ci     * @throws IOException Throws this exception if getDuplicateResList exception
167b8a72a62Sopenharmony_ci     * @throws NoSuchAlgorithmException Throws this exception if getDuplicateResList exception
168b8a72a62Sopenharmony_ci     */
169b8a72a62Sopenharmony_ci    public String statDuplicate(Utility utility, List<String> jsonList, List<String> fileList)
170b8a72a62Sopenharmony_ci            throws IOException, NoSuchAlgorithmException {
171b8a72a62Sopenharmony_ci        DuplicateResult duplicateResult = new DuplicateResult();
172b8a72a62Sopenharmony_ci        duplicateResult.setStartTime(getCurrentTime());
173b8a72a62Sopenharmony_ci        List<ParamModel> resList = getDuplicateResList(fileList);
174b8a72a62Sopenharmony_ci        File parentFile = new File(utility.getOutPath());
175b8a72a62Sopenharmony_ci        if (!parentFile.exists() && !parentFile.mkdirs()) {
176b8a72a62Sopenharmony_ci            LOG.error(ScanErrorEnum.STAT_DUPLICATE_CREATE_FILE_ERROR.toString());
177b8a72a62Sopenharmony_ci        }
178b8a72a62Sopenharmony_ci        List<ParamModel> filterList = new ArrayList<>();
179b8a72a62Sopenharmony_ci        for (ParamModel model : resList) {
180b8a72a62Sopenharmony_ci            List<String> files = model.getFiles();
181b8a72a62Sopenharmony_ci            if (files.size() > 1) {
182b8a72a62Sopenharmony_ci                filterList.add(model);
183b8a72a62Sopenharmony_ci            }
184b8a72a62Sopenharmony_ci        }
185b8a72a62Sopenharmony_ci        duplicateResult.setResult(filterList);
186b8a72a62Sopenharmony_ci        duplicateResult.setStopTime(getCurrentTime());
187b8a72a62Sopenharmony_ci        String taskTypeHtml = getHtmlRow(TASK_TYPE, duplicateResult.getTaskType());
188b8a72a62Sopenharmony_ci        String taskDescHtml = getHtmlRow(TASK_DESC, duplicateResult.getTaskDesc());
189b8a72a62Sopenharmony_ci        String paramHtml = getHtmlRow(PARAM, duplicateResult.getParam());
190b8a72a62Sopenharmony_ci        String startTimeHtml = getHtmlRow(START_TIME, duplicateResult.getStartTime());
191b8a72a62Sopenharmony_ci        String stopTimeHtml = getHtmlRow(STOP_TIME, duplicateResult.getStopTime());
192b8a72a62Sopenharmony_ci        String resultValue = getResultHtml(duplicateResult.getResult());
193b8a72a62Sopenharmony_ci        String resultHtml = getHtmlRowResultClass(RESULT, resultValue);
194b8a72a62Sopenharmony_ci        String htmlStr = HTML_TABLE_BOX + taskTypeHtml + taskDescHtml + paramHtml
195b8a72a62Sopenharmony_ci                + startTimeHtml + stopTimeHtml + resultHtml + HTML_TABLE_END;
196b8a72a62Sopenharmony_ci        String jsonStr = JSON.toJSONString(duplicateResult, new SerializerFeature[] {
197b8a72a62Sopenharmony_ci                SerializerFeature.PrettyFormat, SerializerFeature.WriteMapNullValue,
198b8a72a62Sopenharmony_ci                SerializerFeature.WriteDateUseDateFormat});
199b8a72a62Sopenharmony_ci        jsonList.add(jsonStr);
200b8a72a62Sopenharmony_ci        return htmlStr;
201b8a72a62Sopenharmony_ci    }
202b8a72a62Sopenharmony_ci
203b8a72a62Sopenharmony_ci    private static String getCurrentTime() {
204b8a72a62Sopenharmony_ci        long currentTimeMillis = System.currentTimeMillis();
205b8a72a62Sopenharmony_ci        return new SimpleDateFormat(DATE_FORMAT).format(currentTimeMillis);
206b8a72a62Sopenharmony_ci    }
207b8a72a62Sopenharmony_ci
208b8a72a62Sopenharmony_ci    private List<ParamModel> getDuplicateResList(List<String> fileList) throws IOException, NoSuchAlgorithmException {
209b8a72a62Sopenharmony_ci        List<ParamModel> resList = new ArrayList<>();
210b8a72a62Sopenharmony_ci        for (String filePath : fileList) {
211b8a72a62Sopenharmony_ci            boolean addFlag = true;
212b8a72a62Sopenharmony_ci            String md5 = md5HashCode(filePath);
213b8a72a62Sopenharmony_ci            for (ParamModel element : resList) {
214b8a72a62Sopenharmony_ci                String eleMd5 = element.getMd5();
215b8a72a62Sopenharmony_ci                if (eleMd5.equals(md5)) {
216b8a72a62Sopenharmony_ci                    List<String> eleFiles = element.getFiles();
217b8a72a62Sopenharmony_ci                    eleFiles.add(splitPath(filePath, UNPACK_NAME));
218b8a72a62Sopenharmony_ci                    element.setFiles(eleFiles);
219b8a72a62Sopenharmony_ci                    addFlag = false;
220b8a72a62Sopenharmony_ci                }
221b8a72a62Sopenharmony_ci            }
222b8a72a62Sopenharmony_ci            if (addFlag) {
223b8a72a62Sopenharmony_ci                ParamModel model = new ParamModel();
224b8a72a62Sopenharmony_ci                long size = FileUtils.getFileSize(filePath);
225b8a72a62Sopenharmony_ci                model.setMd5(md5);
226b8a72a62Sopenharmony_ci                model.setSize(size);
227b8a72a62Sopenharmony_ci                List<String> files = model.getFiles();
228b8a72a62Sopenharmony_ci                files.add(splitPath(filePath, UNPACK_NAME));
229b8a72a62Sopenharmony_ci                resList.add(model);
230b8a72a62Sopenharmony_ci            }
231b8a72a62Sopenharmony_ci        }
232b8a72a62Sopenharmony_ci        return resList;
233b8a72a62Sopenharmony_ci    }
234b8a72a62Sopenharmony_ci
235b8a72a62Sopenharmony_ci    private static String getHtmlRow(String key, long valve) {
236b8a72a62Sopenharmony_ci        return HTML_TR_TD_LAYOUT + key + HTML_TR_TD_VALUE + valve + HTML_TR_TD_END;
237b8a72a62Sopenharmony_ci    }
238b8a72a62Sopenharmony_ci
239b8a72a62Sopenharmony_ci    private static String getHtmlRow(String key, String valve) {
240b8a72a62Sopenharmony_ci        return HTML_TR_TD_LAYOUT + key + HTML_TR_TD_VALUE + valve + HTML_TR_TD_END;
241b8a72a62Sopenharmony_ci    }
242b8a72a62Sopenharmony_ci
243b8a72a62Sopenharmony_ci    private static String getHtmlRowResultClass(String key, String valve) {
244b8a72a62Sopenharmony_ci        return HTML_TR_TD_RESULT + key + HTML_TR_TD_VALUE + valve + HTML_TR_TD_END;
245b8a72a62Sopenharmony_ci    }
246b8a72a62Sopenharmony_ci
247b8a72a62Sopenharmony_ci    private static String getHtmlRowResult(String key, long valve,
248b8a72a62Sopenharmony_ci                                           String trClass, String tdClassKey, String tdClassValue) {
249b8a72a62Sopenharmony_ci        return String.format(HTML_TR_TD + key + HTML_TD_END_TD + valve + HTML_TR_TD_END,
250b8a72a62Sopenharmony_ci                trClass, tdClassKey, tdClassValue);
251b8a72a62Sopenharmony_ci    }
252b8a72a62Sopenharmony_ci
253b8a72a62Sopenharmony_ci    private static String getHtmlRowResult(String key, String valve,
254b8a72a62Sopenharmony_ci                                           String trClass, String tdClassKey, String tdClassValue) {
255b8a72a62Sopenharmony_ci        return String.format(HTML_TR_TD + key + HTML_TD_END_TD + valve + HTML_TR_TD_END,
256b8a72a62Sopenharmony_ci                trClass, tdClassKey, tdClassValue);
257b8a72a62Sopenharmony_ci    }
258b8a72a62Sopenharmony_ci
259b8a72a62Sopenharmony_ci    private static String getHtmlRowResult(String key, List<String> valve) {
260b8a72a62Sopenharmony_ci        StringBuilder resValve = new StringBuilder(EMPTY_STRING);
261b8a72a62Sopenharmony_ci        for (String ele : valve) {
262b8a72a62Sopenharmony_ci            resValve.insert(0, HTML_LI_CIRCLE + ele + HTML_LI_END);
263b8a72a62Sopenharmony_ci        }
264b8a72a62Sopenharmony_ci        return HTML_TR_TD_DUPLICATE_KEY + key + HTML_TD_DUPLICATE_VALUE + resValve + HTML_UL_TD_TR_END;
265b8a72a62Sopenharmony_ci    }
266b8a72a62Sopenharmony_ci
267b8a72a62Sopenharmony_ci    private static String getResultHtml(List<ParamModel> models) {
268b8a72a62Sopenharmony_ci        StringBuilder resultHtml = new StringBuilder(EMPTY_STRING);
269b8a72a62Sopenharmony_ci        resultHtml.append(HTML_UL_HEAD);
270b8a72a62Sopenharmony_ci        for (int i = 0; i < models.size(); i++) {
271b8a72a62Sopenharmony_ci            ParamModel model = models.get(i);
272b8a72a62Sopenharmony_ci            String md5Html = getHtmlRowResult(RESULT_MD5, model.getMd5(),
273b8a72a62Sopenharmony_ci                    CLASS_DUPLICATE_LAYOUT, CLASS_DUPLICATE_KEY, CLASS_DUPLICATE_VALUE);
274b8a72a62Sopenharmony_ci            String sizeHtml = getHtmlRowResult(RESULT_SIZE, model.getSize(),
275b8a72a62Sopenharmony_ci                    CLASS_DUPLICATE_LAYOUT, CLASS_DUPLICATE_KEY, CLASS_DUPLICATE_VALUE);
276b8a72a62Sopenharmony_ci            String filesHtml = getHtmlRowResult(RESULT_FILES, model.getFiles());
277b8a72a62Sopenharmony_ci            String liHtml;
278b8a72a62Sopenharmony_ci            if (SHOW_SIZE > i) {
279b8a72a62Sopenharmony_ci                liHtml = HTML_LI_HEAD;
280b8a72a62Sopenharmony_ci            } else {
281b8a72a62Sopenharmony_ci                liHtml = HTML_LI_DUPLICATE;
282b8a72a62Sopenharmony_ci            }
283b8a72a62Sopenharmony_ci            String modelHtml = liHtml + HTML_TABLE_DUPLICATE
284b8a72a62Sopenharmony_ci                    + md5Html + sizeHtml + filesHtml + HTML_TABLE_LI_END;
285b8a72a62Sopenharmony_ci            resultHtml.append(modelHtml);
286b8a72a62Sopenharmony_ci        }
287b8a72a62Sopenharmony_ci        resultHtml.append(HTML_UL_END);
288b8a72a62Sopenharmony_ci        if (models.size() > SHOW_SIZE) {
289b8a72a62Sopenharmony_ci            resultHtml.append(String.format(HTML_BUTTON_SHOW, DUPLICATE_FOLDER_NAME, DUPLICATE_FOLDER_NAME));
290b8a72a62Sopenharmony_ci            resultHtml.append(String.format(HTML_BUTTON_HIDE, DUPLICATE_FOLDER_NAME, DUPLICATE_FOLDER_NAME));
291b8a72a62Sopenharmony_ci        }
292b8a72a62Sopenharmony_ci        return resultHtml.toString();
293b8a72a62Sopenharmony_ci    }
294b8a72a62Sopenharmony_ci
295b8a72a62Sopenharmony_ci    private String md5HashCode(String filePath) throws IOException, NoSuchAlgorithmException {
296b8a72a62Sopenharmony_ci        try (InputStream fis = new FileInputStream(filePath)) {
297b8a72a62Sopenharmony_ci            MessageDigest md = MessageDigest.getInstance(SHA_256);
298b8a72a62Sopenharmony_ci            byte[] buffer = new byte[MD5_BUFFER_SIZE];
299b8a72a62Sopenharmony_ci            int length;
300b8a72a62Sopenharmony_ci            while ((length = fis.read(buffer, 0, MD5_BUFFER_SIZE)) != -1) {
301b8a72a62Sopenharmony_ci                md.update(buffer, 0, length);
302b8a72a62Sopenharmony_ci            }
303b8a72a62Sopenharmony_ci            byte[] md5Bytes = md.digest();
304b8a72a62Sopenharmony_ci            BigInteger bigInt = new BigInteger(1, md5Bytes);
305b8a72a62Sopenharmony_ci            return bigInt.toString(MD5_LENGTH);
306b8a72a62Sopenharmony_ci        } catch (IOException e) {
307b8a72a62Sopenharmony_ci            LOG.error(ScanErrorEnum.STAT_DUPLICATE_INPUT_STREAM_ERROR + e.getMessage());
308b8a72a62Sopenharmony_ci            throw new IOException(ScanErrorEnum.STAT_DUPLICATE_INPUT_STREAM_ERROR.msg + e.getMessage());
309b8a72a62Sopenharmony_ci        } catch (NoSuchAlgorithmException e) {
310b8a72a62Sopenharmony_ci            LOG.error(ScanErrorEnum.STAT_DUPLICATE_MESSAGE_DIGEST_ERROR + e.getMessage());
311b8a72a62Sopenharmony_ci            throw new NoSuchAlgorithmException(ScanErrorEnum.STAT_DUPLICATE_MESSAGE_DIGEST_ERROR.msg
312b8a72a62Sopenharmony_ci                    + e.getMessage());
313b8a72a62Sopenharmony_ci        }
314b8a72a62Sopenharmony_ci    }
315b8a72a62Sopenharmony_ci
316b8a72a62Sopenharmony_ci    private String splitPath(String path, String packageName) {
317b8a72a62Sopenharmony_ci        String[] split = path.split(packageName);
318b8a72a62Sopenharmony_ci        if (split.length > 1) {
319b8a72a62Sopenharmony_ci            return split[1];
320b8a72a62Sopenharmony_ci        } else {
321b8a72a62Sopenharmony_ci            return path;
322b8a72a62Sopenharmony_ci        }
323b8a72a62Sopenharmony_ci    }
324b8a72a62Sopenharmony_ci}
325