From 99edc4efe81c9a77939da351ecbfd36722ed1b31 Mon Sep 17 00:00:00 2001 From: zhaojunxia Date: Tue, 18 Oct 2022 16:43:32 +0800 Subject: [PATCH] feat: add gn intellj plugin Signed-off-by: zhaojunxia --- .../resources/META-INF/plugin.xml | 37 ++ .../resources/images/openDisk.png | Bin 0 -> 318 bytes .../resources/images/step_one.png | Bin 0 -> 41832 bytes .../resources/images/step_two.png | Bin 0 -> 48449 bytes .../com/sk/gn/action/InputScriptAction.java | 72 +++ .../com/sk/gn/action/SelectBankAction.java | 58 +++ .../sk/gn/action/SelectOriginCodeAction.java | 53 ++ .../com/sk/gn/action/SelectOutDirAction.java | 63 +++ .../src/com/sk/gn/dialog/ConfirmDialog.java | 52 ++ .../com/sk/gn/dialog/ConfirmDialogPane.form | 75 +++ .../com/sk/gn/dialog/ConfirmDialogPane.java | 50 ++ .../src/com/sk/gn/dialog/ErrorDialog.form | 86 ++++ .../src/com/sk/gn/dialog/ErrorDialog.java | 97 ++++ .../src/com/sk/gn/dialog/GenDialogPane.form | 313 ++++++++++++ .../src/com/sk/gn/dialog/GenDialogPane.java | 475 ++++++++++++++++++ .../com/sk/gn/dialog/GenGenerateDialog.java | 151 ++++++ .../src/com/sk/gn/dialog/GenResultDialog.form | 78 +++ .../src/com/sk/gn/dialog/GenResultDialog.java | 82 +++ .../src/com/sk/gn/ng/GnDTS.java | 64 +++ .../src/com/sk/gn/ng/GnMenuDTS.java | 44 ++ .../src/com/sk/gn/utils/FileUtil.java | 174 +++++++ .../src/com/sk/gn/utils/GenNotification.java | 116 +++++ 22 files changed, 2140 insertions(+) create mode 100644 hdc/gn_IntelliJ_plugin/resources/META-INF/plugin.xml create mode 100644 hdc/gn_IntelliJ_plugin/resources/images/openDisk.png create mode 100644 hdc/gn_IntelliJ_plugin/resources/images/step_one.png create mode 100644 hdc/gn_IntelliJ_plugin/resources/images/step_two.png create mode 100644 hdc/gn_IntelliJ_plugin/src/com/sk/gn/action/InputScriptAction.java create mode 100644 hdc/gn_IntelliJ_plugin/src/com/sk/gn/action/SelectBankAction.java create mode 100644 hdc/gn_IntelliJ_plugin/src/com/sk/gn/action/SelectOriginCodeAction.java create mode 100644 hdc/gn_IntelliJ_plugin/src/com/sk/gn/action/SelectOutDirAction.java create mode 100644 hdc/gn_IntelliJ_plugin/src/com/sk/gn/dialog/ConfirmDialog.java create mode 100644 hdc/gn_IntelliJ_plugin/src/com/sk/gn/dialog/ConfirmDialogPane.form create mode 100644 hdc/gn_IntelliJ_plugin/src/com/sk/gn/dialog/ConfirmDialogPane.java create mode 100644 hdc/gn_IntelliJ_plugin/src/com/sk/gn/dialog/ErrorDialog.form create mode 100644 hdc/gn_IntelliJ_plugin/src/com/sk/gn/dialog/ErrorDialog.java create mode 100644 hdc/gn_IntelliJ_plugin/src/com/sk/gn/dialog/GenDialogPane.form create mode 100644 hdc/gn_IntelliJ_plugin/src/com/sk/gn/dialog/GenDialogPane.java create mode 100644 hdc/gn_IntelliJ_plugin/src/com/sk/gn/dialog/GenGenerateDialog.java create mode 100644 hdc/gn_IntelliJ_plugin/src/com/sk/gn/dialog/GenResultDialog.form create mode 100644 hdc/gn_IntelliJ_plugin/src/com/sk/gn/dialog/GenResultDialog.java create mode 100644 hdc/gn_IntelliJ_plugin/src/com/sk/gn/ng/GnDTS.java create mode 100644 hdc/gn_IntelliJ_plugin/src/com/sk/gn/ng/GnMenuDTS.java create mode 100644 hdc/gn_IntelliJ_plugin/src/com/sk/gn/utils/FileUtil.java create mode 100644 hdc/gn_IntelliJ_plugin/src/com/sk/gn/utils/GenNotification.java diff --git a/hdc/gn_IntelliJ_plugin/resources/META-INF/plugin.xml b/hdc/gn_IntelliJ_plugin/resources/META-INF/plugin.xml new file mode 100644 index 00000000..1fe4affa --- /dev/null +++ b/hdc/gn_IntelliJ_plugin/resources/META-INF/plugin.xml @@ -0,0 +1,37 @@ + + com.sk.gn + Gn Generate + 1.0.1 + 深圳开鸿数字产业发展有限公司 + + Introduction +

    The current OpenHarmony 3.1Release and later versions use bundle.json to integrate subsystem code. However, some libraries are integrated as cmakelists.txt, which cannot be integrated into OpenHarmony source code. You need to compile the library to a build.gn file, and then use the generated GN script to integrate the library into OpenHarmony.

+

Sources on Gitee

