feat: modified notification mode

fix #I51B1C

Signed-off-by: “lengege” <liulongc@digitalchina.com>
This commit is contained in:
“lengege” 2022-05-23 14:50:04 +08:00 committed by lengege
parent fb379c6e5d
commit e4ded4ab2b
21 changed files with 1188 additions and 504 deletions

7
.gitignore vendored
View File

@ -1,4 +1,5 @@
*.iml
.gitignore
.gradle
/local.properties
/.idea/caches
@ -16,3 +17,9 @@
/node_modules
/src/node_modules
/src/gen/ttt.js
/src/generator/generator.jar
/src/generator/out/
/src/generator/resources/cmds/linux/napi_generator-linux
/src/generator/resources/cmds/mac/napi_generator-macos
/src/generator/resources/cmds/win/napi_generator-win.exe
/src/generator/.idea/

View File

@ -57,6 +57,7 @@ Note:If the text contains special characters, please escape them according to th
<policylist>
<policy name="projectPolicy" desc="">
<policyitem type="copyright" name="Copyright (c) 2022 Shenzhen Kaihong Digital" path=".*" rule="may" group="defaultGroup" filefilter="copyrightPolicyFilter" desc=""/>
<policyitem type="copyright" name="Copyright (c) 2022 Guangzhou Digitalchina Information Technology Co., Ltd." path=".*" desc=""/>
</policy>
</policylist>
<filefilterlist>

View File

