• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 package com.sk.utils;
16 
17 import com.alibaba.fastjson2.JSON;
18 import com.alibaba.fastjson2.JSONObject;
19 import com.fasterxml.jackson.databind.ObjectMapper;
20 import com.intellij.notification.NotificationType;
21 import com.intellij.openapi.diagnostic.Logger;
22 import com.intellij.openapi.project.Project;
23 import org.apache.http.util.TextUtils;
24 
25 import java.io.BufferedReader;
26 import java.io.File;
27 import java.io.FileInputStream;
28 import java.io.FileNotFoundException;
29 import java.io.FileWriter;
30 import java.io.IOException;
31 import java.io.InputStreamReader;
32 import java.nio.charset.StandardCharsets;
33 import java.util.Arrays;
34 import java.util.Properties;
35 import java.util.regex.Pattern;
36 
37 /**
38  * 文本文件工具
39  *
40  * @author: xudong
41  * @see: file utils
42  * @version: v1.0.0
43  * @since 2022-02-21
44  */
45 public class FileUtil {
46     private static final Logger LOG = Logger.getInstance(FileUtil.class);
47 
48     private static final int COMPILE_SDK_VERSION = 5;
49 
50     private static final String LF = getNewline(); // 换行符
51 
52     private static final String BUILD_OPTION = "{" + LF
53             + "    \"externalNativeOptions\": {" + LF
54             + "      \"path\": \"\"," + LF
55             + "      \"arguments\": \"\"," + LF
56             + "      \"cppFlags\": \"\"," + LF
57             + "    }" + LF
58             + "  }";
59 
60     /**
61      * 改写build-profile.json5文件
62      *
63      * @param buildJsonFilePath build-profile.json5 文件路径
64      * @param cmakeFilePath CMakeList.txt 文件路径
65      */
writeBuildJsonFile(String buildJsonFilePath, String cmakeFilePath)66     public void writeBuildJsonFile(String buildJsonFilePath, String cmakeFilePath) {
67         try {
68             String buildStr = readWholeFile(buildJsonFilePath);
69             JSONObject buildObj = (JSONObject) JSON.parse(buildStr);
70             JSONObject buildOptionObj = (JSONObject) JSON.parse(BUILD_OPTION);
71             ((JSONObject) buildOptionObj.get("externalNativeOptions")).put("path", cmakeFilePath);
72             buildObj.put("buildOption", buildOptionObj);
73             ObjectMapper mapper = new ObjectMapper();
74             buildStr = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(buildObj);
75 
76             writeContentToFile(buildJsonFilePath, buildStr, false);
77         } catch (IOException ioException) {
78             LOG.error("Failed to write file [" + buildJsonFilePath + "], error: " + ioException);
79         }
80     }
81 
82     /**
83      * 将数据写入到指定文件中
84      *
85      * @param path    文件路径
86      * @param content 数据内容
87      * @param isAppend 文件是否追加写入
88      */
writeContentToFile(String path, String content, boolean isAppend)89     public void writeContentToFile(String path, String content, boolean isAppend) {
90         File file = new File(path);
91         try (FileWriter fw = new FileWriter(file, isAppend)) {
92             fw.write(FileUtil.getNewline() + content + FileUtil.getNewline());
93         } catch (IOException ioException) {
94             LOG.error("Failed to write file [" + path + "], error: " + ioException);
95         }
96     }
97 
98     /**
99      * 创建文件
100      *
101      * @param path 文件路径
102      * @return 文件路径
103      */
makeFile(String path)104     public String makeFile(String path) {
105         File file = new File(path);
106         if (!file.exists()) {
107             try {
108                 boolean isCreateFile = file.createNewFile();
109                 if (isCreateFile) {
110                     LOG.info(String.format("makeFile %s success", path));
111                 }
112             } catch (IOException ioException) {
113                 LOG.error(String.format("makeFile %s error:%s", path, ioException));
114                 return "";
115             }
116         }
117         return file.getPath();
118     }
119 
120     /**
121      * 获得 pathA 相对于 pathB的相对路径
122      *
123      * @param pathA 路径A,如 D:\xx\yy\zz\a1\a2
124      * @param pathB 路径B, 如 D:\xx\yy\zz\b1\b2\b3
125      * @return pathA 相对于 pathB的相对路径: ../../../a1/a2/
126      */
getRelativePath(String pathA, String pathB)127     public String getRelativePath(String pathA, String pathB) {
128         String separatorStr = File.separator.equals("\\") ? "\\\\" : File.separator;
129         String[] pathAList = pathA.split(separatorStr);
130         String[] pathBList = pathB.split(separatorStr);
131 
132         int pos = 0;
133         for (; pos < pathAList.length && pos < pathBList.length; ++pos) {
134             if (!pathAList[pos].equals(pathBList[pos])) {
135                 // 找到两个path路径存在差异的位置
136                 break;
137             }
138         }
139         // 截取pathA和pathB路径字符串的差异部分
140         String[] diffPathAList = Arrays.copyOfRange(pathAList, pos, pathAList.length);
141         String[] diffPathBList = Arrays.copyOfRange(pathBList, pos, pathBList.length);
142 
143         // pathA的差异字符串作为相对路径的结尾部分
144         String pathAStr = String.join("/", diffPathAList);
145         pathAStr = pathAStr.isBlank() ? "" : pathAStr + "/";
146 
147         // 根据pathB的差异目录层级生成向上跳转字符串
148         String rollbackPath = "";
149         for (int i = 0; i < diffPathBList.length; ++i) {
150             rollbackPath += "../";
151         }
152         rollbackPath = rollbackPath.isEmpty() ? "./" : rollbackPath;
153 
154         // 相对路径 = 向上跳转部分 + pathA的差异部分
155         return rollbackPath + pathAStr;
156     }
157 
158     /**
159      * 将错误信息输入到txt中
160      *
161      * @param path    路径
162      * @param content 内容
163      */
writeErrorToTxt(String path, String content)164     public void writeErrorToTxt(String path, String content) {
165         File file = new File(path);
166         try (FileWriter fw = new FileWriter(file, true)) {
167             fw.write(content + FileUtil.getNewline());
168         } catch (IOException ioException) {
169             LOG.error("writeErrorToTxt io error" + ioException);
170         }
171     }
172 
173     /**
174      * 判断文件是否包含指定字符串
175      *
176      * @param path    文件路径
177      * @param content 指定内容
178      * @return 是否包含指定字符串
179      * @throws IOException 异常信息
180      */
findStringInFile(String path, String content)181     public boolean findStringInFile(String path, String content) throws IOException {
182         File file = new File(path);
183         String[] command = content.split(FileUtil.getNewline());
184 
185         try (InputStreamReader read = new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8);
186             BufferedReader bufferedReader = new BufferedReader(read)) {
187             return isContainString(bufferedReader, command[1]);
188         } catch (FileNotFoundException foundException) {
189             LOG.error("file not found" + foundException);
190             return false;
191         }
192     }
193 
isContainString(BufferedReader bufferedReader, String command)194     private boolean isContainString(BufferedReader bufferedReader, String command) {
195         String line = null;
196         while (true) {
197             try {
198                 if ((line = bufferedReader.readLine()) == null) {
199                     return false;
200                 }
201             } catch (IOException ioException) {
202                 LOG.error("findStringInFile IOException" + ioException);
203             }
204 
205             if (line.contains(command)) {
206                 return true;
207             }
208         }
209     }
210 
211     /**
212      * 获取换行符
213      *
214      * @return 换行符
215      */
getNewline()216     public static String getNewline() {
217         return System.getProperty("line.separator");
218     }
219 
220     /**
221      * 正则匹配所选文件名是否符合规范
222      *
223      * @param fileName 文件名
224      * @return boolean 是否匹配
225      */
patternFileName(String fileName)226     public static boolean patternFileName(String fileName) {
227         String pattern = "((@ohos\\.)*([.a-z_A-Z0-9]+).d.ts)";
228         return Pattern.matches(pattern, fileName);
229     }
230 
231     /**
232      * check project SDK
233      *
234      * @param project  projectid
235      * @param baseFile project root file
236      * @return boolean
237      */
checkProjectSDK(Project project, String baseFile)238     public static boolean checkProjectSDK(Project project, String baseFile) {
239 
240         String gradlePath = "";
241         File baseDir = new File(baseFile);
242         if (baseDir.isDirectory()) {
243             File[] childFile = baseDir.listFiles();
244             assert childFile != null;
245             for (File file : childFile) {
246                 if (file.getName().equals("build.gradle") || file.getName().equals("build-profile.json5")) {
247                     gradlePath = file.getPath();
248                 }
249             }
250         }
251 
252         Properties properties = new Properties();
253         if (TextUtils.isBlank(gradlePath)) {
254             GenNotification.notifyMessage(project, "项目结构中没有grandle配置文件。",
255                     "当前项目结构不支持",
256                     NotificationType.WARNING);
257             return true;
258         }
259         try {
260             properties.load(new FileInputStream(gradlePath));
261         } catch (IOException e) {
262             GenNotification.notifyMessage(project, e.getMessage(), "提示", NotificationType.ERROR);
263             LOG.error(String.format("Can not load file :%s . %s", gradlePath, e));
264             return true;
265         }
266         String ohosSDK = properties.getProperty("compileSdkVersion");
267 
268         if (ohosSDK != null && Integer.parseInt(ohosSDK) < COMPILE_SDK_VERSION) {
269             GenNotification.notifyMessage(project, "SKD版本过低,NAPI仅支持5.0及以上版本",
270                     "提示",
271                     NotificationType.WARNING);
272             return true;
273         }
274         return false;
275     }
276 
readWholeFile(String fileName)277     private String readWholeFile(String fileName) {
278         File file = new File(fileName);
279         byte[] rdBuf = new byte[(int) file.length()];
280         try(FileInputStream in = new FileInputStream(file)) {
281             in.read(rdBuf);
282             return new String(rdBuf, "UTF-8");
283         } catch (FileNotFoundException foundException) {
284             LOG.error(String.format("File %s does not exist.", fileName));
285         } catch (IOException ioException) {
286             LOG.error(String.format("Failed to read file %s. Error: %s", fileName, ioException));
287         }
288         return "";
289     }
290 }
291