+ ]]> +
+ + + com.intellij.modules.lang + + + + + + + + + + + + + + + + + + + + + +
\ No newline at end of file diff --git a/hdc/gn_IntelliJ_plugin/resources/images/openDisk.png b/hdc/gn_IntelliJ_plugin/resources/images/openDisk.png new file mode 100644 index 0000000000000000000000000000000000000000..5956a0e538a400c7deaf41167ae5ea70348b8584 GIT binary patch literal 318 zcmV-E0m1%>P)Px#_(?=TR5(wi(;-L%K@`UE|6{vRxMVzRM&rBzgXO?tuxPWYNkI_HY11Yqu_#ys zi{W73vdL&Qip^+WMqGTbh~Dks)cL+2Z{Usa&m(nR51OXA={hN;NsMva#}+dSz$38Q zDO`!jUI^iS7UICIst!DCW?R4^@HP!7iekfo3sqh0hQBA9*8iGr&4Cl(VAi-l?$3Z- z2aYn!9zS;AR8^OA5HouM_8mA^)ul|}8Q5uol+tC4ahL;?W%(i^+btj>*CB+39H6SI z*ObzxKjBVQ=W_rvdk5AXcu>{3OyC0;IWPfMasZ(1{Q8;tLhUN|4gZz<1l}xWu~ehG QI{*Lx07*qoM6N<$f-2F9MgRZ+ literal 0 HcmV?d00001 diff --git a/hdc/gn_IntelliJ_plugin/resources/images/step_one.png b/hdc/gn_IntelliJ_plugin/resources/images/step_one.png new file mode 100644 index 0000000000000000000000000000000000000000..10638d6cf157dd83e2f0a091c637bad05f5c8e7b GIT binary patch literal 41832 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 C07E_i literal 0 HcmV?d00001 diff --git a/hdc/gn_IntelliJ_plugin/resources/images/step_two.png b/hdc/gn_IntelliJ_plugin/resources/images/step_two.png new file mode 100644 index 0000000000000000000000000000000000000000..a298764419264adfe58ece0c7dfcb72abb4804f0 GIT binary patch literal 48449 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 + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/hdc/gn_IntelliJ_plugin/src/com/sk/gn/dialog/ConfirmDialogPane.java b/hdc/gn_IntelliJ_plugin/src/com/sk/gn/dialog/ConfirmDialogPane.java new file mode 100644 index 00000000..f083c554 --- /dev/null +++ b/hdc/gn_IntelliJ_plugin/src/com/sk/gn/dialog/ConfirmDialogPane.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2022 Shenzhen Kaihong Digital Industry Development 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 com.sk.gn.dialog; + +import javax.swing.JPanel; +import javax.swing.JLabel; +import javax.swing.JDialog; +import javax.swing.ImageIcon; + +/** + * ConfirmDiagPane自定义确认对话框 + * 解决ShowConfirmDiag 在Deveco里面会出现界面错位问题。 + * + * @author: zhaoxudong@kaihong.com + * @see: generator error dialog + * @version: v1.0.0 + * @since 2022-02-21 + */ +public class ConfirmDialogPane extends JDialog { + private JPanel contentPane; + private JLabel msgLabel; + private JLabel iconLabel; + + /** + * 构造函数 + * + * @param sErrorMessage 错误信息 + */ + public ConfirmDialogPane(String sErrorMessage) { + msgLabel.setText(sErrorMessage); + iconLabel.setIcon(new ImageIcon("")); + } + + + JPanel getContentPanel() { + return contentPane; + } +} diff --git a/hdc/gn_IntelliJ_plugin/src/com/sk/gn/dialog/ErrorDialog.form b/hdc/gn_IntelliJ_plugin/src/com/sk/gn/dialog/ErrorDialog.form new file mode 100644 index 00000000..af9042f6 --- /dev/null +++ b/hdc/gn_IntelliJ_plugin/src/com/sk/gn/dialog/ErrorDialog.form @@ -0,0 +1,86 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/hdc/gn_IntelliJ_plugin/src/com/sk/gn/dialog/ErrorDialog.java b/hdc/gn_IntelliJ_plugin/src/com/sk/gn/dialog/ErrorDialog.java new file mode 100644 index 00000000..589dfbb0 --- /dev/null +++ b/hdc/gn_IntelliJ_plugin/src/com/sk/gn/dialog/ErrorDialog.java @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2022 Shenzhen Kaihong Digital Industry Development 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 com.sk.gn.dialog; + +import com.intellij.openapi.diagnostic.Logger; + +import javax.swing.JButton; +import javax.swing.JComponent; +import javax.swing.JDialog; +import javax.swing.JPanel; +import javax.swing.JTextArea; +import javax.swing.KeyStroke; +import java.awt.event.KeyEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.io.IOException; + +/** + * ErrorDialog错误对话框 + * + * @author: zhaoxudong@kaihong.com + * @see: generator error dialog + * @version: v1.0.0 + * @since 2022-02-21 + */ +public class ErrorDialog extends JDialog { + private static final Logger LOG = Logger.getInstance(ErrorDialog.class); + private static final String URL = + "rundll32 url.dll,FileProtocolHandler" + " https://gitee" + ".com/openharmony" + "-sig/napi_generator"; + + private JPanel contentPane; + private JButton buttonOK; + private JButton buttonHelp; + private JTextArea textAreaError; + private String errorMessage; + + public ErrorDialog(String sErrorMessage) { + errorMessage = sErrorMessage; + } + + /** + * 初始化 + */ + public void initDialog() { + setContentPane(contentPane); + setModal(true); + getRootPane().setDefaultButton(buttonOK); + setTitle("执行失败"); + textAreaError.setText(errorMessage); + buttonOK.addActionListener(actionEvent -> onOK()); + + buttonHelp.addActionListener(actionEvent -> onCancel()); + + // call onCancel() when cross is clicked + setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); + addWindowListener(new WindowAdapter() { + /** + * close dialog + * @param windowEvent WindowEvent + */ + @Override + public void windowClosing(WindowEvent windowEvent) { + onCancel(); + } + }); + + // call onCancel() on ESCAPE + contentPane.registerKeyboardAction(actionEvent -> onCancel(), + KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), + JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); + } + + private void onOK() { + dispose(); + } + + private void onCancel() { + try { + Runtime.getRuntime().exec(URL); + } catch (IOException ioException) { + LOG.error("exec command help error" + ioException); + } + dispose(); + } +} \ No newline at end of file diff --git a/hdc/gn_IntelliJ_plugin/src/com/sk/gn/dialog/GenDialogPane.form b/hdc/gn_IntelliJ_plugin/src/com/sk/gn/dialog/GenDialogPane.form new file mode 100644 index 00000000..0404e5e1 --- /dev/null +++ b/hdc/gn_IntelliJ_plugin/src/com/sk/gn/dialog/GenDialogPane.form @@ -0,0 +1,313 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/hdc/gn_IntelliJ_plugin/src/com/sk/gn/dialog/GenDialogPane.java b/hdc/gn_IntelliJ_plugin/src/com/sk/gn/dialog/GenDialogPane.java new file mode 100644 index 00000000..9cbbccbc --- /dev/null +++ b/hdc/gn_IntelliJ_plugin/src/com/sk/gn/dialog/GenDialogPane.java @@ -0,0 +1,475 @@ +/* + * Copyright (c) 2022 Shenzhen Kaihong Digital Industry Development 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 com.sk.gn.dialog; + +import com.intellij.notification.NotificationType; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.ValidationInfo; +import com.sk.gn.action.InputScriptAction; +import com.sk.gn.action.SelectBankAction; +import com.sk.gn.action.SelectOriginCodeAction; +import com.sk.gn.action.SelectOutDirAction; +import com.sk.gn.utils.FileUtil; +import com.sk.gn.utils.GenNotification; +import org.apache.http.util.TextUtils; +import org.jetbrains.annotations.Nullable; + +import javax.swing.JButton; +import javax.swing.JComboBox; +import javax.swing.JComponent; +import javax.swing.JDialog; +import javax.swing.JPanel; +import javax.swing.JTextField; +import javax.swing.KeyStroke; +import java.awt.event.KeyEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.awt.event.WindowListener; +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; + +import static com.sk.gn.utils.FileUtil.writeTmpFile; + +/** + * GenerateDialogPane生成工具主界面 + * + * @author: zhaoxudong@kaihong.com + * @see: select generate dialog + * @version: v1.0.0 + * @since 2022-02-21 + */ +public class GenDialogPane extends JDialog { + private static final Logger LOG = Logger.getInstance(GenDialogPane.class); + private static final String SYS_NAME = System.getProperties().getProperty("os.name").toUpperCase(); + + private JPanel contentPane; + private JTextField opOutPathTextField; + private JTextField opOriginTextField; + private JTextField transplantTextField; + private JButton selectOPOutButton; + private JButton selectOPOriginButton; + private JButton selectTransplantButton; + private JButton selectScriptButton; + private JTextField subsystemTextField; + private JTextField test_partTextField; + private JTextField compileTextField; + private JTextField inputScriptTextField; + private JComboBox comboBox; + private boolean generateSuccess = true; + private String sErrorMessage = ""; + + /** + * 输出路径 -o + */ + private String outputCodeDir; + + /** + * 源码路径 -p + */ + private String originCodeDir; + + /** + * 输入脚本路径 -f + */ + private String inputScriptDir; + + /** + * 输入脚本类型 -t + */ + private String scriptType; + + /** + * 移植库路径/GN生成路径 -m + */ + private String transplantDir; + + /** + * 子系统名称 -s + */ + private String subsystemName; + + /** + * 组件名称 -m + */ + private String componentName; + + /** + * 编译选项 -a + */ + private String compileOptions; + + private final Project project; + + /** + * 构造函数 + * + * @param project projectId + * @param filePath 文件路径 + */ + public GenDialogPane(Project project, String filePath) { + this.project = project; + // call onCancel() on ESCAPE + contentPane.registerKeyboardAction(actionEvent -> onCancel(), KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), + JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); + + selectOPOutButton.addActionListener(new SelectOutDirAction(selectOPOutButton, opOutPathTextField)); + selectOPOriginButton.addActionListener(new SelectOriginCodeAction(selectOPOriginButton, opOriginTextField)); + selectTransplantButton.addActionListener(new SelectBankAction(selectTransplantButton, transplantTextField)); + selectScriptButton.addActionListener(new InputScriptAction(selectScriptButton, inputScriptTextField, + comboBox, transplantTextField)); + inputScriptTextField.setText(filePath); + } + + @Override + public synchronized void addWindowListener(WindowListener windowListener) { + super.addWindowListener(windowListener); + new WindowAdapter() { + /** + * close dialog + * + * @param windowEvent WindowEvent + */ + @Override + public void windowClosing(WindowEvent windowEvent) { + onCancel(); + } + }; + } + + /** + * 验证文本选择框是否空。是否替换已存在的内容 + * + * @return ValidationInfo 返回不符要求的信息。 + */ + @Nullable + public ValidationInfo validationInfo() { + getEditText(); + ValidationInfo validationInfo = null; + String warnMsg; + if (TextUtils.isEmpty(outputCodeDir)) { + warnMsg = "输出路径不能为空"; + warningMessage(warnMsg); + validationInfo = new ValidationInfo(warnMsg); + return validationInfo; + } + if (TextUtils.isEmpty(originCodeDir)) { + warnMsg = "源码路径不能为空"; + warningMessage(warnMsg); + validationInfo = new ValidationInfo(warnMsg); + return validationInfo; + } + if (TextUtils.isEmpty(transplantDir)) { + warnMsg = "库移植的路径不能为空"; + warningMessage(warnMsg); + validationInfo = new ValidationInfo(warnMsg); + return validationInfo; + } + if (TextUtils.isEmpty(inputScriptDir)) { + warnMsg = "输入脚本路径不能为空"; + warningMessage(warnMsg); + validationInfo = new ValidationInfo(warnMsg); + return validationInfo; + } + if (TextUtils.isEmpty(subsystemName)) { + warnMsg = "子系统名称不能为空"; + warningMessage(warnMsg); + validationInfo = new ValidationInfo(warnMsg); + return validationInfo; + } + if (TextUtils.isEmpty(componentName)) { + warnMsg = "组件名称不能为空"; + warningMessage(warnMsg); + validationInfo = new ValidationInfo(warnMsg); + return validationInfo; + } + File file = new File(transplantTextField.getText() + "/build_tmp"); + if (file.exists()) { + ConfirmDialog confirmDialog = new ConfirmDialog("是否替换已存在的生成结果?"); + if (!confirmDialog.showAndGet()) { + validationInfo = new ValidationInfo(String.format("不替换现有生成结果:%s", file)); + return validationInfo; + } + } + return validationInfo; + } + + private void getEditText() { + // 输出路径 + outputCodeDir = opOutPathTextField.getText().trim(); + // 源码路径 + originCodeDir = opOriginTextField.getText().trim(); + // 库移植的路径 + transplantDir = transplantTextField.getText().trim(); + // 输入脚本路径 + inputScriptDir = inputScriptTextField.getText().trim(); + // 输入脚本类型 + scriptType = comboBox.getSelectedItem().toString().trim(); + // 子系统名称 + subsystemName = subsystemTextField.getText().trim(); + // 组件名称 + componentName = test_partTextField.getText().trim(); + // 编译选项 + compileOptions = compileTextField.getText().trim(); + } + + private void onCancel() { + dispose(); + } + + private void warningMessage(String title) { + String notifyContent = "带*号均为必填项"; + GenNotification.notifyMessage(this.project, notifyContent, title, NotificationType.WARNING); + } + + /** + * 执行主程序入口 + * + * @return 执行状态 + */ + public boolean runFun() { + createCopyResMakeFile(); + createCopyResToolChainFile(); + GenNotification.notifyMessage(this.project, "", "正在生成", NotificationType.INFORMATION); + String command; + command = genCommand(); + try { + if (!TextUtils.isEmpty(command) && callExtProcess(command)) { + GenNotification.notifyMessage(project, opOriginTextField.getText(), "提示", + NotificationType.INFORMATION, true); + return true; + } + } catch (IOException | InterruptedException ex) { + GenNotification.notifyMessage(project, opOriginTextField.getText(), "Command exec error", + NotificationType.ERROR); + LOG.error(ex); + } + return false; + } + + /** + * 生成命令行指令 + * + * @return 返回命令行执行内容 + */ + private String genCommand() { + String tmpDirFile = System.getProperty("java.io.tmpdir"); + String execFn; + if (SYS_NAME.contains("WIN")) { + execFn = "cmds/win/gn-gen-win.exe"; + tmpDirFile += "/gn-gen-win.exe"; + } else if (SYS_NAME.contains("LINUX")) { + execFn = "cmds/linux/gn-gen-linux"; + tmpDirFile += "/gn-gen-linux"; + } else { + execFn = "cmds/mac/gn-gen-macos"; + tmpDirFile += "/gn-gen-macos"; + } + File file = new File(tmpDirFile); + writeTmpFile(tmpDirFile, execFn, project); + if (SYS_NAME.contains("LINUX") || SYS_NAME.contains("MAC OS")) { + try { + executable(tmpDirFile); + } catch (IOException | InterruptedException e) { + GenNotification.notifyMessage(this.project, e.getMessage(), "Can not Find File:" + execFn, + NotificationType.ERROR); + LOG.error(e); + } + } + String command = file.toString(); + command += " -o " + outputCodeDir + " -p " + originCodeDir + " -f " + inputScriptDir + " -t " + scriptType + + " -s " + subsystemName + " -m " + componentName + " -d " + transplantDir; + if (!TextUtils.isEmpty(compileTextField.getText().trim())) { + command += " -a " + "\"" + compileOptions + "\""; + } + return command; + } + + private void createCopyResMakeFile() { + String makeFilePath = "cmds/res/linux/bin/make"; + if (SYS_NAME.contains("WIN")) { + makeFilePath = "cmds/res/win64/bin/gnumake.exe"; + } + String tmpDirFile = System.getProperty("java.io.tmpdir") + "/res/linux/bin/"; + File file = new File(tmpDirFile); + if (file.mkdirs()) { + LOG.info("create dir success"); + } + String tmp = SYS_NAME.contains("WIN") ? file.getPath() + "/gnumake.exe" : file.getPath() + "/make"; + writeTmpFile(tmp, makeFilePath, project); + try { + executable(tmp); + } catch (IOException | InterruptedException e) { + GenNotification.notifyMessage(this.project, e.getMessage(), "Can not Find File:" + makeFilePath, + NotificationType.ERROR); + LOG.error(e); + } + } + + private void createCopyResToolChainFile() { + String toolchainFileDir = "cmds/res/linux/ohos.toolchain.cmake"; + if (SYS_NAME.contains("WIN")) { + toolchainFileDir = "cmds/res/win64/ohos.toolchain.cmake"; + } + String tmpDirFile = System.getProperty("java.io.tmpdir") + "/res/linux/"; + File file = new File(tmpDirFile); + if (file.mkdirs()) { + LOG.info("create dir success"); + } + String tmp = file.getPath() + "/ohos.toolchain.cmake"; + writeTmpFile(tmp, toolchainFileDir, project); + try { + executable(tmp); + } catch (IOException | InterruptedException e) { + GenNotification.notifyMessage(this.project, e.getMessage(), "Can not Find File:" + toolchainFileDir, + NotificationType.ERROR); + LOG.error(e); + } + } + + private boolean callExtProcess(String command) throws IOException, InterruptedException { + if (TextUtils.isEmpty(command)) { + GenNotification.notifyMessage(this.project, "执行命令文件为空", "空命令行提示", NotificationType.ERROR); + return false; + } + Process process = Runtime.getRuntime().exec(command); + genResultLog(process); + StreamConsumer errConsumer = new StreamConsumer(process.getErrorStream()); + StreamConsumer outputConsumer = new StreamConsumer(process.getInputStream()); + errConsumer.start(); + outputConsumer.start(); + if (generateSuccess) { + GenNotification.notifyMessage(project, "执行成功", "提示", NotificationType.INFORMATION); + } else { + GenNotification.notifyMessage(project, sErrorMessage, "提示", NotificationType.ERROR); + return false; + } + errConsumer.join(); + outputConsumer.join(); + return true; + } + + /** + * 赋值可执行文件权限。 + * + * @param execFn 可执行命令 + * @throws IOException 打开文件异常 + * @throws InterruptedException 中断异常 + */ + private void executable(String execFn) throws IOException, InterruptedException { + callExtProcess("chmod a+x " + execFn); + } + + /** + * 获取生成成功结果文件。 + * + * @param process 进程ID + */ + private void genResultLog(Process process) { + BufferedReader stdInput = new BufferedReader(new InputStreamReader(process.getInputStream())); + BufferedReader stdError = new BufferedReader(new InputStreamReader(process.getErrorStream())); + String sErr; + String sOut; + sErr = getErrorResult(stdError); + if (TextUtils.isEmpty(sErr)) { + sOut = genInputLog(stdInput); + if (!generateIsSuccess(sOut)) { + sErrorMessage = sOut; + } + return; + } + generateSuccess = false; + sErrorMessage = sErr; + } + + /** + * 获取生成失败结果文件。 + * + * @param stdError error buff + * @return ErrorResult + */ + private String getErrorResult(BufferedReader stdError) { + StringBuilder sErr = new StringBuilder(); + while (true) { + String sTmp; + try { + if ((sTmp = stdError.readLine()) == null) { + break; + } + sErr.append(sTmp).append(FileUtil.getNewline()); + } catch (IOException ioException) { + LOG.error(" genResultLog stdInput error" + ioException); + } + } + return sErr.toString(); + } + + private boolean generateIsSuccess(String sOut) { + generateSuccess = sOut.contains("success") || TextUtils.isEmpty(sOut); + return generateSuccess; + } + + /** + * 获取生成文本内容。 + * + * @param stdInput input buff + * @return 返回当前输入框内容 + */ + private String genInputLog(BufferedReader stdInput) { + StringBuilder sOut = new StringBuilder(); + while (true) { + String sTmp; + try { + if ((sTmp = stdInput.readLine()) == null) { + break; + } + sOut.append(sTmp).append(FileUtil.getNewline()); + } catch (IOException ioException) { + LOG.error(" genResultLog stdInput error" + ioException); + } + } + return sOut.toString(); + } + + static class StreamConsumer extends Thread { + InputStream is; + + StreamConsumer(InputStream is) { + super.setName("StreamConsumer"); + this.is = is; + } + + @Override + public void run() { + try { + InputStreamReader isr = new InputStreamReader(is); + BufferedReader br = new BufferedReader(isr); + String line; + while ((line = br.readLine()) != null) { + LOG.error("StreamConsumer" + line); + } + } catch (IOException ioException) { + LOG.error("StreamConsumer io error" + ioException); + } + } + } + + JPanel getContentPanel() { + return contentPane; + } +} diff --git a/hdc/gn_IntelliJ_plugin/src/com/sk/gn/dialog/GenGenerateDialog.java b/hdc/gn_IntelliJ_plugin/src/com/sk/gn/dialog/GenGenerateDialog.java new file mode 100644 index 00000000..0429418b --- /dev/null +++ b/hdc/gn_IntelliJ_plugin/src/com/sk/gn/dialog/GenGenerateDialog.java @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2022 Guangzhou Digitalchina Information Technology Co., Ltd. + * All rights reserved. + * 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 com.sk.gn.dialog; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.ValidationInfo; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.Action; +import javax.swing.JComponent; +import java.awt.Desktop; +import java.awt.event.ActionEvent; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; + +/** + * 主界面对话框Wrapper + * + * @author: zhaoxudong@kaihong.com + * @see: tool conversion plug-in + * @version: v1.0.0 + * @since 2022-09-27 + */ +public class GenGenerateDialog extends DialogWrapper { + private static final Logger LOG = Logger.getInstance(GenGenerateDialog.class); + private static final String TITLE = "Gn Generate Frame"; + private static final String URL = "https://gitee.com/openharmony/napi_generator/tree/master/hdc/gn-gen"; + + private final GenDialogPane genDiag; + + /** + * 构造函数 + * + * @param project projectId + * @param filePath 文件路径 + */ + public GenGenerateDialog(Project project, String filePath) { + super(true); + this.setResizable(false); + setTitle(TITLE); + setModal(true); + genDiag = new GenDialogPane(project, filePath); + init(); + } + + /** + * 创建视图 + * + * @return 组件内容 + */ + @Nullable + @Override + protected JComponent createCenterPanel() { + return genDiag.getContentPanel(); + } + + + /** + * 校验数据 + * + * @return 检测文本框架是否有目录。 + */ + @Nullable + @Override + protected ValidationInfo doValidate() { + return genDiag.validationInfo(); + } + + /** + * ok/cancel按钮 + * + * @return Action[] buttos list + */ + @NotNull + @Override + protected Action[] createActions() { + DialogWrapperExitAction exitAction = new DialogWrapperExitAction("Cancel", CANCEL_EXIT_CODE); + CustomOKAction okAction = new CustomOKAction(); + + // 设置默认的焦点按钮 + okAction.putValue(DialogWrapper.DEFAULT_ACTION, true); + return new Action[]{exitAction, okAction}; + } + + @NotNull + @Override + protected Action[] createLeftSideActions() { + CustomHelpAction helpAction = new CustomHelpAction(); + return new Action[]{helpAction}; + } + + /** + * 自定义 ok Action + */ + protected class CustomOKAction extends DialogWrapperAction { + + protected CustomOKAction() { + super("OK"); + } + + @Override + protected void doAction(ActionEvent actionEvent) { + + + ValidationInfo validationInfo = doValidate(); + if (validationInfo != null) { + LOG.info(validationInfo.message); + } else { + if (genDiag.runFun()) { + close(CANCEL_EXIT_CODE); + } + } + } + } + + /** + * 自定义 help Action + */ + protected class CustomHelpAction extends DialogWrapperAction { + + protected CustomHelpAction() { + super("Help"); + } + + @Override + protected void doAction(ActionEvent actionEvent) { + try { + Desktop.getDesktop().browse(new URI(URL)); + } catch (URISyntaxException | IOException e) { + LOG.error("Open help error:" + e); + } + } + } +} diff --git a/hdc/gn_IntelliJ_plugin/src/com/sk/gn/dialog/GenResultDialog.form b/hdc/gn_IntelliJ_plugin/src/com/sk/gn/dialog/GenResultDialog.form new file mode 100644 index 00000000..e699fec7 --- /dev/null +++ b/hdc/gn_IntelliJ_plugin/src/com/sk/gn/dialog/GenResultDialog.form @@ -0,0 +1,78 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/hdc/gn_IntelliJ_plugin/src/com/sk/gn/dialog/GenResultDialog.java b/hdc/gn_IntelliJ_plugin/src/com/sk/gn/dialog/GenResultDialog.java new file mode 100644 index 00000000..42f8eecb --- /dev/null +++ b/hdc/gn_IntelliJ_plugin/src/com/sk/gn/dialog/GenResultDialog.java @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2022 Shenzhen Kaihong Digital Industry Development 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 com.sk.gn.dialog; + +import com.intellij.openapi.diagnostic.Logger; + +import javax.swing.JButton; +import javax.swing.JDialog; +import javax.swing.JList; +import javax.swing.JPanel; +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +/** + * GenResultDialog结果生成框 + * + * @author: zhaoxudong@kaihong.com + * @see: generate success dialog + * @version: v1.0.0 + * @since 2022-02-21 + */ +public class GenResultDialog extends JDialog { + private static final Logger LOG = Logger.getInstance(GenResultDialog.class); + + private JPanel contentPane; + private JButton buttonOK; + private JList resultList; + private String path; + + public GenResultDialog(String directoryPath) { + path = directoryPath; + } + + /** + * 初始化 + */ + public void initResultDialog() { + setContentPane(contentPane); + setModal(true); + getRootPane().setDefaultButton(buttonOK); + setTitle("执行成功"); + buttonOK.addActionListener(actionEvent -> onOK()); + List fileList = getDirFileName(path); + resultList.setListData(fileList.toArray(new String[fileList.size()])); + } + + private void onOK() { + dispose(); + } + + private List getDirFileName(String path) { + List files = new ArrayList<>(); + File file = new File(path); + if (!file.exists()) { + LOG.info("getDirFileName f not exist"); + return files; + } + File[] fileArray = file.listFiles(); + for (int i = 0; i < fileArray.length; i++) { + File fs = fileArray[i]; + if (!fs.isDirectory()) { + files.add(fs.getPath()); + } else { + LOG.info("getDirFileName this file is dir"); + } + } + return files; + } +} diff --git a/hdc/gn_IntelliJ_plugin/src/com/sk/gn/ng/GnDTS.java b/hdc/gn_IntelliJ_plugin/src/com/sk/gn/ng/GnDTS.java new file mode 100644 index 00000000..ebd170b2 --- /dev/null +++ b/hdc/gn_IntelliJ_plugin/src/com/sk/gn/ng/GnDTS.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2022 Shenzhen Kaihong Digital Industry Development 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 com.sk.gn.ng; + +import com.intellij.notification.NotificationType; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.PlatformDataKeys; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.sk.gn.dialog.GenGenerateDialog; +import com.sk.gn.utils.FileUtil; +import com.sk.gn.utils.GenNotification; + +/** + * 项目文件入口 + * + * @author: zhaoxudong@kaihong.com + * @see: tool conversion plug-in + * @version: v1.0.0 + * @since 2022-09-21 + */ +public class GnDTS extends AnAction { + + @Override + public void actionPerformed(AnActionEvent anActionEvent) { + Project project = anActionEvent.getProject(); + VirtualFile file = anActionEvent.getData(PlatformDataKeys.VIRTUAL_FILE); + if (file == null) { + GenNotification.notifyMessage(project, "", "file is not exist", NotificationType.ERROR); + return; + } + if (project == null) { + return; + } + String filePath = file.getPath(); + GenGenerateDialog wrapper = new GenGenerateDialog(project, filePath); + wrapper.showAndGet(); + } + + + @Override + public void update(AnActionEvent event) { + // 根据所选文件名,判断是否显示生成菜单项 + VirtualFile file = event.getData(PlatformDataKeys.VIRTUAL_FILE); + if (file == null) { + event.getPresentation().setEnabledAndVisible(false); + } else { + event.getPresentation().setEnabledAndVisible(FileUtil.patternFileName(file.getName())); + } + } +} diff --git a/hdc/gn_IntelliJ_plugin/src/com/sk/gn/ng/GnMenuDTS.java b/hdc/gn_IntelliJ_plugin/src/com/sk/gn/ng/GnMenuDTS.java new file mode 100644 index 00000000..9e609d8f --- /dev/null +++ b/hdc/gn_IntelliJ_plugin/src/com/sk/gn/ng/GnMenuDTS.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2022 Guangzhou Digitalchina Information Technology 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 com.sk.gn.ng; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.project.Project; +import com.sk.gn.dialog.GenGenerateDialog; +import org.jetbrains.annotations.NotNull; + +/** + * 工具菜单入口 + * + * @author: zhaoxudong@kaihong.com + * @see: tool conversion plug-in + * @version: v1.0.0 + * @since 2022-09-27 + */ +public class GnMenuDTS extends AnAction { + + @Override + public void actionPerformed(@NotNull AnActionEvent anActionEvent) { + Project project = anActionEvent.getProject(); + + if (project == null) { + return; + } + GenGenerateDialog wrapper = new GenGenerateDialog(project, ""); + wrapper.showAndGet(); + } + +} diff --git a/hdc/gn_IntelliJ_plugin/src/com/sk/gn/utils/FileUtil.java b/hdc/gn_IntelliJ_plugin/src/com/sk/gn/utils/FileUtil.java new file mode 100644 index 00000000..8f771c19 --- /dev/null +++ b/hdc/gn_IntelliJ_plugin/src/com/sk/gn/utils/FileUtil.java @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2022 Shenzhen Kaihong Digital Industry Development 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 com.sk.gn.utils; + +import com.intellij.notification.NotificationType; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import org.apache.http.util.TextUtils; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; +import java.util.regex.Pattern; + +/** + * 文本文件工具 + * + * @author: zhaoxudong@kaihong.com + * @see: file utils + * @version: v1.0.0 + * @since 2022-09-21 + */ +public class FileUtil { + private static final Logger LOG = Logger.getInstance(FileUtil.class); + + private static final int COMPILE_SDK_VERSION = 5; + + /** + * 将错误信息输入到txt中 + * + * @param path 路径 + * @param content 内容 + */ + public void writeErrorToTxt(String path, String content) { + File file = new File(path); + try (FileWriter fw = new FileWriter(file, true)) { + fw.write(content + FileUtil.getNewline()); + } catch (IOException ioException) { + LOG.error("writeErrorToTxt io error" + ioException); + } + } + + /** + * 创建文件 + * + * @param path 文件路径 + * @return 文件路径 + */ + public String makeFile(String path) { + File file = new File(path); + if (!file.exists()) { + try { + boolean isCreateFile = file.createNewFile(); + if (isCreateFile) { + LOG.info(String.format("makeFile %s success", path)); + } + } catch (IOException ioException) { + LOG.error(String.format("makeFile %s error:%s", path, ioException)); + return ""; + } + } + return file.getPath(); + } + + /** + * 获取换行符 + * + * @return 换行符 + */ + public static String getNewline() { + return System.getProperty("line.separator"); + } + + /** + * 正则匹配所选文件名是否符合规范 + * + * @param fileName 文件名 + * @return boolean 是否匹配 + */ + public static boolean patternFileName(String fileName) { + String pattern = "([.a-z_A-Z0-9]+).(am|txt)"; + return Pattern.matches(pattern, fileName); + } + + /** + * check project SDK + * + * @param project project + * @param baseFile project root file + * @return boolean + */ + public static boolean checkProjectSDK(Project project, String baseFile) { + + String gradlePath = ""; + File baseDir = new File(baseFile); + if (baseDir.isDirectory()) { + File[] childFile = baseDir.listFiles(); + assert childFile != null; + for (File file : childFile) { + if (file.getName().equals("build.gradle") || file.getName().equals("build-profile.json5")) { + gradlePath = file.getPath(); + } + } + } + + Properties properties = new Properties(); + if (TextUtils.isBlank(gradlePath)) { + GenNotification.notifyMessage(project, "项目结构中没有grandle配置文件。", "当前项目结构不支持", + NotificationType.WARNING); + return true; + } + try { + properties.load(new FileInputStream(gradlePath)); + } catch (IOException e) { + GenNotification.notifyMessage(project, e.getMessage(), "提示", NotificationType.ERROR); + LOG.error(String.format("Can not load file :%s . %s", gradlePath, e)); + return true; + } + String ohosSDK = properties.getProperty("compileSdkVersion"); + + if (ohosSDK != null && Integer.parseInt(ohosSDK) < COMPILE_SDK_VERSION) { + GenNotification.notifyMessage(project, "SKD版本过低,NAPI仅支持5.0及以上版本", "提示", + NotificationType.WARNING); + return true; + } + return false; + } + + /** + * 拷贝可执行文件到临时文件夹 + * + * @param path 目标文件路径 + * @param oldPath 原文件路径 + * @param project project + * @throws IOException exception + */ + public static void writeTmpFile(String path, String oldPath, Project project) { + File file = new File(path); + try (InputStream inputStream = FileUtil.class.getClassLoader().getResourceAsStream(oldPath)) { + if (inputStream == null) { + throw new IOException("exec File InputStream is Null"); + } + byte[] bs = inputStream.readAllBytes(); + file.setWritable(true); + boolean isNewFile = file.createNewFile(); + if (!isNewFile) { + LOG.info("writeTmpFile createNewFile error"); + } + FileOutputStream fw = new FileOutputStream(file); + fw.write(bs, 0, bs.length); + fw.close(); + } catch (IOException e) { + GenNotification.notifyMessage(project, e.getMessage(), "Can not Find File:" + oldPath, + NotificationType.ERROR); + LOG.error(e); + } + } +} diff --git a/hdc/gn_IntelliJ_plugin/src/com/sk/gn/utils/GenNotification.java b/hdc/gn_IntelliJ_plugin/src/com/sk/gn/utils/GenNotification.java new file mode 100644 index 00000000..5281519d --- /dev/null +++ b/hdc/gn_IntelliJ_plugin/src/com/sk/gn/utils/GenNotification.java @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2022 Guangzhou Digitalchina Information Technology 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 com.sk.gn.utils; + +import com.intellij.ide.actions.OpenFileAction; +import com.intellij.notification.Notification; +import com.intellij.notification.NotificationAction; +import com.intellij.notification.NotificationType; +import com.intellij.notification.Notifications; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import org.jetbrains.annotations.NotNull; + +import java.io.File; + +/** + * 通知框 + * + * @author: zhaoxudong@kaihong.com + * @see: tool conversion plug-in + * @version: v1.0.0 + * @since 2022-09-27 + */ +public class GenNotification { + + private static final Logger LOG = Logger.getInstance(FileUtil.class); + + private GenNotification() { + } + + /** + * 无action 通知 + * + * @param project projectid + * @param content 提示内容 + * @param title 提示栏内容 + * @param type 提示类型 Error,Waring,info + */ + public static void notifyMessage(@javax.annotation.Nullable Project project, String content, String title, + NotificationType type) { + notifyMessage(project, content, title, type, false); + } + + /** + * 消息通知 + * + * @param project projectid + * @param content 提示内容 + * @param title 提示栏内容 + * @param type 提示类型 Error,Waring,info + * @param addAct 是否添加action + */ + public static void notifyMessage(@javax.annotation.Nullable Project project, String content, String title, + NotificationType type, boolean addAct) { + + Notification notification = new Notification("Generate.Result.Group", "Notes Message", content, type); + notification.setTitle(title); + notification.setContent(content); + + if (NotificationType.ERROR.equals(type)) { + LOG.error(content); + } else if (NotificationType.WARNING.equals(type)) { + LOG.warn(content); + } else { + LOG.info(content); + } + + if (addAct) { + notification.setContent(null); + addAction(project, content, notification); + } + Notifications.Bus.notify(notification, project); + + } + + private static void addAction(Project project, String dirPath, Notification notification) { + File genResultPath = new File(dirPath); + if (!genResultPath.exists()) { + LOG.info(String.format("%s not exist", genResultPath.getPath())); + } + LOG.info("generated file list log:"); + + File[] fa = genResultPath.listFiles(); + for (int i = 0; i < fa.length; i++) { + File fs = fa[i]; + String fileName = fs.getName(); + boolean dissFile = !fileName.endsWith(".log") || !fileName.endsWith(".txt") || !fileName.endsWith(".ts"); + if (!fs.isDirectory() && dissFile) { + String filePath = fs.getPath(); + NotificationAction action = new NotificationAction(filePath) { + @Override + public void actionPerformed(@NotNull AnActionEvent anActionEvent, + @NotNull Notification notification) { + OpenFileAction.openFile(filePath, project); + } + }; + notification.addAction(action); + } else { + LOG.info(String.format("%s is Directory", fs.getPath())); + } + } + } +} -- Gitee