@ -5,9 +5,21 @@
<vendor email="support@yourcompany.com" url="http://www.yourcompany.com">YourCompany</vendor>
<description><![CDATA[
Enter short description for your plugin here.<br>
<em>most HTML tags may be used</em>
]]></description>
<h2>Introduction</h2>
<p>&nbsp;&nbsp;&nbsp;&nbsp;One-click generation of NAPI framework code, business code framework, GN file, etc. according to the ts (typescript) interface file in the user-specified path.<br/></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;When developing the interface between JS applications and NAPI, the developers of the underlying framework do not need to pay attention to the upper-level application conversion logic such as Nodejs syntax, data type conversion between C++ and JS, and only focus on the underlying business logic. Professional people do professional things. Thus, the development efficiency can be greatly improved</p>
<p><a href="https://gitee.com/openharmony/napi_generator">Sources on Gitee</a></p>
<!-- <h2>Features</h2>-->
<!-- <ol>-->
<!-- <li>✔ Repository browser in a tool window named 'generator'</li>-->
<!-- <li>✔ .</li>-->
<!-- <li>✔ </li>-->
<!-- <li>✔ .</li>-->
<!-- </ol>-->
]]>
</description>
<change-notes><![CDATA[
Add change notes here.<br>
@ -24,6 +36,8 @@
<extensions defaultExtensionNs="com.intellij">
<!-- Add your extensions here -->
<!-- <notificationGroup displayType="BALLOON" id="Generate.Result.Group"/>-->
<!-- <toolWindow id="Generator window" anchor="right" factoryClass="com.sk.dialog.ResutlToolWindowFactory" secondary="true"/>-->
</extensions>
<actions>
@ -31,6 +45,16 @@
<action id="NapiGenerate.gen" class="com.sk.ng.GenDTS" text="Generate Napi Frame" description="generate napi files">
<add-to-group group-id="ProjectViewPopupMenu" anchor="first"/>
</action>
<group id="NapiGenerate.meneGen" text="Generate Napi" >
<add-to-group group-id="ToolsMenu" anchor="last" />
</group>
<action class="com.sk.ng.GenMenuDTS" id="toolsGen" text="Generate Napi Frame">
<add-to-group group-id="NapiGenerate.meneGen" anchor="last" />
<keyboard-shortcut keymap="$default" first-keystroke="shift alt G"/>
</action>
</actions>
</idea-plugin>

Binary file not shown.

After

Width:  |  Height:  |  Size: 176 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 B

View File

@ -14,32 +14,55 @@
*/
package com.sk.action;
import com.intellij.notification.NotificationType;
import com.intellij.openapi.project.Project;
import com.sk.utils.FileUtil;
import com.sk.utils.GenNotification;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JTextField;
import javax.swing.JFileChooser;
import javax.swing.filechooser.FileNameExtensionFilter;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.prefs.Preferences;
/**
* 接口文件选择框
*
* @author: xudong
* @see: select file
* @version: v1.0.0
* @since 2022/02/21
* @since 2022-02-21
*/
public class BrowseAction implements ActionListener {
private JButton button;
private JTextField textField;
private JTextField interField;
private JTextField genField;
private JTextField scriptField;
private Project project;
public BrowseAction(JButton button, JTextField textField) {
public BrowseAction(Project project, JButton button, JTextField interField,
JTextField geField, JTextField scriptField) {
this.project = project;
this.button = button;
this.textField = textField;
this.interField = interField;
this.genField = geField;
this.scriptField = scriptField;
}
@Override
public void actionPerformed(ActionEvent actionEvent) {
if (actionEvent.getSource().equals(button)) {
Preferences preferences = Preferences.userRoot();
JFileChooser fcDlg = new JFileChooser();
String pathRecord = preferences.get("interPathRecord", "");
if (!pathRecord.equals("")) {
fcDlg = new JFileChooser(pathRecord);
}
fcDlg.setDialogTitle("请选择接口文件...");
fcDlg.setFileSelectionMode(JFileChooser.FILES_ONLY);
FileNameExtensionFilter filter = new FileNameExtensionFilter("文本文件(*.ts)", "ts");
@ -47,7 +70,20 @@ public class BrowseAction implements ActionListener {
int returnVal = fcDlg.showOpenDialog(null);
if (returnVal == JFileChooser.APPROVE_OPTION) {
String filepath = fcDlg.getSelectedFile().getPath();
textField.setText(filepath);
String filename = fcDlg.getSelectedFile().getName();
if (!FileUtil.patternFileName(filename)) {
GenNotification.notifyMessage(project,
"当前文件名不符合转换规则!",
"提示",
NotificationType.WARNING);
return;
}
String upPath = fcDlg.getSelectedFile().getParent();
preferences.put("interPathRecord", filepath);
interField.setText(filepath);
genField.setText(upPath);
scriptField.setText(upPath);
}
}
}

View File

@ -21,10 +21,12 @@ import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/**
* 编译文件夹选择框
*
* @author: xudong
* @see: select generator file path
* @version: v1.0.0
* @since 2022/02/21
* @since 2022-02-21
*/
public class GenAction implements ActionListener {
private JButton button;

View File

@ -21,10 +21,12 @@ import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/**
* 脚本选择对话框
*
* @author: xudong
* @see: select compile script
* @version: v1.0.0
* @since 2022/02/21
* @since 2022-02-21
*/
public class ScriptAction implements ActionListener {
private JButton button;

View File

@ -0,0 +1,61 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.sk.dialog.ConfirmDiagPane">
<grid id="cbd77" binding="contentPane" layout-manager="GridLayoutManager" row-count="2" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="10" left="10" bottom="10" right="10"/>
<constraints>
<xy x="48" y="54" width="312" height="85"/>
</constraints>
<properties>
<preferredSize width="315" height="85"/>
</properties>
<border type="none"/>
<children>
<grid id="4c5dc" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="55ae4" class="javax.swing.JLabel" binding="msgLabel">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value=""/>
</properties>
</component>
</children>
</grid>
<grid id="e1e12" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false">
<preferred-size width="30" height="30"/>
<maximum-size width="30" height="30"/>
</grid>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="d0454" class="javax.swing.JLabel" binding="iconLabel">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false">
<preferred-size width="30" height="30"/>
</grid>
</constraints>
<properties>
<text value=""/>
</properties>
</component>
</children>
</grid>
<hspacer id="ef134">
<constraints>
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
</hspacer>
</children>
</grid>
</form>

View File

@ -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.dialog;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JDialog;
import javax.swing.ImageIcon;
/**
* ConfirmDiagPane自定义确认对话框
* 解决ShowConfirmDiag 在Deveco里面会出现界面错位问题
*
* @author: xudong
* @see: generator error dialog
* @version: v1.0.0
* @since 2022-02-21
*/
public class ConfirmDiagPane extends JDialog {
private JPanel contentPane;
private JLabel msgLabel;
private JLabel iconLabel;
/**
* 构造函数
*
* @param sErrorMessage 错误信息
*/
public ConfirmDiagPane(String sErrorMessage) {
msgLabel.setText(sErrorMessage);
iconLabel.setIcon(new ImageIcon(""));
}
JPanel getContentPanel() {
return contentPane;
}
}

View File

@ -0,0 +1,53 @@
/*
* 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.dialog;
import com.intellij.openapi.ui.DialogWrapper;
import org.jetbrains.annotations.Nullable;
import javax.swing.JComponent;
/**
* 自定义确认对话框Wrapper
*
* @author: liulongc digitalchina.com
* @see: tool conversion plug-in
* @version: v1.0.0
* @since 2022-02-21
*/
public class ConfirmDialog extends DialogWrapper {
private ConfirmDiagPane confirmDiagPane;
/**
* 构造函数
* @param message 弹出框信息内容
*/
public ConfirmDialog(String message) {
super(true);
confirmDiagPane = new ConfirmDiagPane(message);
setOKButtonText("Yes");
setCancelButtonText("No");
setUndecorated(true);
setResizable(false);
init();
}
@Override
@Nullable
protected JComponent createCenterPanel() {
return confirmDiagPane.getContentPanel();
}
}

View File

@ -28,10 +28,12 @@ import java.awt.event.WindowEvent;
import java.io.IOException;
/**
* ErrorDialog错误对话框
*
* @author: xudong
* @see: generator error dialog
* @version: v1.0.0
* @since 2022/02/21
* @since 2022-02-21
*/
public class ErrorDialog extends JDialog {
private static final Logger LOG = Logger.getInstance(ErrorDialog.class);
@ -92,4 +94,4 @@ public class ErrorDialog extends JDialog {
}
dispose();
}
}
}

View File

@ -25,10 +25,12 @@ import java.util.ArrayList;
import java.util.List;
/**
* GenResultDialog结果生成框
*
* @author: xudong
* @see: generate success dialog
* @version: v1.0.0
* @since 2022/02/21
* @since 2022-02-21
*/
public class GenResultDialog extends JDialog {
private static final Logger LOG = Logger.getInstance(GenResultDialog.class);

View File

@ -1,141 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.sk.dialog.GenerateDialog">
<grid id="cbd77" binding="contentPane" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="10" left="10" bottom="10" right="10"/>
<constraints>
<xy x="48" y="54" width="436" height="297"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<grid id="94766" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="1" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<grid id="9538f" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="true" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="e7465" class="javax.swing.JButton" binding="buttonOK">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="OK"/>
</properties>
</component>
<component id="5723f" class="javax.swing.JButton" binding="buttonCancel">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Cancel"/>
</properties>
</component>
</children>
</grid>
<component id="d156d" class="javax.swing.JButton" binding="buttonHelp">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Help"/>
</properties>
</component>
</children>
</grid>
<grid id="e3588" layout-manager="GridLayoutManager" row-count="4" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none">
<font name="Consolas"/>
</border>
<children>
<component id="4b48d" class="javax.swing.JButton" binding="btnGenPath">
<constraints>
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="生成框架路径:"/>
</properties>
</component>
<component id="4acb7" class="javax.swing.JButton" binding="btnSelectScript">
<constraints>
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="编译脚本路径:"/>
</properties>
</component>
<component id="f3f81" class="javax.swing.JTextField" binding="textField3" default-binding="true">
<constraints>
<grid row="3" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
<preferred-size width="150" height="-1"/>
</grid>
</constraints>
<properties/>
</component>
<component id="ba40a" class="javax.swing.JButton" binding="btnSelectInter">
<constraints>
<grid row="0" column="0" row-span="2" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="接口文件:"/>
</properties>
</component>
<component id="d9d6" class="javax.swing.JTextField" binding="textField2">
<constraints>
<grid row="2" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
<preferred-size width="150" height="-1"/>
</grid>
</constraints>
<properties/>
</component>
<component id="b2411" class="javax.swing.JTextField" binding="textField1" default-binding="true">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
<preferred-size width="150" height="-1"/>
</grid>
</constraints>
<properties/>
</component>
<component id="610fd" class="javax.swing.JButton" binding="selectInter">
<constraints>
<grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="选择"/>
</properties>
</component>
<component id="f1fbc" class="javax.swing.JButton" binding="selectGenPath">
<constraints>
<grid row="2" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="选择"/>
</properties>
</component>
<component id="fa1ba" class="javax.swing.JButton" binding="select">
<constraints>
<grid row="3" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="选择"/>
</properties>
</component>
</children>
</grid>
</children>
</grid>
</form>

View File

@ -1,10 +1,11 @@
/*
* Copyright (c) 2022 Shenzhen Kaihong Digital Industry Development Co., Ltd.
* 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
* 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,
@ -15,362 +16,140 @@
package com.sk.dialog;
import com.intellij.openapi.diagnostic.Logger;
import com.sk.action.BrowseAction;
import com.sk.action.GenAction;
import com.sk.action.ScriptAction;
import com.sk.utils.FileUtil;
import org.apache.http.util.TextUtils;
import javax.swing.JButton;
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.JComponent;
import javax.swing.JDialog;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import java.awt.event.ComponentAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import javax.swing.Action;
import java.awt.Desktop;
import java.awt.event.ActionEvent;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.net.URI;
import java.net.URISyntaxException;
/**
* @author: xudong
* @see: select generate dialog
* 主界面对话框Wrapper
*
* @author: liulongc digitalchina.com
* @see: tool conversion plug-in
* @version: v1.0.0
* @since 2022/02/21
* @since 2022-05-27
*/
public class GenerateDialog extends JDialog {
public class GenerateDialog extends DialogWrapper {
private static final Logger LOG = Logger.getInstance(GenerateDialog.class);
private static final String TITLE = "Generate Napi Frame";
private static final String URL =
"rundll32 url.dll,FileProtocolHandler" + " https://gitee" + ".com/openharmony" + "-sig/napi_generator";
private static final String COMMAND_STATEMENT = "add_library(napitest SHARED x_napi_tool.cpp napitest.cpp "
+ "napitest_middle.cpp)" + FileUtil.getNewline() + "target_link_libraries(napitest libace_napi.z.so)";
private static final String REGEX = "napitest";
private static final Pattern LF_PATTERN = Pattern.compile(REGEX, Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
private static final String URL = "https://gitee.com/openharmony/napi_generator";
private JPanel contentPane;
private JButton buttonOK;
private JButton buttonCancel;
private JButton btnGenPath;
private JButton btnSelectScript;
private JTextField textField1;
private JTextField textField2;
private JTextField textField3;
private JButton btnSelectInter;
private JButton selectInter;
private JButton selectGenPath;
private JButton select;
private JButton buttonHelp;
private boolean generateSuccess = true;
private String sErrorMessage = "";
private String destPath;
private String directoryPath;
private String fileName;
private GenerateDialogPane genDiag;
private DialogWrapperExitAction exitAction;
private CustomOKAction okAction;
private CustomHelpAction helpAction;
/**
* 构造函数
*
* @param destPath 接口文件路径
* @param directoryPath 生成框架文件路径
* @param fileName 文件名
* @param project projectid
* @param destPath 目录文件
* @param directoryPath 文件夹目录
* @param fileName 文件名
*/
public GenerateDialog(String destPath, String directoryPath, String fileName) {
this.destPath = destPath;
this.directoryPath = directoryPath;
this.fileName = fileName;
public GenerateDialog(Project project, String destPath, String directoryPath, String fileName) {
super(true);
this.setResizable(false);
setTitle(TITLE);
setModal(true);
genDiag = new GenerateDialogPane(project, destPath, directoryPath, fileName);
init();
}
/**
* 初始化对话框
* 创建视图
*
* @return 组件内容
*/
public void initDialog() {
initData();
setContentPane(contentPane);
setModal(true);
setTitle(TITLE);
getRootPane().setDefaultButton(buttonOK);
btnGenPath.setText("生成框架路径:");
btnSelectScript.setText("编译脚本路径:");
btnSelectInter.setText("接口文件:");
buttonOK.addActionListener(actionEvent -> onOK());
buttonCancel.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);
selectInter.addActionListener(new BrowseAction(selectInter, textField1));
selectGenPath.addActionListener(new GenAction(selectGenPath, textField2));
select.addActionListener(new ScriptAction(select, textField3));
buttonHelp.addComponentListener(new ComponentAdapter() {
});
buttonHelp.addActionListener(actionEvent -> onHelp());
@Nullable
@Override
protected JComponent createCenterPanel() {
return genDiag.getContentPanel();
}
private void onHelp() {
try {
Runtime.getRuntime().exec(URL);
} catch (IOException ioException) {
LOG.error("exec command help error" + ioException);
}
dispose();
/**
* 校验数据
*
* @return 检测文本框架是否有目录
*/
@Nullable
@Override
protected ValidationInfo doValidate() {
return genDiag.validationInfo();
}
private void initData() {
textField1.setText(destPath);
textField2.setText(directoryPath);
textField3.setText(directoryPath);
/**
* ok/cancel按钮
*
* @return Action[] buttos list
*/
@NotNull
@Override
protected Action[] createActions() {
exitAction = new DialogWrapperExitAction("Cancel", CANCEL_EXIT_CODE);
okAction = new CustomOKAction();
// 设置默认的焦点按钮
okAction.putValue(DialogWrapper.DEFAULT_ACTION, true);
return new Action[]{exitAction, okAction};
}
private void onOK() {
if (TextUtils.isEmpty(textField1.getText())) {
warningMessage("请选择接口文件");
return;
}
if (TextUtils.isEmpty(textField2.getText())) {
warningMessage("请选择保存框架路径");
return;
}
if (TextUtils.isEmpty(textField3.getText())) {
warningMessage("请选择编译脚本路径");
return;
}
runFun(textField1.getText(), textField2.getText());
dispose();
@NotNull
@Override
protected Action[] createLeftSideActions() {
helpAction = new CustomHelpAction();
return new Action[]{helpAction};
}
private void onCancel() {
dispose();
}
/**
* 自定义 ok Action
*/
protected class CustomOKAction extends DialogWrapperAction {
private void warningMessage(String message) {
JOptionPane.showMessageDialog(null, message, "提示", JOptionPane.WARNING_MESSAGE);
}
private void runFun(String destPath, String parentPath) {
String sysName = System.getProperties().getProperty("os.name").toUpperCase();
String executeProgram;
if (sysName.indexOf("WIN") >= 0) {
executeProgram = "cmds/win/napi_generator-win.exe";
} else if (sysName.indexOf("LINUX") >= 0) {
executeProgram = "cmds/linux/napi_generator-linux";
} else {
executeProgram = "cmds/linux/napi_generator-mac";
}
try (InputStream inputStream = getClass().getClassLoader().getResourceAsStream(executeProgram)) {
String command = genCommand(inputStream, destPath, parentPath);
callExtProcess(command);
} catch (IOException ioException) {
LOG.error("exec command error" + ioException);
} catch (InterruptedException exception) {
LOG.warn("exec command Interrupted" + exception);
Thread.currentThread().interrupt();
}
}
private String genCommand(InputStream inputStream, String destPath, String parentPath) {
String sysName = System.getProperties().getProperty("os.name").toUpperCase();
String tmpDir = System.getProperty("java.io.tmpdir");
String execFn = tmpDir + "/napi_generator.exe";
if (sysName.indexOf("LINUX") >= 0) {
executable(execFn);
}
File file = new File(execFn);
if (!file.exists()) {
try {
byte[] bs = inputStream.readAllBytes();
writeTmpFile(execFn, bs);
} catch (IOException ioException) {
LOG.error("runFun WIN write_tmp_file io error" + ioException);
}
}
return file + " " + "-f" + " " + destPath + " " + "-o" + " " + parentPath;
}
private void callExtProcess(String command) throws IOException, InterruptedException {
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) {
LOG.error(" callExtProcess process.waitFor() != 0");
promptDialog();
} else {
promptDialog();
writeCommand();
}
errConsumer.join();
outputConsumer.join();
}
private void writeCommand() {
FileUtil fileUtil = new FileUtil();
String filePath = fileUtil.makeFile(directoryPath + "/makeFile.txt");
if (TextUtils.isEmpty(filePath)) {
LOG.error("makeFile is error");
return;
}
Matcher matcher = LF_PATTERN.matcher(COMMAND_STATEMENT);
String statement = matcher.replaceAll(fileName);
try {
if (!fileUtil.findStringInFile(filePath, statement)) {
fileUtil.writeErrorToTxt(filePath, statement);
}
} catch (IOException ioException) {
LOG.error("writeCommand io error" + ioException);
}
}
private void executable(String execFn) {
try {
callExtProcess("chmod a+x " + execFn);
} catch (IOException ioException) {
LOG.warn("LINUX IOException error" + ioException);
} catch (InterruptedException exception) {
LOG.warn("exec chmod command Interrupted" + exception);
Thread.currentThread().interrupt();
}
}
private void writeTmpFile(String path, byte[] bs) throws IOException {
File file = new File(path);
if (!file.exists()) {
boolean isNewFile = file.createNewFile();
if (!isNewFile) {
LOG.info("writeTmpFile createNewFile error");
}
}
try (FileOutputStream fw = new FileOutputStream(file)) {
fw.write(bs, 0, bs.length);
} catch (IOException ioException) {
LOG.error("writeTmpFile io error" + ioException);
}
}
private void promptDialog() {
if (generateSuccess) {
GenResultDialog genResultDialog = new GenResultDialog(directoryPath);
genResultDialog.initResultDialog();
setMethod(genResultDialog);
} else {
ErrorDialog errorDialog = new ErrorDialog(sErrorMessage);
errorDialog.initDialog();
setMethod(errorDialog);
}
}
private void setMethod(JDialog dialog) {
dialog.setLocationRelativeTo(dialog);
dialog.pack();
dialog.setVisible(true);
}
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;
}
private String getErrorResult(BufferedReader stdError) {
String sErr = "";
while (true) {
String sTmp;
try {
if ((sTmp = stdError.readLine()) == null) {
break;
}
sErr += sTmp + FileUtil.getNewline();
} catch (IOException ioException) {
LOG.error(" genResultLog stdInput error" + ioException);
}
}
return sErr;
}
private boolean generateIsSuccess(String sOut) {
if (!TextUtils.isEmpty(sOut) && sOut.indexOf("success") >= 0) {
generateSuccess = true;
} else {
generateSuccess = false;
}
return generateSuccess;
}
private String genInputLog(BufferedReader stdInput) {
String sOut = "";
while (true) {
String sTmp;
try {
if ((sTmp = stdInput.readLine()) == null) {
break;
}
sOut += sTmp + FileUtil.getNewline();
} catch (IOException ioException) {
LOG.error(" genResultLog stdInput error" + ioException);
}
}
return sOut;
}
class StreamConsumer extends Thread {
InputStream is;
StreamConsumer(InputStream is) {
super.setName("StreamConsumer");
this.is = is;
protected CustomOKAction() {
super("OK");
}
@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);
protected void doAction(ActionEvent actionEvent) {
ValidationInfo validationInfo = doValidate();
if (validationInfo != null) {
LOG.info(validationInfo.message);
} else {
if (genDiag.runFun()) {
close(CANCEL_EXIT_CODE);
}
} catch (IOException ioException) {
LOG.error("StreamConsumer io error" + ioException);
}
}
}
/**
* 自定义 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);
}
}
}

View File

@ -0,0 +1,157 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.sk.dialog.GenerateDialogPane">
<grid id="cbd77" binding="contentPane" layout-manager="GridLayoutManager" row-count="4" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="0">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="48" y="54" width="540" height="123"/>
</constraints>
<properties>
<enabled value="false"/>
<focusCycleRoot value="false"/>
<focusTraversalPolicyProvider value="false"/>
<maximumSize width="-1" height="-1"/>
<minimumSize width="-1" height="-1"/>
<preferredSize width="530" height="125"/>
<requestFocusEnabled value="true"/>
</properties>
<border type="none"/>
<children>
<grid id="64844" layout-manager="FlowLayout" hgap="-1" vgap="-1" flow-align="0">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="b2411" class="javax.swing.JTextField" binding="interPath">
<constraints/>
<properties>
<margin top="2" left="6" bottom="2" right="6"/>
<maximumSize width="500" height="30"/>
<minimumSize width="300" height="30"/>
<preferredSize width="400" height="30"/>
</properties>
</component>
<component id="610fd" class="javax.swing.JButton" binding="selectInter">
<constraints/>
<properties>
<icon value="images/text.png"/>
<inheritsPopupMenu value="false"/>
<maximumSize width="30" height="30"/>
<minimumSize width="30" height="30"/>
<preferredSize width="30" height="30"/>
<text value=""/>
<toolTipText value="选择接口文件"/>
</properties>
</component>
</children>
</grid>
<grid id="fcb65" layout-manager="FlowLayout" hgap="-1" vgap="-1" flow-align="0">
<constraints>
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="c4c1b" class="javax.swing.JTextField" binding="genPath">
<constraints/>
<properties>
<maximumSize width="500" height="30"/>
<minimumSize width="300" height="30"/>
<preferredSize width="400" height="30"/>
</properties>
</component>
<component id="f1fbc" class="javax.swing.JButton" binding="selectGenPath">
<constraints/>
<properties>
<icon value="images/openDisk.png"/>
<maximumSize width="30" height="30"/>
<minimumSize width="30" height="30"/>
<preferredSize width="30" height="30"/>
<selected value="true"/>
<text value=""/>
<toolTipText value="选择框架生成保存路径"/>
</properties>
</component>
</children>
</grid>
<grid id="6fb92" layout-manager="FlowLayout" hgap="-1" vgap="-1" flow-align="0">
<constraints>
<grid row="2" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<doubleBuffered value="false"/>
<enabled value="true"/>
</properties>
<border type="none"/>
<children>
<component id="7194f" class="javax.swing.JTextField" binding="scriptPath">
<constraints/>
<properties>
<maximumSize width="500" height="30"/>
<minimumSize width="300" height="30"/>
<preferredSize width="400" height="30"/>
<requestFocusEnabled value="true"/>
<text value=""/>
</properties>
</component>
<component id="b9580" class="javax.swing.JButton" binding="selectScriptPath">
<constraints/>
<properties>
<horizontalAlignment value="0"/>
<horizontalTextPosition value="11"/>
<icon value="images/openDisk.png"/>
<maximumSize width="30" height="30"/>
<minimumSize width="30" height="30"/>
<preferredSize width="30" height="30"/>
<requestFocusEnabled value="true"/>
<rolloverEnabled value="false"/>
<selected value="true"/>
<text value=""/>
<toolTipText value="选择编译脚本保存路径"/>
</properties>
</component>
</children>
</grid>
<component id="415a9" class="javax.swing.JLabel" binding="scriptText">
<constraints>
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<maximumSize width="91" height="18"/>
<minimumSize width="91" height="18"/>
<opaque value="true"/>
<preferredSize width="91" height="18"/>
<text value="编译脚本路径:"/>
</properties>
</component>
<component id="3661f" class="javax.swing.JLabel" binding="genText">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<maximumSize width="91" height="18"/>
<minimumSize width="91" height="18"/>
<preferredSize width="91" height="18"/>
<text value="生成框架路径:"/>
</properties>
</component>
<component id="502f" class="javax.swing.JLabel" binding="interText">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<maximumSize width="91" height="18"/>
<minimumSize width="91" height="18"/>
<preferredSize width="91" height="18"/>
<text value="接口文件:"/>
</properties>
</component>
<hspacer id="f0139">
<constraints>
<grid row="3" column="1" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
</hspacer>
</children>
</grid>
</form>

View File

@ -0,0 +1,418 @@
/*
* 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.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.action.BrowseAction;
import com.sk.action.GenAction;
import com.sk.action.ScriptAction;
import com.sk.utils.FileUtil;
import com.sk.utils.GenNotification;
import org.apache.http.util.TextUtils;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.JLabel;
import javax.swing.JButton;
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.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* GenerateDialogPane生成工具主界面
*
* @author: xudong
* @see: select generate dialog
* @version: v1.0.0
* @since 2022-02-21
*/
public class GenerateDialogPane extends JDialog {
private static final Logger LOG = Logger.getInstance(GenerateDialogPane.class);
private static final String COMMAND_STATEMENT = "add_library(napitest SHARED x_napi_tool.cpp napitest.cpp "
+ "napitest_middle.cpp)" + FileUtil.getNewline() + "target_link_libraries(napitest libace_napi.z.so)";
private static final String REGEX = "napitest";
private static final Pattern LF_PATTERN = Pattern.compile(REGEX, Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
private JPanel contentPane;
private JTextField interPath;
private JTextField genPath;
private JTextField scriptPath;
private JButton selectInter;
private JButton selectGenPath;
private JButton selectScriptPath;
private JLabel genText;
private JLabel scriptText;
private JLabel interText;
private boolean generateSuccess = true;
private String sErrorMessage = "";
private String destPath;
private String directoryPath;
private String fileName;
private Project project;
/**
* 构造函数
* @param project projectid
* @param interFilePath 接口文件路径
* @param genDir 生成框架文件路径
* @param scriptDir 脚本目录
*/
public GenerateDialogPane(Project project, String interFilePath, String genDir, String scriptDir) {
this.project = project;
this.destPath = interFilePath;
this.directoryPath = genDir;
this.fileName = scriptDir;
interText.setText("接口文件:");
genText.setText("生成框架路径:");
scriptText.setText("编译脚本路径:");
interPath.setText(destPath);
genPath.setText(directoryPath);
scriptPath.setText(directoryPath);
// call onCancel() on ESCAPE
contentPane.registerKeyboardAction(actionEvent -> onCancel(), KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0),
JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
selectInter.addActionListener(new BrowseAction(project, selectInter, interPath, genPath, scriptPath));
selectGenPath.addActionListener(new GenAction(selectGenPath, genPath));
selectScriptPath.addActionListener(new ScriptAction(selectScriptPath, scriptPath));
}
@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 返回不符要求的信息
*/
public ValidationInfo validationInfo() {
String fileInter = interPath.getText();
String scriptDir = scriptPath.getText();
String filegypDir = genPath.getText();
boolean isEmptyFile = TextUtils.isEmpty(fileInter)
|| TextUtils.isEmpty(scriptDir)
|| TextUtils.isEmpty(filegypDir);
ValidationInfo validationInfo = new ValidationInfo(null);
if (isEmptyFile) {
String warnMsg = "接口文件、框架、编译脚本路径不能为空";
warningMessage("Please input interface,gen and gyp file directory", warnMsg);
validationInfo = new ValidationInfo(warnMsg);
return validationInfo;
}
File file = new File(filegypDir + "/binding.gyp");
if (file.exists()) {
ConfirmDialog confirmDialog = new ConfirmDialog("是否替换已存在的编译脚本?");
if (!confirmDialog.showAndGet()) {
validationInfo = new ValidationInfo(String.format("不替换现有编译脚本:%s", file));
return validationInfo;
}
}
return validationInfo;
}
private void onCancel() {
dispose();
}
private void warningMessage(String message, String title) {
GenNotification.notifyMessage(this.project, message, title, NotificationType.WARNING);
}
/**
* 执行主程序入口
*
* @return 执行状态
* @throws IOException 文件打开
*/
public boolean runFun() {
GenNotification.notifyMessage(this.project, "", "正在生成", NotificationType.INFORMATION);
destPath = interPath.getText();
String parentPath = genPath.getText();
String command;
command = genCommand(destPath, parentPath);
try {
if (!TextUtils.isEmpty(command) && callExtProcess(command)) {
GenNotification.notifyMessage(project, directoryPath, "提示", NotificationType.INFORMATION, true);
return true;
}
} catch (IOException | InterruptedException ex) {
GenNotification.notifyMessage(project, directoryPath, "Command exec error", NotificationType.ERROR);
LOG.error(ex);
}
return false;
}
/**
* 生成命令行指令
*
* @param destPath 目标文件
* @param parentPath 父目录文件
* @return 返回命令行执行内容
*/
private String genCommand(String destPath, String parentPath) {
String sysName = System.getProperties().getProperty("os.name").toUpperCase();
String tmpDirFile = System.getProperty("java.io.tmpdir");
String execFn;
if (sysName.indexOf("WIN") >= 0) {
execFn = "cmds/win/napi_generator-win.exe";
tmpDirFile += "napi_generator-win.exe";
} else if (sysName.indexOf("LINUX") >= 0) {
execFn = "cmds/linux/napi_generator-linux";
tmpDirFile += "napi_generator-linux";
} else {
execFn = "cmds/mac/napi_generator-macos";
tmpDirFile += "napi_generator-macos";
}
;
File file = new File(tmpDirFile);
if (!file.exists()) {
try (InputStream inputStream = getClass().getClassLoader().getResourceAsStream(execFn)) {
if (inputStream == null) {
return "";
}
byte[] bs = inputStream.readAllBytes();
writeTmpFile(tmpDirFile, bs);
if (sysName.indexOf("LINUX") >= 0 || sysName.indexOf("MAC OS") >= 0) {
executable(tmpDirFile);
}
} catch (IOException | InterruptedException e) {
GenNotification.notifyMessage(this.project, e.getMessage(), "Can not Find File:" + execFn,
NotificationType.ERROR);
LOG.error(e);
return "";
}
}
return file + " " + "-f" + " " + destPath + " " + "-o" + " " + parentPath;
}
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) {
writeCommand();
} else {
GenNotification.notifyMessage(project, sErrorMessage, "提示", NotificationType.ERROR);
return false;
}
errConsumer.join();
outputConsumer.join();
return true;
}
/**
* 写makeFile.txt文件
*
* @throws IOException 文件异常
*/
private void writeCommand() {
FileUtil fileUtil = new FileUtil();
String filePath = fileUtil.makeFile(directoryPath + "/makeFile.txt");
if (TextUtils.isEmpty(filePath)) {
LOG.error("makeFile is error");
return;
}
Matcher matcher = LF_PATTERN.matcher(COMMAND_STATEMENT);
String statement = matcher.replaceAll(fileName);
try {
if (!fileUtil.findStringInFile(filePath, statement)) {
fileUtil.writeErrorToTxt(filePath, statement);
}
} catch (IOException ioException) {
LOG.error("writeCommand io error" + ioException);
}
}
/**
* 赋值可执行文件权限
*
* @param execFn 可执行命令
* @throws IOException 打开文件异常
* @throws InterruptedException 中断异常
*/
private void executable(String execFn) throws IOException, InterruptedException {
callExtProcess("chmod a+x " + execFn);
}
/**
* 拷贝可执行文件到临时文件夹
*
* @param path 目标文件路径
* @param bs 字节内容
* @throws IOException exception
*/
private void writeTmpFile(String path, byte[] bs) throws IOException {
File file = new File(path);
if (!file.exists()) {
boolean isNewFile = file.createNewFile();
if (!isNewFile) {
LOG.info("writeTmpFile createNewFile error");
}
}
FileOutputStream fw = new FileOutputStream(file);
fw.write(bs, 0, bs.length);
fw.close();
}
/**
* 获取生成成功结果文件
*
* @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) {
String sErr = "";
while (true) {
String sTmp;
try {
if ((sTmp = stdError.readLine()) == null) {
break;
}
sErr += sTmp + FileUtil.getNewline();
} catch (IOException ioException) {
LOG.error(" genResultLog stdInput error" + ioException);
}
}
return sErr;
}
private boolean generateIsSuccess(String sOut) {
if (sOut.indexOf("success") >= 0 || TextUtils.isEmpty(sOut)) {
generateSuccess = true;
} else {
generateSuccess = false;
}
return generateSuccess;
}
/**
* 获取生成文本内容
*
* @param stdInput input buff
* @return 返回当前输入框内容
*/
private String genInputLog(BufferedReader stdInput) {
String sOut = "";
while (true) {
String sTmp;
try {
if ((sTmp = stdInput.readLine()) == null) {
break;
}
sOut += sTmp + FileUtil.getNewline();
} catch (IOException ioException) {
LOG.error(" genResultLog stdInput error" + ioException);
}
}
return sOut;
}
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;
}
}

View File

@ -14,52 +14,51 @@
*/
package com.sk.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.diagnostic.Logger;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.sk.dialog.GenerateDialog;
import java.util.regex.Pattern;
import com.sk.utils.FileUtil;
import com.sk.utils.GenNotification;
/**
* 项目文件入口
*
* @author: xudong
* @see: tool conversion plug-in
* @version: v1.0.0
* @since 2022/02/21
* @since 2022-02-21
*/
public class GenDTS extends AnAction {
private static final Logger LOG = Logger.getInstance(GenDTS.class);
@Override
public void actionPerformed(AnActionEvent anActionEvent) {
Project project = anActionEvent.getProject();
// 获取需要处理的.d.ts文件绝对路径
VirtualFile file = anActionEvent.getData(PlatformDataKeys.VIRTUAL_FILE);
if (file == null) {
LOG.error("file is not exit");
GenNotification.notifyMessage(project, "", "file is not exist", NotificationType.ERROR);
return;
}
// 正则匹配所选文件名是否符合规范
if (!Pattern.matches("@ohos.[a-zA-Z0-9]+.d.ts", file.getName())) {
Messages.showErrorDialog("选择@ohos.xxx.d.ts文件生成", "错误");
String baseFile = project.getBasePath();
if (!FileUtil.checkProjectSDK(project, baseFile)) {
return;
}
String destPath = file.getPath();
String directoryPath = file.getParent().getPath();
String fileName = file.getName();
showDialog(destPath, directoryPath, fileName);
GenerateDialog wrapper = new GenerateDialog(project, destPath, directoryPath, fileName);
if (wrapper.showAndGet()) {
return;
}
}
private void showDialog(String destPath, String directoryPath, String fileName) {
GenerateDialog dialog = new GenerateDialog(destPath, directoryPath, fileName);
dialog.initDialog();
dialog.setLocationRelativeTo(dialog);
dialog.pack();
dialog.setVisible(true);
}
@Override
public void update(AnActionEvent event) {
@ -68,8 +67,7 @@ public class GenDTS extends AnAction {
if (file == null) {
event.getPresentation().setEnabledAndVisible(false);
} else {
String extension = file.getExtension();
if (extension != null && "ts".equals(extension)) {
if (FileUtil.patternFileName(file.getName())) {
event.getPresentation().setEnabledAndVisible(true);
} else {
event.getPresentation().setEnabledAndVisible(false);

View File

@ -0,0 +1,50 @@
/*
* 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.ng;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.project.Project;
import com.sk.dialog.GenerateDialog;
import com.sk.utils.FileUtil;
import org.jetbrains.annotations.NotNull;
/**
* 工具菜单入口
*
* @author: liulongc digitalchina.com
* @see: tool conversion plug-in
* @version: v1.0.0
* @since 2022-05-27
*/
public class GenMenuDTS extends AnAction {
@Override
public void actionPerformed(@NotNull AnActionEvent anActionEvent) {
Project project = anActionEvent.getProject();
String baseFile = project.getBasePath();
if (!FileUtil.checkProjectSDK(project, baseFile)) {
return;
}
GenerateDialog wrapper = new GenerateDialog(project, "", "", "");
if (wrapper.showAndGet()) {
return;
}
}
}

View File

@ -14,7 +14,9 @@
*/
package com.sk.utils;
import com.intellij.notification.NotificationType;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import org.apache.commons.lang3.StringUtils;
import java.io.BufferedReader;
@ -23,16 +25,22 @@ import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Properties;
import java.util.regex.Pattern;
/**
* 文本文件工具
*
* @author: xudong
* @see: file utils
* @version: v1.0.0
* @since 2022/02/21
* @since 2022-02-21
*/
public class FileUtil {
private static final Logger LOG = Logger.getInstance(FileUtil.class);
private static final int COMPILE_SDK_VERSION = 5;
/**
* 将错误信息输入到txt中
*
@ -85,7 +93,7 @@ public class FileUtil {
File file = new File(path);
String[] command = content.split(StringUtils.LF);
try (InputStreamReader read = new InputStreamReader(new FileInputStream(file), "UTF-8");
BufferedReader bufferedReader = new BufferedReader(read)) {
BufferedReader bufferedReader = new BufferedReader(read)) {
return isContainString(bufferedReader, command);
}
}
@ -121,4 +129,54 @@ public class FileUtil {
public static String getNewline() {
return System.getProperty("line.separator");
}
/**
* 正则匹配所选文件名是否符合规范
*
* @param fileName 文件名
* @return boolean 是否匹配
*/
public static boolean patternFileName(String fileName) {
String pattern = "@ohos.([a-zA-Z0-9]+).d.ts";
return Pattern.matches(pattern, fileName);
}
/**
* check project SDK
*
* @param project projectid
* @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();
for (File file : childFile) {
if (file.getName().equals("build.gradle")) {
gradlePath = file.getPath();
}
}
}
Properties properties = new Properties();
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 false;
}
String ohosSDK = properties.getProperty("compileSdkVersion");
if (ohosSDK != null && Integer.parseInt(ohosSDK) < COMPILE_SDK_VERSION) {
GenNotification.notifyMessage(project, "SKD版本过低NAPI仅支持5.0及以上版本",
"提示",
NotificationType.WARNING);
return false;
}
return true;
}
}

View File

@ -0,0 +1,125 @@
/*
* 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.utils;
import com.intellij.ide.actions.OpenFileAction;
import com.intellij.notification.NotificationType;
import com.intellij.notification.Notification;
import com.intellij.notification.NotificationGroup;
import com.intellij.notification.NotificationAction;
import com.intellij.notification.Notifications;
import com.intellij.notification.NotificationDisplayType;
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: liulongc digitalchina.com
* @see: tool conversion plug-in
* @version: v1.0.0
* @since 2022-05-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) {
NotificationGroup notificationGroup = new NotificationGroup("Generate.Result.Group",
NotificationDisplayType.STICKY_BALLOON);
Notification notification = notificationGroup.createNotification(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()));
}
}
}
}