├── .gitignore
├── LICENSE
├── README.md
├── README_zh_CN.md
├── build.gradle
├── docs
└── media
│ ├── Add-Server.gif
│ ├── Command.gif
│ ├── Upload.gif
│ └── small-logo.svg
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── settings.gradle
└── src
├── main
├── java
│ ├── icons
│ │ └── MyIcons.java
│ └── tech
│ │ └── lin2j
│ │ └── idea
│ │ └── plugin
│ │ ├── action
│ │ ├── AddCommandAction.java
│ │ ├── ClassHotReloadAction.java
│ │ ├── CleanConfigAction.java
│ │ ├── CommandDialogAction.java
│ │ ├── ConfigExportAction.java
│ │ ├── ConfigImportAction.java
│ │ ├── CopyCommandAction.java
│ │ ├── CopyUploadProfileAction.java
│ │ ├── EnterKeyAdapter.java
│ │ ├── ExportAndImportAction.java
│ │ ├── GithubAction.java
│ │ ├── HomePageAction.java
│ │ ├── HostMoreOpsAction.java
│ │ ├── NewUpdateThreadAction.java
│ │ ├── OpenTerminalAction.java
│ │ ├── PasteCommandAction.java
│ │ ├── PasteUploadProfileAction.java
│ │ ├── SFTPTableMouseListener.java
│ │ ├── ServerSearchKeyAdapter.java
│ │ ├── TestConnectionAction.java
│ │ ├── UploadDialogAction.java
│ │ └── ftp
│ │ │ ├── ChangePermissionAction.java
│ │ │ ├── CopyFileNameAction.java
│ │ │ ├── CopyFilePathAction.java
│ │ │ ├── CreateNewFolderAction.java
│ │ │ ├── DeleteFileAndDirAction.java
│ │ │ ├── DownloadFileAndDirAction.java
│ │ │ ├── FileAction.java
│ │ │ ├── FilePropertiesAction.java
│ │ │ ├── GoToDesktopAction.java
│ │ │ ├── GoToParentFolderAction.java
│ │ │ ├── HomeDirectoryAction.java
│ │ │ ├── OpenFilePathAction.java
│ │ │ ├── OpenPathInTerminalAction.java
│ │ │ ├── ProjectPathAction.java
│ │ │ ├── RefreshFolderAction.java
│ │ │ ├── RowDoubleClickAction.java
│ │ │ ├── ShowHiddenFileAndDirAction.java
│ │ │ └── UploadFileAndDirAction.java
│ │ ├── enums
│ │ ├── AuthType.java
│ │ ├── Constant.java
│ │ ├── I18nType.java
│ │ ├── SFTPAction.java
│ │ ├── TransferEventType.java
│ │ ├── TransferMode.java
│ │ └── TransferState.java
│ │ ├── event
│ │ ├── ApplicationContext.java
│ │ ├── ApplicationEvent.java
│ │ ├── ApplicationListener.java
│ │ ├── ApplicationPublisher.java
│ │ └── listener
│ │ │ └── UploadProfileSelectedListener.java
│ │ ├── exception
│ │ └── IllegalFileTypeException.java
│ │ ├── factory
│ │ ├── CustomTtyConnectorFactory.java
│ │ └── DeployConsoleToolWindowFactory.java
│ │ ├── file
│ │ ├── ConsoleTransferListener.java
│ │ ├── DirectoryInfo.java
│ │ ├── LocalTableFile.java
│ │ ├── PluginFileTypeRegistry.java
│ │ ├── ProgressTableTransferListener.java
│ │ ├── RemoteTableFile.java
│ │ ├── TableFile.java
│ │ ├── fileTypes
│ │ │ ├── ConfigFileType.java
│ │ │ ├── DmgFileType.java
│ │ │ ├── EbookFileType.java
│ │ │ ├── ExcelFileType.java
│ │ │ ├── LogFileType.java
│ │ │ ├── PdfFileType.java
│ │ │ ├── PptFileType.java
│ │ │ ├── SFTPFileType.java
│ │ │ ├── SpecifiedArchiveFileType.java
│ │ │ ├── VideoFileType.java
│ │ │ └── WordFileType.java
│ │ └── filter
│ │ │ ├── ConsoleFileFilter.java
│ │ │ ├── ExtExcludeFilter.java
│ │ │ ├── FileAction.java
│ │ │ ├── FileFilter.java
│ │ │ ├── ListableFileFilter.java
│ │ │ └── RegexFileFilter.java
│ │ ├── model
│ │ ├── Command.java
│ │ ├── ConfigHelper.java
│ │ ├── ConfigImportExport.java
│ │ ├── ConfigPersistence.java
│ │ ├── DeployProfile.java
│ │ ├── EDPluginUpdateChecker.java
│ │ ├── ExportOptions.java
│ │ ├── HotReloadPersistence.java
│ │ ├── NoneCommand.java
│ │ ├── PluginConfigInitializer.java
│ │ ├── PluginSetting.java
│ │ ├── SeparatorCommand.java
│ │ ├── UniqueModel.java
│ │ ├── UploadProfile.java
│ │ └── event
│ │ │ ├── CommandAddEvent.java
│ │ │ ├── CommandExecuteEvent.java
│ │ │ ├── FileTransferEvent.java
│ │ │ ├── TableRefreshEvent.java
│ │ │ ├── UploadProfileAddEvent.java
│ │ │ ├── UploadProfileExecuteEvent.java
│ │ │ └── UploadProfileSelectedEvent.java
│ │ ├── runner
│ │ ├── ContentManagerAdapter.java
│ │ ├── DeployConfigurationFactory.java
│ │ ├── DeployRunConfiguration.java
│ │ ├── DeployRunConfigurationOptions.java
│ │ ├── DeployRunConfigurationType.java
│ │ ├── DeployRunProfileState.java
│ │ ├── DeploySettingsEditor.java
│ │ ├── ParallelDeployRunProfileState.java
│ │ └── process
│ │ │ ├── ListExecutionResult.java
│ │ │ ├── ListProcessHandler.java
│ │ │ └── UploadProcessHandler.java
│ │ ├── service
│ │ ├── IHotReloadService.java
│ │ ├── ISshService.java
│ │ └── impl
│ │ │ ├── HotReloadServiceImpl.java
│ │ │ ├── PluginNotificationService.java
│ │ │ └── SshjSshService.java
│ │ ├── ssh
│ │ ├── ClosableCloudTerminalProcess.java
│ │ ├── CommandLog.java
│ │ ├── ConsoleCommandLog.java
│ │ ├── CustomTtyConnector.java
│ │ ├── JavaProcess.java
│ │ ├── SshConnection.java
│ │ ├── SshConnectionManager.java
│ │ ├── SshProcess.java
│ │ ├── SshServer.java
│ │ ├── SshStatus.java
│ │ ├── SshUploadTask.java
│ │ ├── exception
│ │ │ └── RemoteSdkException.java
│ │ └── sshj
│ │ │ ├── SshjConnection.java
│ │ │ ├── SshjLoggerFactory.java
│ │ │ └── SshjTtyConnector.java
│ │ ├── ui
│ │ ├── DashboardView.java
│ │ ├── component
│ │ │ ├── ArrowLabel.java
│ │ │ ├── HostActionPanel.java
│ │ │ ├── HostBasicPanel.java
│ │ │ ├── HostChainItem.java
│ │ │ ├── HostDependencyPanel.java
│ │ │ ├── HostProxyPanel.java
│ │ │ └── ManualProxyPanel.java
│ │ ├── dialog
│ │ │ ├── AddCommandDialog.java
│ │ │ ├── AddUploadProfileDialog.java
│ │ │ ├── ChangePermissionsDialog.java
│ │ │ ├── ClassRetransformDialog.java
│ │ │ ├── FilePropertiesDialog.java
│ │ │ ├── FilesDeleteConfirmDialog.java
│ │ │ ├── HostSettingsDialog.java
│ │ │ ├── ImportConfigPreviewDialog.java
│ │ │ ├── InputConfirmDialog.java
│ │ │ ├── PasswordInputDialog.java
│ │ │ ├── PluginSettingsDialog.java
│ │ │ ├── SelectCommandDialog.java
│ │ │ ├── SelectServerDialog.java
│ │ │ ├── SelectUploadProfileDialog.java
│ │ │ ├── TransferConfirmDialog.java
│ │ │ └── UploadProfileDialog.java
│ │ ├── editor
│ │ │ ├── SFTPEditor.java
│ │ │ ├── SFTPEditorProvider.java
│ │ │ ├── SFTPFileSystem.java
│ │ │ └── SFTPVirtualFile.java
│ │ ├── ftp
│ │ │ ├── FTPConsole.java
│ │ │ ├── ProgressTable.java
│ │ │ └── container
│ │ │ │ ├── AbstractFileTableContainer.java
│ │ │ │ ├── FileTableContainer.java
│ │ │ │ ├── LocalFileTableContainer.java
│ │ │ │ └── RemoteFileTableContainer.java
│ │ ├── module
│ │ │ ├── ConsoleLogView.java
│ │ │ └── DashboardView.java
│ │ ├── render
│ │ │ ├── CommandColoredListCellRenderer.java
│ │ │ └── UploadProfileColoredListCellRenderer.java
│ │ ├── settings
│ │ │ ├── GeneralConfigurable.java
│ │ │ ├── SFTPConfigurable.java
│ │ │ └── ServerTagConfigurable.java
│ │ └── table
│ │ │ ├── ActionCellEditor.java
│ │ │ ├── ActionCellRenderer.java
│ │ │ ├── DeployProfileTableModel.java
│ │ │ ├── FileNameCellRenderer.java
│ │ │ ├── LocalFileTableModel.java
│ │ │ ├── ProgressCell.java
│ │ │ └── RemoteFileTableModel.java
│ │ └── uitl
│ │ ├── CommandUtil.java
│ │ ├── EasyDeployPluginUtil.java
│ │ ├── EncryptionUtil.java
│ │ ├── FTPUtil.java
│ │ ├── FileTransferSpeed.java
│ │ ├── FileUtil.java
│ │ ├── ImportExportUtil.java
│ │ ├── MessagesBundle.java
│ │ ├── PosixUtil.java
│ │ ├── TerminalRunnerUtil.java
│ │ ├── UiUtil.java
│ │ └── WebBrowseUtil.java
└── resources
│ ├── META-INF
│ ├── plugin.xml
│ └── pluginIcon.svg
│ ├── arthas.tar.gz
│ ├── icons
│ ├── actions
│ │ ├── copy.svg
│ │ ├── export_import.svg
│ │ ├── github.svg
│ │ ├── home-page.svg
│ │ ├── host.svg
│ │ ├── my-add.svg
│ │ ├── my_clean.svg
│ │ ├── my_connect.svg
│ │ ├── my_export.svg
│ │ ├── my_import.svg
│ │ ├── my_lost_connect.svg
│ │ ├── my_refresh.svg
│ │ ├── my_settings.svg
│ │ ├── my_share.svg
│ │ ├── my_share_selected.svg
│ │ ├── my_upload.svg
│ │ ├── paste.svg
│ │ ├── showHiddens.svg
│ │ └── showHiddens_dark.svg
│ ├── deploy.svg
│ ├── deploy_dark.svg
│ ├── easy-deploy.svg
│ ├── fileTypes
│ │ ├── c.svg
│ │ ├── c_dark.svg
│ │ ├── cpp.svg
│ │ ├── cpp_dark.svg
│ │ ├── dmg.svg
│ │ ├── ebook.svg
│ │ ├── excel.svg
│ │ ├── log.svg
│ │ ├── pdf.svg
│ │ ├── ppt.svg
│ │ ├── video.svg
│ │ └── word.svg
│ ├── filter.svg
│ ├── message_blue.svg
│ ├── sftp.svg
│ ├── tag.svg
│ ├── tag_dark.svg
│ ├── transferToolWindow.svg
│ ├── transferToolWindow_dark.svg
│ └── upload_profile.svg
│ ├── messages_en.properties
│ └── messages_zh.properties
└── test
└── java
└── tech
└── lin2j
└── idea
└── plugin
└── file
└── FilterTest.java
/.gitignore:
--------------------------------------------------------------------------------
1 | /.idea
2 | /target
3 | /logs
4 | .idea/
5 | .svn/
6 | *.iml
7 | *.ipr
8 | *.iws
9 | */*.log
10 | */target/
11 | *.DS_Store
12 | *.classpath
13 | *.settings
14 | *.project
15 | .flattened-pom.xml
16 | .gradle
17 | build
--------------------------------------------------------------------------------
/README_zh_CN.md:
--------------------------------------------------------------------------------
1 |

2 |
3 | 方便开发过程中部署升级服务的 Intellij 平台插件
4 |
5 |
11 |
12 |
13 |
14 | Easy Deploy 是我借鉴 Alibaba Cloud Toolkit 插件开发的一个方便自己在开发过程中部署服务的插件。相比较 Alibaba Cloud Toolkit,我开发的插件功能会少很多很多,因为 ACT 很多的功能我都用不上,对我来说它有点臃肿。
15 |
16 | 因此,我只取自己关注的那部分功能进行开发,这部分就是对服务器的管理以及发布的过程。我给这个插件起这个名是希望他能够帮助开发者简化开发过程的部署步骤,我会不断地优化它,完善它的功能。
17 |
18 | 这也是我开发的第一款 Idea 插件,很多问题都是通过长时间的搜索才一点一点的解决的,特别是 Swing 相关的知识,毕竟很多年没写了,再加上 Intellj 的封装,不同版本的 UI 可能会有些不同。因此如果你在下载和使用它过程中有问题的话,可以给我提 Issue。
19 |
20 | 👉👉 [去插件市场下载](https://plugins.jetbrains.com/plugin/19432-easy-deploy)
21 |
22 | # 支持
23 |
24 | 如果这个插件对你有帮助的话,请动动小手给仓库一个 star ⭐️⭐️。
25 |
26 | # 功能
27 |
28 | - [x] 添加/编辑/删除/搜索服务器信息
29 | - [x] 添加/编辑/删除/分享命令
30 | - [x] 上传文件或者目录,并支持过滤
31 | - [x] 文件(目录)上传配置
32 | - [x] 终端连接
33 | - [x] SSH 免密登录(私钥登录)
34 | - [x] SSH 代理跳板机
35 | - [x] Run/Debug Configuration (并行部署)
36 | - [x] 国际化
37 | - [x] SFTP 传输面板
38 | - [x] 插件设置
39 | - [x] 导出、导入、清除插件配置
40 |
41 | # 联系我🐾
42 |
43 | 在开发 Idea 插件方面我是一个新手,有很多问题可能处理得不是很好。
44 |
45 | 如果你有什么建议或者遇到什么bug,可以提 issues 也可以邮箱联系我,我会尽快回复你。
46 |
47 | 📮📮 linjinjia047@163.com
48 |
49 | 👻👻[去 Github 提 Issue](https://github.com/lin2j/easy-deploy/issues)
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'org.jetbrains.intellij' version '1.17.4'
3 | id 'java'
4 | }
5 |
6 | group 'tech.lin2j'
7 | version '1.3.8-241'
8 |
9 | repositories {
10 | mavenCentral()
11 | }
12 |
13 | dependencies {
14 | implementation 'com.hierynomus:sshj:0.39.0'
15 | }
16 |
17 | // See https://github.com/JetBrains/gradle-intellij-plugin/
18 | intellij {
19 | version = '2024.1'
20 | // type = 'IU'
21 | plugins = [
22 | 'com.intellij.java',
23 | "org.jetbrains.plugins.terminal",
24 | ]
25 | updateSinceUntilBuild = false
26 | }
27 |
28 | tasks.withType(JavaCompile).configureEach {
29 | sourceCompatibility = "17"
30 | targetCompatibility = "17"
31 | options.encoding = "UTF-8"
32 | options.compilerArgs << "-Xlint:unchecked"
33 | }
34 |
35 | test {
36 | useJUnitPlatform()
37 | }
38 |
--------------------------------------------------------------------------------
/docs/media/Add-Server.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lin2j/easy-deploy/b9fc0ec2029ef5149418180c6d737ffd8feadec8/docs/media/Add-Server.gif
--------------------------------------------------------------------------------
/docs/media/Command.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lin2j/easy-deploy/b9fc0ec2029ef5149418180c6d737ffd8feadec8/docs/media/Command.gif
--------------------------------------------------------------------------------
/docs/media/Upload.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lin2j/easy-deploy/b9fc0ec2029ef5149418180c6d737ffd8feadec8/docs/media/Upload.gif
--------------------------------------------------------------------------------
/docs/media/small-logo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx2024m
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lin2j/easy-deploy/b9fc0ec2029ef5149418180c6d737ffd8feadec8/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.1-bin.zip
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name = 'Easy-Deploy'
2 |
3 |
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/action/AddCommandAction.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.action;
2 |
3 | import com.intellij.openapi.actionSystem.AnActionEvent;
4 | import com.intellij.openapi.project.Project;
5 | import icons.MyIcons;
6 | import org.jetbrains.annotations.NotNull;
7 | import tech.lin2j.idea.plugin.model.Command;
8 | import tech.lin2j.idea.plugin.model.ConfigHelper;
9 | import tech.lin2j.idea.plugin.ui.dialog.AddCommandDialog;
10 | import tech.lin2j.idea.plugin.uitl.MessagesBundle;
11 |
12 | import java.util.List;
13 | import java.util.function.Consumer;
14 |
15 | /**
16 | * @author linjinjia
17 | * @date 2024/7/7 16:07
18 | */
19 | public class AddCommandAction extends NewUpdateThreadAction {
20 |
21 | private static final String text = MessagesBundle.getText("action.common.command.add.text");
22 |
23 | private final int sshId;
24 | private final Project project;
25 | private final Consumer action;
26 |
27 | public AddCommandAction(Project project, int sshId, Consumer action) {
28 | super(text, text, MyIcons.Actions.Add);
29 | this.sshId = sshId;
30 | this.project = project;
31 | this.action = action;
32 | }
33 |
34 | @Override
35 | public void actionPerformed(@NotNull AnActionEvent e) {
36 | Command tmp = new Command(sshId);
37 | boolean exitOk = new AddCommandDialog(project, tmp).showAndGet();
38 | if (exitOk && action != null) {
39 | List list = ConfigHelper.getCommandsBySshId(sshId);
40 | Command newCmd = list.get(list.size() - 1);
41 | action.accept(newCmd);
42 | }
43 | }
44 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/action/ClassHotReloadAction.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.action;
2 |
3 | import com.intellij.openapi.actionSystem.AnAction;
4 | import com.intellij.openapi.actionSystem.AnActionEvent;
5 | import com.intellij.openapi.progress.ProgressIndicator;
6 | import com.intellij.openapi.progress.ProgressManager;
7 | import com.intellij.openapi.progress.Task;
8 | import com.intellij.openapi.project.Project;
9 | import com.intellij.openapi.ui.Messages;
10 | import org.jetbrains.annotations.NotNull;
11 | import tech.lin2j.idea.plugin.exception.IllegalFileTypeException;
12 | import tech.lin2j.idea.plugin.ui.dialog.ClassRetransformDialog;
13 | import tech.lin2j.idea.plugin.uitl.MessagesBundle;
14 |
15 | import javax.swing.SwingUtilities;
16 |
17 | /**
18 | * @author linjinjia
19 | * @date 2024/10/20 15:31
20 | */
21 | public class ClassHotReloadAction extends AnAction {
22 |
23 | public ClassHotReloadAction() {
24 | super(MessagesBundle.getText("dialog.retransform.frame"));
25 | }
26 |
27 | @Override
28 | public void actionPerformed(@NotNull AnActionEvent e) {
29 | try {
30 | Project project = e.getProject();
31 | assert project != null;
32 | ClassRetransformDialog dialog = new ClassRetransformDialog(project, e);
33 | dialog.setData();
34 | dialog.show();
35 | } catch (IllegalFileTypeException err) {
36 | Messages.showErrorDialog("Class reload only supports Java files", "File Type Error");
37 | }
38 |
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/action/CleanConfigAction.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.action;
2 |
3 | import com.intellij.openapi.actionSystem.AnActionEvent;
4 | import icons.MyIcons;
5 | import org.jetbrains.annotations.NotNull;
6 | import tech.lin2j.idea.plugin.event.ApplicationContext;
7 | import tech.lin2j.idea.plugin.model.ConfigHelper;
8 | import tech.lin2j.idea.plugin.model.event.TableRefreshEvent;
9 | import tech.lin2j.idea.plugin.ui.dialog.InputConfirmDialog;
10 | import tech.lin2j.idea.plugin.uitl.MessagesBundle;
11 |
12 | /**
13 | *
14 | * @author linjinjia
15 | * @date 2024/7/28 18:21
16 | */
17 | public class CleanConfigAction extends NewUpdateThreadAction {
18 |
19 | private static final String text = MessagesBundle.getText("action.dashboard.clean.text");
20 |
21 | public CleanConfigAction() {
22 | super(text, text, MyIcons.Actions.Clean);
23 | }
24 |
25 | @Override
26 | public void actionPerformed(@NotNull AnActionEvent e) {
27 | String title = MessagesBundle.getText("dialog.clean.title");
28 | String msg = MessagesBundle.getText("dialog.clean.tip");
29 | String okText = MessagesBundle.getText("dialog.clean.ok-text");
30 | String confirm = "Clean All Configuration";
31 |
32 | boolean isOk = new InputConfirmDialog(null, title, msg, confirm, okText).showAndGet();
33 | if (isOk) {
34 | ConfigHelper.cleanConfig();
35 | ApplicationContext.getApplicationContext().publishEvent(new TableRefreshEvent(true));
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/action/CommandDialogAction.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.action;
2 |
3 | import com.intellij.openapi.project.Project;
4 | import tech.lin2j.idea.plugin.event.ApplicationContext;
5 | import tech.lin2j.idea.plugin.ui.dialog.SelectCommandDialog;
6 |
7 | import java.awt.event.ActionEvent;
8 | import java.awt.event.ActionListener;
9 |
10 | /**
11 | * @author linjinjia
12 | * @date 2024/5/5 12:26
13 | */
14 | public class CommandDialogAction implements ActionListener {
15 |
16 | private final int sshId;
17 | private final Project project;
18 |
19 | public CommandDialogAction(int sshId, Project project) {
20 | this.sshId = sshId;
21 | this.project = project;
22 | }
23 |
24 | @Override
25 | public void actionPerformed(ActionEvent e) {
26 | SelectCommandDialog ui = new SelectCommandDialog(project, sshId);
27 | ApplicationContext.getApplicationContext().addApplicationListener(ui);
28 | ui.showAndGet();
29 | }
30 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/action/CopyCommandAction.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.action;
2 |
3 | import com.google.gson.Gson;
4 | import com.intellij.openapi.actionSystem.AnActionEvent;
5 | import com.intellij.openapi.ide.CopyPasteManager;
6 | import com.intellij.util.ui.TextTransferable;
7 | import icons.MyIcons;
8 | import org.jetbrains.annotations.NotNull;
9 | import tech.lin2j.idea.plugin.model.Command;
10 |
11 | import java.util.function.Supplier;
12 |
13 | /**
14 | * @author linjinjia
15 | * @date 2024/6/9 16:09
16 | */
17 | public class CopyCommandAction extends NewUpdateThreadAction {
18 |
19 | private final Supplier provider;
20 |
21 | public CopyCommandAction(Command command) {
22 | this(() -> command);
23 | }
24 |
25 | public CopyCommandAction(Supplier provider) {
26 | super("Copy Command", "Copy command", MyIcons.Actions.Copy);
27 | this.provider = provider;
28 |
29 | }
30 |
31 | @Override
32 | public void actionPerformed(@NotNull AnActionEvent e) {
33 | if (provider.get() == null) {
34 | return;
35 | }
36 | Gson gson = new Gson();
37 | String json = gson.toJson(provider.get());
38 | CopyPasteManager.getInstance().setContents(new TextTransferable(json));
39 | }
40 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/action/CopyUploadProfileAction.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.action;
2 |
3 | import com.google.gson.Gson;
4 | import com.intellij.openapi.actionSystem.AnActionEvent;
5 | import com.intellij.openapi.ide.CopyPasteManager;
6 | import com.intellij.util.ui.TextTransferable;
7 | import icons.MyIcons;
8 | import org.jetbrains.annotations.NotNull;
9 | import tech.lin2j.idea.plugin.model.UploadProfile;
10 |
11 | import java.util.function.Supplier;
12 |
13 | /**
14 | * @author linjinjia
15 | * @date 2024/6/9 16:09
16 | */
17 | public class CopyUploadProfileAction extends NewUpdateThreadAction {
18 |
19 | private final Supplier provider;
20 |
21 | public CopyUploadProfileAction(UploadProfile profile) {
22 | this(() -> profile);
23 | }
24 |
25 | public CopyUploadProfileAction(Supplier provider) {
26 | super("Copy Profile", "Copy profile", MyIcons.Actions.Copy);
27 | this.provider = provider;
28 |
29 | }
30 |
31 | @Override
32 | public void actionPerformed(@NotNull AnActionEvent e) {
33 | if (provider.get() == null) {
34 | return;
35 | }
36 | Gson gson = new Gson();
37 | String json = gson.toJson(provider.get());
38 | CopyPasteManager.getInstance().setContents(new TextTransferable(json));
39 | }
40 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/action/EnterKeyAdapter.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.action;
2 |
3 | import java.awt.event.KeyAdapter;
4 | import java.awt.event.KeyEvent;
5 |
6 | /**
7 | *
8 | * @author linjinjia
9 | * @date 2024/8/7 21:09
10 | */
11 | public abstract class EnterKeyAdapter extends KeyAdapter {
12 |
13 | @Override
14 | public void keyPressed(KeyEvent e) {
15 | if (e.getKeyCode() != KeyEvent.VK_ENTER) {
16 | return;
17 | }
18 | doAction(e);
19 | }
20 |
21 | protected abstract void doAction(KeyEvent e);
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/action/ExportAndImportAction.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.action;
2 |
3 | import com.intellij.openapi.actionSystem.ActionGroup;
4 | import com.intellij.openapi.actionSystem.AnAction;
5 | import com.intellij.openapi.actionSystem.AnActionEvent;
6 | import icons.MyIcons;
7 | import org.jetbrains.annotations.NotNull;
8 | import org.jetbrains.annotations.Nullable;
9 | import tech.lin2j.idea.plugin.uitl.MessagesBundle;
10 |
11 | /**
12 | * @author linjinjia
13 | * @date 2024/7/20 22:56
14 | */
15 | public class ExportAndImportAction extends ActionGroup {
16 |
17 | private static final String text = MessagesBundle.getText("action.dashboard.export-import.text");
18 |
19 |
20 | public ExportAndImportAction() {
21 | super(text, text, MyIcons.Actions.ExportAndImport);
22 | setPopup(true);
23 | }
24 |
25 | @NotNull
26 | @Override
27 | public AnAction[] getChildren(@Nullable AnActionEvent e) {
28 | return new AnAction[]{
29 | new ConfigImportAction(),
30 | new ConfigExportAction(),
31 | new CleanConfigAction(),
32 | };
33 | }
34 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/action/GithubAction.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.action;
2 |
3 | import com.intellij.openapi.actionSystem.AnActionEvent;
4 | import icons.MyIcons;
5 | import org.jetbrains.annotations.NotNull;
6 | import tech.lin2j.idea.plugin.uitl.WebBrowseUtil;
7 |
8 | /**
9 | * @author linjinjia
10 | * @date 2024/4/25 22:43
11 | */
12 | public class GithubAction extends NewUpdateThreadAction {
13 | public GithubAction() {
14 | super("Github", "Plugin github repository", MyIcons.Actions.Github);
15 | }
16 |
17 | @Override
18 | public void actionPerformed(@NotNull AnActionEvent e) {
19 | WebBrowseUtil.browse("https://github.com/lin2j/easy-deploy");
20 | }
21 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/action/HomePageAction.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.action;
2 |
3 | import com.intellij.openapi.actionSystem.AnActionEvent;
4 | import icons.MyIcons;
5 | import org.jetbrains.annotations.NotNull;
6 | import tech.lin2j.idea.plugin.uitl.MessagesBundle;
7 | import tech.lin2j.idea.plugin.uitl.WebBrowseUtil;
8 |
9 | /**
10 | * @author linjinjia
11 | * @date 2024/4/25 22:43
12 | */
13 | public class HomePageAction extends NewUpdateThreadAction {
14 | private static final String text = MessagesBundle.getText("action.dashboard.home-page.text");
15 |
16 | public HomePageAction() {
17 | super(text, "Plugin Home page", MyIcons.EasyDeploy);
18 | }
19 |
20 | @Override
21 | public void actionPerformed(@NotNull AnActionEvent e) {
22 | WebBrowseUtil.browse("https://lin2j.tech/md/easy-deploy/brief.html");
23 | }
24 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/action/NewUpdateThreadAction.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.action;
2 |
3 | import com.intellij.openapi.actionSystem.ActionUpdateThread;
4 | import com.intellij.openapi.actionSystem.AnAction;
5 | import com.intellij.openapi.util.NlsActions;
6 | import org.jetbrains.annotations.NotNull;
7 | import org.jetbrains.annotations.Nullable;
8 |
9 | import javax.swing.Icon;
10 | import java.util.function.Supplier;
11 |
12 | /**
13 | * @author linjinjia
14 | * @date 2024/8/18 18:21
15 | */
16 | public abstract class NewUpdateThreadAction extends AnAction {
17 |
18 | public NewUpdateThreadAction() {
19 | }
20 |
21 | public NewUpdateThreadAction(@Nullable Icon icon) {
22 | super(icon);
23 | }
24 |
25 | public NewUpdateThreadAction(@Nullable @NlsActions.ActionText String text) {
26 | super(text);
27 | }
28 |
29 | public NewUpdateThreadAction(@NotNull Supplier<@NlsActions.ActionText String> dynamicText) {
30 | super(dynamicText);
31 | }
32 |
33 | public NewUpdateThreadAction(@Nullable @NlsActions.ActionText String text, @Nullable @NlsActions.ActionDescription String description, @Nullable Icon icon) {
34 | super(text, description, icon);
35 | }
36 |
37 | public NewUpdateThreadAction(@NotNull @NlsActions.ActionText Supplier text, @Nullable @NlsActions.ActionDescription Supplier description, @Nullable Supplier extends @Nullable Icon> icon) {
38 | super(text, description, icon);
39 | }
40 |
41 | public NewUpdateThreadAction(@NotNull @NlsActions.ActionText Supplier text, @NotNull @NlsActions.ActionDescription Supplier description) {
42 | super(text, description);
43 | }
44 |
45 | public NewUpdateThreadAction(@NotNull Supplier<@NlsActions.ActionText String> dynamicText, @Nullable Icon icon) {
46 | super(dynamicText, icon);
47 | }
48 |
49 | public NewUpdateThreadAction(@NotNull Supplier<@NlsActions.ActionText String> dynamicText, @NotNull Supplier<@NlsActions.ActionDescription String> dynamicDescription, @Nullable Icon icon) {
50 | super(dynamicText, dynamicDescription, icon);
51 | }
52 |
53 | @Override
54 | public @NotNull ActionUpdateThread getActionUpdateThread() {
55 | return ActionUpdateThread.BGT;
56 | }
57 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/action/PasteCommandAction.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.action;
2 |
3 | import com.google.gson.Gson;
4 | import com.google.gson.JsonSyntaxException;
5 | import com.intellij.openapi.actionSystem.AnActionEvent;
6 | import com.intellij.openapi.ide.CopyPasteManager;
7 | import com.intellij.openapi.ui.Messages;
8 | import com.intellij.openapi.util.text.StringUtil;
9 | import icons.MyIcons;
10 | import org.apache.commons.lang.StringUtils;
11 | import org.jetbrains.annotations.NotNull;
12 | import tech.lin2j.idea.plugin.model.Command;
13 |
14 | import javax.swing.SwingUtilities;
15 | import java.awt.datatransfer.DataFlavor;
16 | import java.util.function.Consumer;
17 |
18 | /**
19 | * @author linjinjia
20 | * @date 2024/6/9 16:12
21 | */
22 | public class PasteCommandAction extends NewUpdateThreadAction {
23 |
24 | private final Consumer consumer;
25 |
26 | public PasteCommandAction(Consumer consumer) {
27 | super("Paste Command", "Paste command", MyIcons.Actions.Paste);
28 | this.consumer = consumer;
29 | }
30 |
31 | @Override
32 | public void actionPerformed(@NotNull AnActionEvent e) {
33 | try {
34 | String json = CopyPasteManager.getInstance().getContents(DataFlavor.stringFlavor);
35 |
36 | if (StringUtil.isEmpty(json)) {
37 | return;
38 | }
39 | Gson gson = new Gson();
40 | Command cmd = gson.fromJson(json, Command.class);
41 | if (cmd == null) {
42 | return;
43 | }
44 | consumer.accept(cmd);
45 | } catch (JsonSyntaxException err) {
46 | SwingUtilities.invokeLater(() -> Messages.showErrorDialog("Json parse exception", "Parse Error"));
47 | }
48 |
49 | }
50 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/action/PasteUploadProfileAction.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.action;
2 |
3 | import com.google.gson.Gson;
4 | import com.google.gson.JsonSyntaxException;
5 | import com.intellij.openapi.actionSystem.AnActionEvent;
6 | import com.intellij.openapi.ide.CopyPasteManager;
7 | import com.intellij.openapi.ui.Messages;
8 | import com.intellij.openapi.util.text.StringUtil;
9 | import icons.MyIcons;
10 | import org.jetbrains.annotations.NotNull;
11 | import tech.lin2j.idea.plugin.model.UploadProfile;
12 |
13 | import javax.swing.SwingUtilities;
14 | import java.awt.datatransfer.DataFlavor;
15 | import java.util.function.Consumer;
16 |
17 | /**
18 | * @author linjinjia
19 | * @date 2024/6/9 16:12
20 | */
21 | public class PasteUploadProfileAction extends NewUpdateThreadAction {
22 |
23 | private final Consumer consumer;
24 |
25 | public PasteUploadProfileAction(Consumer consumer) {
26 | super("Paste Profile", "Paste profile", MyIcons.Actions.Paste);
27 | this.consumer = consumer;
28 | }
29 |
30 | @Override
31 | public void actionPerformed(@NotNull AnActionEvent e) {
32 | try {
33 | String json = CopyPasteManager.getInstance().getContents(DataFlavor.stringFlavor);
34 | if (StringUtil.isEmpty(json)) {
35 | return;
36 | }
37 | Gson gson = new Gson();
38 | UploadProfile up = gson.fromJson(json, UploadProfile.class);
39 | if (up == null) {
40 | return;
41 | }
42 | up.setCommandId(null);
43 | consumer.accept(up);
44 | } catch (JsonSyntaxException err) {
45 | SwingUtilities.invokeLater(() -> {
46 | Messages.showErrorDialog("Json parse exception", "Parse Error");
47 | });
48 | }
49 |
50 | }
51 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/action/ServerSearchKeyAdapter.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.action;
2 |
3 | import com.intellij.openapi.util.text.StringUtil;
4 | import com.intellij.ui.SearchTextField;
5 | import org.apache.commons.collections.CollectionUtils;
6 | import tech.lin2j.idea.plugin.model.ConfigHelper;
7 | import tech.lin2j.idea.plugin.ssh.SshServer;
8 |
9 | import java.awt.event.KeyAdapter;
10 | import java.awt.event.KeyEvent;
11 | import java.util.ArrayList;
12 | import java.util.List;
13 | import java.util.function.Consumer;
14 |
15 | /**
16 | * keyboard listener
17 | *
18 | * @author linjinjia 2024/5/16 23:11
19 | */
20 | public class ServerSearchKeyAdapter extends KeyAdapter {
21 |
22 | private final SearchTextField searchInput;
23 | private final Consumer> action;
24 |
25 | public ServerSearchKeyAdapter(SearchTextField searchInput, Consumer> action) {
26 | this.searchInput = searchInput;
27 | this.action = action;
28 | }
29 |
30 | @Override
31 | public void keyPressed(KeyEvent e) {
32 | search(e);
33 | }
34 |
35 | @Override
36 | public void keyReleased(KeyEvent e) {
37 | search(e);
38 | }
39 |
40 |
41 | private void search(KeyEvent e) {
42 | List searchResult = new ArrayList<>();
43 | List serverInConfig = ConfigHelper.sshServers();
44 | if (CollectionUtils.isEmpty(serverInConfig)) {
45 | return;
46 | }
47 |
48 | String keyword = searchInput.getText();
49 | if (StringUtil.isEmpty(keyword)) {
50 | action.accept(serverInConfig);
51 | return;
52 | }
53 |
54 | for (SshServer server : serverInConfig) {
55 | if (server.getIp().contains(keyword)) {
56 | searchResult.add(server);
57 | continue;
58 | }
59 | if (server.getUsername().contains(keyword)) {
60 | searchResult.add(server);
61 | continue;
62 | }
63 | String desc = server.getDescription();
64 | if (StringUtil.isNotEmpty(desc) && desc.contains(keyword)) {
65 | searchResult.add(server);
66 | }
67 | }
68 |
69 | action.accept(searchResult);
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/action/TestConnectionAction.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.action;
2 |
3 | import com.intellij.openapi.application.ApplicationManager;
4 | import com.intellij.openapi.progress.ProgressIndicator;
5 | import com.intellij.openapi.progress.ProgressManager;
6 | import com.intellij.openapi.progress.Task;
7 | import com.intellij.openapi.project.Project;
8 | import com.intellij.openapi.ui.Messages;
9 | import org.jetbrains.annotations.NotNull;
10 | import tech.lin2j.idea.plugin.service.ISshService;
11 | import tech.lin2j.idea.plugin.service.impl.PluginNotificationService;
12 | import tech.lin2j.idea.plugin.service.impl.SshjSshService;
13 | import tech.lin2j.idea.plugin.ssh.SshServer;
14 | import tech.lin2j.idea.plugin.ssh.SshStatus;
15 | import tech.lin2j.idea.plugin.uitl.MessagesBundle;
16 |
17 | import java.awt.event.ActionEvent;
18 | import java.awt.event.ActionListener;
19 |
20 | /**
21 | *
22 | * @author linjinjia
23 | * @date 2024/11/28 22:27
24 | */
25 | public class TestConnectionAction implements ActionListener {
26 | private final SshServer sshServer;
27 | private final Project project;
28 | private final ISshService sshService;
29 | private final PluginNotificationService notificationService;
30 |
31 | public TestConnectionAction(Project project, SshServer server) {
32 | this.sshServer = server;
33 | this.project = project;
34 | sshService = ApplicationManager.getApplication().getService(ISshService.class);
35 | notificationService = ApplicationManager.getApplication().getService(PluginNotificationService.class);
36 | }
37 |
38 | @Override
39 | public void actionPerformed(ActionEvent e) {
40 | String title = String.format("Testing %s:%s", sshServer.getIp(), sshServer.getPort());
41 | ProgressManager.getInstance().run(new Task.Backgroundable(project, title) {
42 | @Override
43 | public void run(@NotNull ProgressIndicator indicator) {
44 | SshStatus status = sshService.isValid(sshServer);
45 |
46 | String title = MessagesBundle.getText("dialog.panel.host.test-connect.title");
47 | String tip = MessagesBundle.getText("dialog.panel.host.test-connect.tip");
48 | String msg = status.isSuccess() ? tip : status.getMessage();
49 | notificationService.showNotification(project, title, msg);
50 | }
51 | });
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/action/UploadDialogAction.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.action;
2 |
3 | import com.intellij.openapi.project.Project;
4 | import tech.lin2j.idea.plugin.event.ApplicationContext;
5 | import tech.lin2j.idea.plugin.model.ConfigHelper;
6 | import tech.lin2j.idea.plugin.ui.dialog.UploadProfileDialog;
7 |
8 | import java.awt.event.ActionEvent;
9 | import java.awt.event.ActionListener;
10 |
11 | /**
12 | * @author linjinjia
13 | * @date 2024/5/5 12:26
14 | */
15 | public class UploadDialogAction implements ActionListener {
16 |
17 | private final int sshId;
18 | private final Project project;
19 |
20 | public UploadDialogAction(int sshId, Project project) {
21 | this.sshId = sshId;
22 | this.project = project;
23 | }
24 |
25 | @Override
26 | public void actionPerformed(ActionEvent e) {
27 | UploadProfileDialog dialog = new UploadProfileDialog(project, ConfigHelper.getSshServerById(sshId));
28 | ApplicationContext.getApplicationContext().addApplicationListener(dialog);
29 | dialog.showAndGet();
30 | }
31 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/action/ftp/ChangePermissionAction.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.action.ftp;
2 |
3 | import com.intellij.icons.AllIcons;
4 | import com.intellij.openapi.actionSystem.AnActionEvent;
5 | import org.apache.commons.collections.CollectionUtils;
6 | import org.jetbrains.annotations.NotNull;
7 | import tech.lin2j.idea.plugin.action.NewUpdateThreadAction;
8 | import tech.lin2j.idea.plugin.file.RemoteTableFile;
9 | import tech.lin2j.idea.plugin.file.TableFile;
10 | import tech.lin2j.idea.plugin.ui.dialog.ChangePermissionsDialog;
11 | import tech.lin2j.idea.plugin.ui.ftp.container.RemoteFileTableContainer;
12 | import tech.lin2j.idea.plugin.uitl.MessagesBundle;
13 |
14 | import java.util.List;
15 |
16 | /**
17 | * @author linjinjia
18 | * @date 2024/4/4 17:24
19 | */
20 | public class ChangePermissionAction extends NewUpdateThreadAction {
21 | private static final String text = MessagesBundle.getText("action.ftp.popup.permission.text");
22 |
23 | private final RemoteFileTableContainer container;
24 |
25 | public ChangePermissionAction(RemoteFileTableContainer container) {
26 | super(text, "Change permission of file and directory", AllIcons.Actions.ChangeView);
27 | this.container = container;
28 | }
29 |
30 | @Override
31 | public void actionPerformed(@NotNull AnActionEvent e) {
32 | List fileList = container.getSelectedFiles();
33 | if (CollectionUtils.isNotEmpty(fileList)) {
34 | RemoteTableFile file = (RemoteTableFile) fileList.get(0);
35 | boolean refresh = new ChangePermissionsDialog(file, container.getFTPClient()).showAndGet();
36 | if (refresh) {
37 | container.refreshFileList();
38 | }
39 | }
40 | }
41 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/action/ftp/CopyFileNameAction.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.action.ftp;
2 |
3 | import com.intellij.openapi.ide.CopyPasteManager;
4 | import com.intellij.util.ui.TextTransferable;
5 | import tech.lin2j.idea.plugin.file.TableFile;
6 | import tech.lin2j.idea.plugin.ui.ftp.container.FileTableContainer;
7 | import tech.lin2j.idea.plugin.uitl.MessagesBundle;
8 |
9 | /**
10 | *
11 | * @author linjinjia
12 | * @date 2024/5/24 23:28
13 | */
14 | public class CopyFileNameAction extends FileAction {
15 | private static final String text = MessagesBundle.getText("action.ftp.popup.copy.filename.text");
16 |
17 | public CopyFileNameAction(FileTableContainer container) {
18 | super(text, container);
19 | }
20 |
21 | @Override
22 | protected void handle(TableFile file) {
23 | String data = file.getName();
24 | CopyPasteManager.getInstance().setContents(new TextTransferable(data));
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/action/ftp/CopyFilePathAction.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.action.ftp;
2 |
3 | import com.intellij.openapi.ide.CopyPasteManager;
4 | import com.intellij.util.ui.TextTransferable;
5 | import tech.lin2j.idea.plugin.file.TableFile;
6 | import tech.lin2j.idea.plugin.ui.ftp.container.FileTableContainer;
7 | import tech.lin2j.idea.plugin.uitl.MessagesBundle;
8 |
9 | /**
10 | *
11 | * @author linjinjia
12 | * @date 2024/5/24 21:42
13 | */
14 | public class CopyFilePathAction extends FileAction {
15 | private static final String text = MessagesBundle.getText("action.ftp.popup.copy.path.text");
16 |
17 | public CopyFilePathAction(FileTableContainer container) {
18 | super(text, container);
19 | }
20 |
21 |
22 | @Override
23 | protected void handle(TableFile file) {
24 | String path = file.getFilePath();
25 | CopyPasteManager.getInstance().setContents(new TextTransferable(path));
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/action/ftp/CreateNewFolderAction.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.action.ftp;
2 |
3 | import com.intellij.icons.AllIcons;
4 | import com.intellij.openapi.actionSystem.AnActionEvent;
5 | import com.intellij.openapi.ui.Messages;
6 | import com.intellij.openapi.util.text.StringUtil;
7 | import org.jetbrains.annotations.NotNull;
8 | import org.slf4j.Logger;
9 | import org.slf4j.LoggerFactory;
10 | import tech.lin2j.idea.plugin.action.NewUpdateThreadAction;
11 | import tech.lin2j.idea.plugin.ui.ftp.container.FileTableContainer;
12 | import tech.lin2j.idea.plugin.uitl.MessagesBundle;
13 |
14 | import java.io.IOException;
15 |
16 | /**
17 | * @author linjinjia
18 | * @date 2024/4/4 17:09
19 | */
20 | public class CreateNewFolderAction extends NewUpdateThreadAction {
21 |
22 | public static final Logger log = LoggerFactory.getLogger(CreateNewFolderAction.class);
23 |
24 | private static final String text = MessagesBundle.getText("action.ftp.new-folder.text");
25 | private static final String desc = MessagesBundle.getText("action.ftp.new-folder.description");
26 |
27 | private final FileTableContainer container;
28 |
29 |
30 | public CreateNewFolderAction(FileTableContainer container) {
31 | super(text, desc, AllIcons.Actions.NewFolder);
32 | this.container = container;
33 | }
34 |
35 | @Override
36 | public void actionPerformed(@NotNull AnActionEvent e) {
37 | String folderName = Messages.showInputDialog("Folder Name", "Create Folder", AllIcons.Actions.NewFolder);
38 | if (StringUtil.isEmpty(folderName)) {
39 | return;
40 | }
41 | if (!folderName.startsWith("/")) {
42 | folderName = "/" + folderName;
43 | }
44 | String path = container.getPath() + folderName;
45 | String err = null;
46 | boolean success = false;
47 | try {
48 | success = container.createNewFolder(path);
49 | if (success) {
50 | container.refreshFileList();
51 | }
52 | } catch (IOException ex) {
53 | log.error(ex.getMessage(), e);
54 | err = ex.getMessage();
55 | }
56 | if (!success) {
57 | Messages.showErrorDialog("create directory failed: " + err , "Create Folder Error");
58 | }
59 | }
60 |
61 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/action/ftp/DeleteFileAndDirAction.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.action.ftp;
2 |
3 | import com.intellij.icons.AllIcons;
4 | import com.intellij.openapi.actionSystem.AnActionEvent;
5 | import org.apache.commons.collections.CollectionUtils;
6 | import org.jetbrains.annotations.NotNull;
7 | import tech.lin2j.idea.plugin.action.NewUpdateThreadAction;
8 | import tech.lin2j.idea.plugin.file.TableFile;
9 | import tech.lin2j.idea.plugin.ui.dialog.FilesDeleteConfirmDialog;
10 | import tech.lin2j.idea.plugin.ui.ftp.container.FileTableContainer;
11 | import tech.lin2j.idea.plugin.uitl.MessagesBundle;
12 |
13 | import java.util.List;
14 |
15 | /**
16 | * @author linjinjia
17 | * @date 2024/4/4 17:11
18 | */
19 | public class DeleteFileAndDirAction extends NewUpdateThreadAction {
20 | private static final String text = MessagesBundle.getText("action.ftp.delete.text");
21 | private static final String desc = MessagesBundle.getText("action.ftp.delete.description");
22 |
23 | private final FileTableContainer container;
24 |
25 | public DeleteFileAndDirAction(FileTableContainer container) {
26 | super(text, desc, AllIcons.Actions.Cancel);
27 | this.container = container;
28 | }
29 |
30 | public DeleteFileAndDirAction(int count, FileTableContainer container) {
31 | this(container);
32 | if (count > 1) {
33 | String text = "Delete (" + count + " Selected)";
34 | getTemplatePresentation().setText(text);
35 | }
36 | }
37 |
38 | @Override
39 | public void actionPerformed(@NotNull AnActionEvent e) {
40 | List selectedFiles = container.getSelectedFiles();
41 | if (CollectionUtils.isEmpty(selectedFiles)) {
42 | return;
43 | }
44 |
45 | boolean confirm = new FilesDeleteConfirmDialog(selectedFiles, null).showAndGet();
46 | if (!confirm) {
47 | return;
48 | }
49 |
50 | for (TableFile selectedFile : selectedFiles) {
51 | container.deleteFileAndDir(selectedFile);
52 | }
53 |
54 | container.refreshFileList();
55 | }
56 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/action/ftp/DownloadFileAndDirAction.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.action.ftp;
2 |
3 | import com.intellij.icons.AllIcons;
4 | import com.intellij.openapi.actionSystem.AnActionEvent;
5 | import org.jetbrains.annotations.NotNull;
6 | import tech.lin2j.idea.plugin.action.NewUpdateThreadAction;
7 | import tech.lin2j.idea.plugin.enums.TransferEventType;
8 | import tech.lin2j.idea.plugin.event.ApplicationContext;
9 | import tech.lin2j.idea.plugin.model.event.FileTransferEvent;
10 | import tech.lin2j.idea.plugin.ui.ftp.container.RemoteFileTableContainer;
11 | import tech.lin2j.idea.plugin.uitl.MessagesBundle;
12 |
13 | /**
14 | * @author linjinjia
15 | * @date 2024/4/4 17:24
16 | */
17 | public class DownloadFileAndDirAction extends NewUpdateThreadAction {
18 | private static final String text = MessagesBundle.getText("action.ftp.download.text");
19 | private static final String desc = MessagesBundle.getText("action.ftp.download.description");
20 |
21 | private final RemoteFileTableContainer container;
22 |
23 | public DownloadFileAndDirAction(RemoteFileTableContainer container) {
24 | super(text, desc, AllIcons.Actions.Download);
25 | this.container = container;
26 | }
27 |
28 | public DownloadFileAndDirAction(int count, RemoteFileTableContainer container) {
29 | this(container);
30 | if (count > 1) {
31 | String text = "Download (" + count + " Selected)";
32 | getTemplatePresentation().setText(text);
33 | }
34 | }
35 |
36 |
37 | @Override
38 | public void actionPerformed(@NotNull AnActionEvent e) {
39 | FileTransferEvent event = new FileTransferEvent(container, false, TransferEventType.START);
40 | ApplicationContext.getApplicationContext().publishEvent(event);
41 | }
42 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/action/ftp/FileAction.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.action.ftp;
2 |
3 | import com.intellij.openapi.actionSystem.AnActionEvent;
4 | import org.apache.commons.collections.CollectionUtils;
5 | import org.jetbrains.annotations.NotNull;
6 | import tech.lin2j.idea.plugin.action.NewUpdateThreadAction;
7 | import tech.lin2j.idea.plugin.file.TableFile;
8 | import tech.lin2j.idea.plugin.ui.ftp.container.FileTableContainer;
9 |
10 | import java.util.List;
11 |
12 | /**
13 | *
14 | *
15 | * @author linjinjia
16 | * @date 2024/5/24 21:38
17 | */
18 | public abstract class FileAction extends NewUpdateThreadAction {
19 |
20 | public FileTableContainer container;
21 |
22 | protected FileAction(String text, FileTableContainer container) {
23 | super(text);
24 | this.container = container;
25 | }
26 |
27 | @Override
28 | public void actionPerformed(@NotNull AnActionEvent e) {
29 | List files = container.getSelectedFiles();
30 | if (CollectionUtils.isEmpty(files)) {
31 | return;
32 | }
33 | handle(files.get(0));
34 | }
35 |
36 | protected abstract void handle(TableFile file);
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/action/ftp/FilePropertiesAction.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.action.ftp;
2 |
3 | import com.intellij.icons.AllIcons;
4 | import tech.lin2j.idea.plugin.file.TableFile;
5 | import tech.lin2j.idea.plugin.ui.dialog.FilePropertiesDialog;
6 | import tech.lin2j.idea.plugin.ui.ftp.container.FileTableContainer;
7 | import tech.lin2j.idea.plugin.uitl.MessagesBundle;
8 |
9 | /**
10 | *
11 | * @author linjinjia
12 | * @date 2024/5/24 21:43
13 | */
14 | public class FilePropertiesAction extends FileAction {
15 | private static final String text = MessagesBundle.getText("action.ftp.popup.properties.text");
16 |
17 | public FilePropertiesAction(FileTableContainer container) {
18 | super(text, container);
19 | getTemplatePresentation().setIcon(AllIcons.Actions.Properties);
20 | }
21 |
22 | @Override
23 | protected void handle(TableFile file) {
24 | new FilePropertiesDialog(file).show();
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/action/ftp/GoToDesktopAction.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.action.ftp;
2 |
3 | import com.intellij.icons.AllIcons;
4 | import com.intellij.openapi.actionSystem.AnActionEvent;
5 | import com.intellij.openapi.vfs.VirtualFile;
6 | import org.jetbrains.annotations.NotNull;
7 | import tech.lin2j.idea.plugin.action.NewUpdateThreadAction;
8 | import tech.lin2j.idea.plugin.ui.ftp.container.LocalFileTableContainer;
9 | import tech.lin2j.idea.plugin.uitl.MessagesBundle;
10 |
11 | /**
12 | * @author linjinjia
13 | * @date 2024/4/4 16:20
14 | */
15 | public class GoToDesktopAction extends NewUpdateThreadAction {
16 | private static final String text = MessagesBundle.getText("action.ftp.desktop.text");
17 | private static final String desc = MessagesBundle.getText("action.ftp.desktop.description");
18 |
19 | private final LocalFileTableContainer container;
20 |
21 | public GoToDesktopAction(LocalFileTableContainer container) {
22 | super(text, desc, AllIcons.Nodes.Desktop);
23 | this.container = container;
24 | }
25 |
26 | @Override
27 | public void actionPerformed(@NotNull AnActionEvent e) {
28 | VirtualFile desktop = container.getDesktopDirectory();
29 | if (desktop != null) {
30 | container.setPath(desktop.getPath());
31 | }
32 | }
33 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/action/ftp/GoToParentFolderAction.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.action.ftp;
2 |
3 | import com.intellij.icons.AllIcons;
4 | import com.intellij.openapi.actionSystem.AnActionEvent;
5 | import org.jetbrains.annotations.NotNull;
6 | import tech.lin2j.idea.plugin.action.NewUpdateThreadAction;
7 | import tech.lin2j.idea.plugin.ui.ftp.container.FileTableContainer;
8 | import tech.lin2j.idea.plugin.uitl.MessagesBundle;
9 |
10 | /**
11 | * @author linjinjia
12 | * @date 2024/4/4 16:40
13 | */
14 | public class GoToParentFolderAction extends NewUpdateThreadAction {
15 | private static final String text = MessagesBundle.getText("action.ftp.parent.text");
16 | private static final String desc = MessagesBundle.getText("action.ftp.parent.description");
17 |
18 |
19 | private final FileTableContainer container;
20 |
21 | public GoToParentFolderAction(FileTableContainer container) {
22 | super(text, desc, AllIcons.Actions.Rollback);
23 | this.container = container;
24 | }
25 |
26 | @Override
27 | public void actionPerformed(@NotNull AnActionEvent e) {
28 | container.setPath(container.getParentPath());
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/action/ftp/HomeDirectoryAction.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.action.ftp;
2 |
3 | import com.intellij.icons.AllIcons;
4 | import com.intellij.openapi.actionSystem.AnActionEvent;
5 | import com.intellij.openapi.util.text.StringUtil;
6 | import org.jetbrains.annotations.NotNull;
7 | import tech.lin2j.idea.plugin.action.NewUpdateThreadAction;
8 | import tech.lin2j.idea.plugin.ui.ftp.container.FileTableContainer;
9 | import tech.lin2j.idea.plugin.uitl.MessagesBundle;
10 |
11 | /**
12 | * @author linjinjia
13 | * @date 2024/4/4 16:19
14 | */
15 | public class HomeDirectoryAction extends NewUpdateThreadAction {
16 | private static final String text = MessagesBundle.getText("action.ftp.home.text");
17 | private static final String desc = MessagesBundle.getText("action.ftp.home.description");
18 |
19 | private final FileTableContainer container;
20 |
21 | public HomeDirectoryAction(FileTableContainer container) {
22 | super(text, desc, AllIcons.Nodes.HomeFolder);
23 | this.container = container;
24 | }
25 |
26 | @Override
27 | public void actionPerformed(@NotNull AnActionEvent e) {
28 | if (StringUtil.isEmpty(container.getHomePath())) {
29 | return;
30 | }
31 | container.setPath(container.getHomePath());
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/action/ftp/OpenFilePathAction.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.action.ftp;
2 |
3 | import com.intellij.openapi.actionSystem.AnActionEvent;
4 | import com.intellij.openapi.ui.Messages;
5 | import com.intellij.openapi.util.SystemInfo;
6 | import org.jetbrains.annotations.NotNull;
7 | import tech.lin2j.idea.plugin.action.NewUpdateThreadAction;
8 | import tech.lin2j.idea.plugin.file.TableFile;
9 | import tech.lin2j.idea.plugin.ui.ftp.container.FileTableContainer;
10 | import tech.lin2j.idea.plugin.uitl.FileUtil;
11 | import tech.lin2j.idea.plugin.uitl.MessagesBundle;
12 |
13 | import javax.swing.SwingUtilities;
14 | import java.io.IOException;
15 | import java.util.List;
16 |
17 | /**
18 | *
19 | * @author linjinjia
20 | * @date 2024/7/15 22:37
21 | */
22 | public class OpenFilePathAction extends NewUpdateThreadAction {
23 |
24 | private static final String winText = MessagesBundle.getText("action.ftp.popup.open-in-win.text");
25 | private static final String macText = MessagesBundle.getText("action.ftp.popup.open-in-mac.text");
26 | private static final String text = SystemInfo.isMac ? macText : winText;
27 | private static final String desc = MessagesBundle.getText("action.ftp.popup.open-in.desc");
28 | private static final String errorTitle = MessagesBundle.getText("action.ftp.popup.open-in.error.title");
29 | private static final String errorTip = MessagesBundle.getText("action.ftp.popup.open-in.error.tip");
30 |
31 | private final FileTableContainer tableContainer;
32 |
33 | public OpenFilePathAction(FileTableContainer tableContainer) {
34 | super(text, desc, null);
35 | this.tableContainer = tableContainer;
36 | }
37 |
38 | @Override
39 | public void actionPerformed(@NotNull AnActionEvent e) {
40 | String targetPath = tableContainer.getPath();
41 | try {
42 | List files = tableContainer.getSelectedFiles();
43 | if (files != null && files.size() > 0 && files.get(0).isDirectory()) {
44 | targetPath = files.get(0).getFilePath();
45 | }
46 | FileUtil.openDir(targetPath);
47 | } catch (IOException ex) {
48 | SwingUtilities.invokeLater(() -> Messages.showErrorDialog(errorTip + ex.getMessage(), errorTitle));
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/action/ftp/OpenPathInTerminalAction.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.action.ftp;
2 |
3 | import com.intellij.openapi.actionSystem.AnActionEvent;
4 | import com.intellij.openapi.project.Project;
5 | import org.jetbrains.annotations.NotNull;
6 | import tech.lin2j.idea.plugin.action.NewUpdateThreadAction;
7 | import tech.lin2j.idea.plugin.action.OpenTerminalAction;
8 | import tech.lin2j.idea.plugin.file.TableFile;
9 | import tech.lin2j.idea.plugin.ui.ftp.container.RemoteFileTableContainer;
10 | import tech.lin2j.idea.plugin.uitl.MessagesBundle;
11 |
12 | import java.util.List;
13 |
14 | /**
15 | * @author linjinjia
16 | * @date 2024/7/10 22:20
17 | */
18 | public class OpenPathInTerminalAction extends NewUpdateThreadAction {
19 |
20 | private static final String text = MessagesBundle.getText("action.ftp.popup.open-in-ftp.text");
21 | private static final String desc = MessagesBundle.getText("action.ftp.popup.open-in-ftp.desc");
22 |
23 | private final RemoteFileTableContainer tableContainer;
24 |
25 | public OpenPathInTerminalAction(RemoteFileTableContainer tableContainer) {
26 | super(text, desc, null);
27 | this.tableContainer = tableContainer;
28 | }
29 |
30 | @Override
31 | public void actionPerformed(@NotNull AnActionEvent e) {
32 | String workingDirectory = tableContainer.getPath();
33 | List files = tableContainer.getSelectedFiles();
34 | if (files != null && files.size() > 0 && files.get(0).isDirectory()) {
35 | workingDirectory = files.get(0).getFilePath();
36 | }
37 | Integer sshId = tableContainer.getSshId();
38 | Project project = tableContainer.getProject();
39 |
40 | new OpenTerminalAction(sshId, project, workingDirectory).actionPerformed(null);
41 | }
42 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/action/ftp/ProjectPathAction.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.action.ftp;
2 |
3 | import com.intellij.icons.AllIcons;
4 | import com.intellij.openapi.actionSystem.AnActionEvent;
5 | import org.jetbrains.annotations.NotNull;
6 | import tech.lin2j.idea.plugin.action.NewUpdateThreadAction;
7 | import tech.lin2j.idea.plugin.ui.ftp.container.LocalFileTableContainer;
8 | import tech.lin2j.idea.plugin.uitl.MessagesBundle;
9 |
10 | /**
11 | * @author linjinjia
12 | * @date 2024/4/25 22:47
13 | */
14 | public class ProjectPathAction extends NewUpdateThreadAction {
15 | private static final String text = MessagesBundle.getText("action.ftp.project.text");
16 | private static final String desc = MessagesBundle.getText("action.ftp.project.description");
17 |
18 | public LocalFileTableContainer container;
19 |
20 | public ProjectPathAction(LocalFileTableContainer container) {
21 | super(text, desc, AllIcons.Actions.ProjectDirectory);
22 | this.container = container;
23 | }
24 |
25 | @Override
26 | public void actionPerformed(@NotNull AnActionEvent e) {
27 | container.setPath(container.getProject().getBasePath());
28 | }
29 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/action/ftp/RefreshFolderAction.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.action.ftp;
2 |
3 | import com.intellij.icons.AllIcons;
4 | import com.intellij.openapi.actionSystem.AnActionEvent;
5 | import org.jetbrains.annotations.NotNull;
6 | import tech.lin2j.idea.plugin.action.NewUpdateThreadAction;
7 | import tech.lin2j.idea.plugin.ui.ftp.container.FileTableContainer;
8 | import tech.lin2j.idea.plugin.uitl.MessagesBundle;
9 |
10 | /**
11 | * @author linjinjia
12 | * @date 2024/4/4 17:13
13 | */
14 | public class RefreshFolderAction extends NewUpdateThreadAction {
15 | private static final String text = MessagesBundle.getText("action.ftp.refresh.text");
16 | private static final String desc = MessagesBundle.getText("action.ftp.refresh.description");
17 |
18 | private final FileTableContainer container;
19 |
20 | public RefreshFolderAction(FileTableContainer container) {
21 | super(text, desc, AllIcons.Actions.Refresh);
22 | this.container = container;
23 | }
24 |
25 | @Override
26 | public void actionPerformed(@NotNull AnActionEvent e) {
27 | container.refreshFileList();
28 | }
29 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/action/ftp/RowDoubleClickAction.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.action.ftp;
2 |
3 | import com.intellij.ui.DoubleClickListener;
4 | import tech.lin2j.idea.plugin.enums.SFTPAction;
5 | import tech.lin2j.idea.plugin.enums.TransferEventType;
6 | import tech.lin2j.idea.plugin.event.ApplicationContext;
7 | import tech.lin2j.idea.plugin.file.TableFile;
8 | import tech.lin2j.idea.plugin.model.ConfigHelper;
9 | import tech.lin2j.idea.plugin.model.PluginSetting;
10 | import tech.lin2j.idea.plugin.model.event.FileTransferEvent;
11 | import tech.lin2j.idea.plugin.ui.dialog.FilePropertiesDialog;
12 | import tech.lin2j.idea.plugin.ui.ftp.container.FileTableContainer;
13 |
14 | import java.awt.event.MouseEvent;
15 |
16 | /**
17 | * @author linjinjia
18 | * @date 2024/4/6 14:03
19 | */
20 | public class RowDoubleClickAction extends DoubleClickListener {
21 |
22 | private final PluginSetting setting = ConfigHelper.pluginSetting();
23 |
24 | private final FileTableContainer container;
25 |
26 | public RowDoubleClickAction(FileTableContainer container) {
27 | this.container = container;
28 | }
29 |
30 | @Override
31 | protected boolean onDoubleClick(MouseEvent e) {
32 | int selected = container.getTable().getSelectedRow();
33 | if (selected == -1) {
34 | return false;
35 | }
36 | TableFile tf = container.getFileList().get(selected);
37 | if (!tf.isDirectory()) {
38 | SFTPAction action = setting.getDoubleClickAction();
39 | if (action == SFTPAction.Properties) {
40 | new FilePropertiesDialog(tf).show();
41 | } else if (action == SFTPAction.Transfer) {
42 | boolean isUpload = container.isLocal();
43 | FileTransferEvent event = new FileTransferEvent(container, isUpload, TransferEventType.START);
44 | ApplicationContext.getApplicationContext().publishEvent(event);
45 | }
46 | return true;
47 | }
48 |
49 | container.setPath(tf.getFilePath());
50 | return true;
51 | }
52 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/action/ftp/ShowHiddenFileAndDirAction.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.action.ftp;
2 |
3 | import com.intellij.openapi.actionSystem.ActionUpdateThread;
4 | import com.intellij.openapi.actionSystem.AnActionEvent;
5 | import com.intellij.openapi.actionSystem.ToggleAction;
6 | import icons.MyIcons;
7 | import org.jetbrains.annotations.NotNull;
8 | import tech.lin2j.idea.plugin.ui.ftp.container.FileTableContainer;
9 | import tech.lin2j.idea.plugin.uitl.MessagesBundle;
10 |
11 | /**
12 | * @author linjinjia
13 | * @date 2024/4/4 17:14
14 | */
15 | public class ShowHiddenFileAndDirAction extends ToggleAction {
16 | private static final String text = MessagesBundle.getText("action.ftp.hidden.text");
17 | private static final String desc = MessagesBundle.getText("action.ftp.hidden.description");
18 |
19 | private final FileTableContainer container;
20 |
21 | public ShowHiddenFileAndDirAction(FileTableContainer container) {
22 | super(text, desc, MyIcons.Actions.showHidden);
23 | this.container = container;
24 | }
25 |
26 | @Override
27 | public boolean isSelected(@NotNull AnActionEvent e) {
28 | return !container.showHiddenFileAndDir();
29 | }
30 |
31 | @Override
32 | public void setSelected(@NotNull AnActionEvent e, boolean state) {
33 | container.reversedHiddenFlag();
34 | container.refreshFileList();
35 | }
36 |
37 | @Override
38 | public void update(@NotNull AnActionEvent e) {
39 | super.update(e);
40 | }
41 |
42 | @Override
43 | public @NotNull ActionUpdateThread getActionUpdateThread() {
44 | return ActionUpdateThread.BGT;
45 | }
46 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/action/ftp/UploadFileAndDirAction.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.action.ftp;
2 |
3 | import com.intellij.icons.AllIcons;
4 | import com.intellij.openapi.actionSystem.AnActionEvent;
5 | import org.jetbrains.annotations.NotNull;
6 | import tech.lin2j.idea.plugin.action.NewUpdateThreadAction;
7 | import tech.lin2j.idea.plugin.enums.TransferEventType;
8 | import tech.lin2j.idea.plugin.event.ApplicationContext;
9 | import tech.lin2j.idea.plugin.model.event.FileTransferEvent;
10 | import tech.lin2j.idea.plugin.ui.ftp.container.LocalFileTableContainer;
11 | import tech.lin2j.idea.plugin.uitl.MessagesBundle;
12 |
13 | /**
14 | * @author linjinjia
15 | * @date 2024/4/4 17:12
16 | */
17 | public class UploadFileAndDirAction extends NewUpdateThreadAction {
18 | private static final String text = MessagesBundle.getText("action.ftp.upload.text");
19 | private static final String desc = MessagesBundle.getText("action.ftp.upload.description");
20 |
21 | private final LocalFileTableContainer localContainer;
22 |
23 | public UploadFileAndDirAction(LocalFileTableContainer localContainer) {
24 | super(text, desc, AllIcons.Actions.Upload);
25 | this.localContainer = localContainer;
26 | }
27 |
28 | public UploadFileAndDirAction(int count, LocalFileTableContainer localContainer) {
29 | this(localContainer);
30 | if (count > 1) {
31 | String text = "Upload (" + count + " Selected)";
32 | getTemplatePresentation().setText(text);
33 | }
34 | }
35 |
36 | @Override
37 | public void actionPerformed(@NotNull AnActionEvent e) {
38 | FileTransferEvent event = new FileTransferEvent(localContainer, true, TransferEventType.START);
39 | ApplicationContext.getApplicationContext().publishEvent(event);
40 | }
41 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/enums/AuthType.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.enums;
2 |
3 | /**
4 | * @author linjinjia
5 | * @date 2022/12/3 13:23
6 | */
7 | public enum AuthType {
8 |
9 | /**
10 | * Using a password for authentication
11 | */
12 | PASSWORD(1, "password"),
13 |
14 | /**
15 | * Using a private key for authentication
16 | */
17 | PEM_PRIVATE_KEY(2, "private key");
18 |
19 | private final Integer code;
20 | private final String desc;
21 |
22 | AuthType(Integer code, String desc) {
23 | this.code = code;
24 | this.desc = desc;
25 | }
26 |
27 | public Integer getCode() {
28 | return code;
29 | }
30 |
31 | public String getDesc() {
32 | return desc;
33 | }
34 |
35 | /**
36 | * @param code code of authenticate type
37 | * @return true if the code represents
38 | * authenticate with password
39 | */
40 | public static boolean needPassword(Integer code) {
41 | // the code parameter may be null
42 | // because server info stored in the
43 | // configuration has no authType value
44 | return code == null || PASSWORD.getCode().equals(code);
45 | }
46 |
47 | /**
48 | * @param code code of authenticate type
49 | * @return true if the code represents
50 | * authenticate with pem private key
51 | */
52 | public static boolean needPemPrivateKey(Integer code) {
53 | return PEM_PRIVATE_KEY.getCode().equals(code);
54 | }
55 |
56 | @Override
57 | public String toString() {
58 | return code.toString();
59 | }
60 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/enums/Constant.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.enums;
2 |
3 | import tech.lin2j.idea.plugin.model.UploadProfile;
4 |
5 | /**
6 | * @author linjinjia
7 | * @date 2024/7/21 16:07
8 | */
9 | public interface Constant {
10 |
11 | String EASY_DEPLOY = "EasyDeploy";
12 |
13 | String UPDATE_CHECKER_PROPERTY = "easy-deploy.statistics.timestamp";
14 |
15 | String STR_FALSE = "0";
16 |
17 | String STR_TRUE = "1";
18 |
19 | /**
20 | * default top inset of form item
21 | */
22 | int DEFAULT_TOP_INSET = 20;
23 |
24 | /**
25 | * The prefix of run tab title
26 | */
27 | String RUN_TAB_PREFIX = "ED@";
28 |
29 | /**
30 | * Separator of multiple local file paths
31 | */
32 | String LOCAL_FILE_SEPARATOR = "\n";
33 |
34 | /**
35 | * Path and identifier separation in {@link UploadProfile}
36 | */
37 | String LOCAL_FILE_INFO_SEPARATOR = "::";
38 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/enums/I18nType.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.enums;
2 |
3 | /**
4 | * @author linjinjia
5 | * @date 2024/6/29 21:25
6 | */
7 | public enum I18nType {
8 |
9 | English(0, "English"),
10 | Chinese(1, "简体中文"),
11 | ;
12 |
13 | private final Integer type;
14 | private final String text;
15 |
16 | I18nType(Integer type, String text) {
17 | this.type = type;
18 | this.text = text;
19 | }
20 |
21 | public static I18nType getByType(int type) {
22 | for (I18nType value : values()) {
23 | if (value.getType().equals(type)) {
24 | return value;
25 | }
26 | }
27 | return English;
28 | }
29 |
30 | public Integer getType() {
31 | return type;
32 | }
33 |
34 | public String getText() {
35 | return text;
36 | }
37 |
38 | @Override
39 | public String toString() {
40 | return text;
41 | }
42 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/enums/SFTPAction.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.enums;
2 |
3 | import java.util.Arrays;
4 | import java.util.List;
5 |
6 | /**
7 | * @author linjinjia
8 | * @date 2024/5/25 10:12
9 | */
10 | public enum SFTPAction {
11 |
12 | NONE, Transfer, Properties;
13 |
14 | public static List asList() {
15 | return Arrays.asList(SFTPAction.values());
16 | }
17 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/enums/TransferEventType.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.enums;
2 |
3 | /**
4 | * @author linjinjia
5 | * @date 2024/4/13 16:25
6 | */
7 | public enum TransferEventType {
8 |
9 | START,
10 | END
11 |
12 | ;
13 |
14 | public boolean isEnd() {
15 | return this == END;
16 | }
17 |
18 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/enums/TransferMode.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.enums;
2 |
3 | public enum TransferMode {
4 |
5 | SFTP(0, "SFTP"),
6 | SCP(1, "SCP"),
7 | ;
8 |
9 | private final int type;
10 | private final String text;
11 |
12 | TransferMode(int type, String text) {
13 | this.type = type;
14 | this.text = text;
15 | }
16 |
17 | public static TransferMode getByType(int type) {
18 | for (TransferMode value : values()) {
19 | if (value.getType().equals(type)) {
20 | return value;
21 | }
22 | }
23 | return SFTP;
24 | }
25 |
26 | public Integer getType() {
27 | return type;
28 | }
29 |
30 | public String getText() {
31 | return text;
32 | }
33 |
34 | @Override
35 | public String toString() {
36 | return text;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/enums/TransferState.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.enums;
2 |
3 | /**
4 | * @author linjinjia
5 | * @date 2024/4/16 22:23
6 | */
7 | public enum TransferState {
8 |
9 | UPLOADED("Uploaded", null),
10 | DOWNLOADED("Downloaded", null),
11 | UPLOADING("Uploading", UPLOADED),
12 | DOWNLOADING("Downloading", DOWNLOADED),
13 |
14 | FAILED("Failed", null),
15 | ;
16 |
17 | private final String desc;
18 | private final TransferState nextState;
19 |
20 | TransferState(String desc, TransferState nextState) {
21 | this.desc = desc;
22 | this.nextState = nextState;
23 | }
24 |
25 | public TransferState nextState() {
26 | if (nextState == null) {
27 | return this;
28 | }
29 | return nextState;
30 | }
31 |
32 | @Override
33 | public String toString() {
34 | return desc;
35 | }
36 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/event/ApplicationContext.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.event;
2 |
3 | import com.intellij.openapi.diagnostic.Logger;
4 |
5 | import java.util.Set;
6 | import java.util.concurrent.CopyOnWriteArraySet;
7 |
8 | /**
9 | * @author linjinjia
10 | * @date 2022/4/27 10:30
11 | */
12 | public class ApplicationContext implements ApplicationPublisher {
13 |
14 | private static final Logger log = Logger.getInstance(ApplicationContext.class);
15 |
16 | private static final ApplicationContext APPLICATION_CONTEXT = new ApplicationContext();
17 |
18 | private final Set> listeners = new CopyOnWriteArraySet<>();
19 |
20 | public void addApplicationListener(ApplicationListener> listener) {
21 | listeners.add(listener);
22 | }
23 |
24 | public void removeApplicationListener(ApplicationListener> listener) {
25 | listeners.remove(listener);
26 | }
27 |
28 |
29 | @SuppressWarnings({"rawtypes", "unchecked"})
30 | @Override
31 | public void publishEvent(Object event) {
32 | ApplicationEvent applicationEvent;
33 | if (event instanceof ApplicationEvent) {
34 | applicationEvent = (ApplicationEvent) event;
35 | } else {
36 | if (log.isDebugEnabled()) {
37 | log.debug("event is not ApplicationEvent");
38 | }
39 | return;
40 | }
41 | for (final ApplicationListener listener : listeners) {
42 | try {
43 | listener.onApplicationEvent(applicationEvent);
44 | } catch (ClassCastException e) {
45 | if (log.isDebugEnabled()) {
46 | log.debug("Non-matching event type for listener: " + listener, e);
47 | }
48 | }
49 | }
50 | }
51 |
52 | public static ApplicationContext getApplicationContext() {
53 | return APPLICATION_CONTEXT;
54 | }
55 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/event/ApplicationEvent.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.event;
2 |
3 |
4 | import java.util.EventObject;
5 |
6 | /**
7 | * @author linjinjia
8 | * @date 2022/4/27 10:21
9 | */
10 | public class ApplicationEvent extends EventObject {
11 |
12 | public ApplicationEvent(Object source) {
13 | super(source);
14 | }
15 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/event/ApplicationListener.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.event;
2 |
3 | import java.util.EventListener;
4 |
5 | /**
6 | * @author linjinjia
7 | * @date 2022/4/27 10:22
8 | */
9 | @FunctionalInterface
10 | public interface ApplicationListener extends EventListener {
11 | void onApplicationEvent(E event);
12 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/event/ApplicationPublisher.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.event;
2 |
3 | /**
4 | * @author linjinjia
5 | * @date 2022/4/27 10:24
6 | */
7 | @FunctionalInterface
8 | public interface ApplicationPublisher {
9 |
10 | default void publishEvent(ApplicationEvent event) {
11 | publishEvent((Object) event);
12 | }
13 |
14 | void publishEvent(Object event);
15 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/event/listener/UploadProfileSelectedListener.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.event.listener;
2 |
3 | import tech.lin2j.idea.plugin.event.ApplicationListener;
4 | import tech.lin2j.idea.plugin.model.ConfigHelper;
5 | import tech.lin2j.idea.plugin.model.UploadProfile;
6 | import tech.lin2j.idea.plugin.model.event.UploadProfileSelectedEvent;
7 |
8 | import java.util.Objects;
9 |
10 | /**
11 | * @author linjinjia
12 | * @date 2022/5/24 17:54
13 | */
14 | public class UploadProfileSelectedListener implements ApplicationListener {
15 | @Override
16 | public void onApplicationEvent(UploadProfileSelectedEvent event) {
17 | UploadProfile profile = (UploadProfile) event.getSource();
18 | ConfigHelper.getUploadProfileBySshId(profile.getSshId()).forEach(s -> {
19 | if (!Objects.equals(profile, s)) {
20 | s.setSelected(false);
21 | }
22 | });
23 | }
24 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/exception/IllegalFileTypeException.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.exception;
2 |
3 | /**
4 | * @author linjinjia
5 | * @date 2024/11/16 23:01
6 | */
7 | public class IllegalFileTypeException extends IllegalArgumentException {
8 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/factory/CustomTtyConnectorFactory.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.factory;
2 |
3 | import org.slf4j.Logger;
4 | import org.slf4j.LoggerFactory;
5 | import tech.lin2j.idea.plugin.ssh.CustomTtyConnector;
6 | import tech.lin2j.idea.plugin.ssh.SshConnectionManager;
7 | import tech.lin2j.idea.plugin.ssh.SshServer;
8 | import tech.lin2j.idea.plugin.ssh.exception.RemoteSdkException;
9 | import tech.lin2j.idea.plugin.ssh.sshj.SshjConnection;
10 | import tech.lin2j.idea.plugin.ssh.sshj.SshjTtyConnector;
11 |
12 | import java.io.IOException;
13 |
14 | /**
15 | * @author linjinjia
16 | * @date 2022/6/25 11:29
17 | */
18 | public class CustomTtyConnectorFactory {
19 |
20 | public static final Logger LOG = LoggerFactory.getLogger(CustomTtyConnectorFactory.class);
21 |
22 | /**
23 | * return a tty connector
24 | * @param type implementation of ssh2, {@link CustomTtyConnector}
25 | * @param server server information
26 | * @return tty connector
27 | */
28 | public static CustomTtyConnector getCustomTtyConnector(String type,
29 | SshServer server,
30 | String workingDirectory) throws RemoteSdkException {
31 | if (CustomTtyConnector.SSHJ.equals(type)) {
32 | try {
33 | SshjConnection connection = SshConnectionManager.makeSshjConnection(server);
34 | return new SshjTtyConnector(connection, workingDirectory);
35 | } catch (IOException e) {
36 | LOG.error("Error connecting server: {}", e.getMessage());
37 | throw new RemoteSdkException("Error connecting server: " + e.getMessage(), e);
38 | }
39 | }
40 | throw new IllegalArgumentException(type);
41 | }
42 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/factory/DeployConsoleToolWindowFactory.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.factory;
2 |
3 | import com.intellij.openapi.project.Project;
4 | import com.intellij.openapi.wm.ToolWindow;
5 | import com.intellij.openapi.wm.ToolWindowFactory;
6 | import com.intellij.openapi.wm.ex.ToolWindowManagerListener;
7 | import com.intellij.ui.content.Content;
8 | import com.intellij.ui.content.ContentFactory;
9 | import org.jetbrains.annotations.NotNull;
10 | import tech.lin2j.idea.plugin.event.ApplicationContext;
11 | import tech.lin2j.idea.plugin.event.listener.UploadProfileSelectedListener;
12 | import tech.lin2j.idea.plugin.ui.module.ConsoleLogView;
13 | import tech.lin2j.idea.plugin.ui.module.DashboardView;
14 |
15 | /**
16 | * @author linjinjia
17 | * @date 2022/4/24 16:07
18 | */
19 | public class DeployConsoleToolWindowFactory implements ToolWindowFactory {
20 |
21 | @Override
22 | public void createToolWindowContent(@NotNull Project project, @NotNull ToolWindow toolWindow) {
23 | ContentFactory contentFactory = ContentFactory.getInstance();
24 | // deploy tab
25 | DashboardView dashboardView = new DashboardView(project);
26 | Content deploy = contentFactory.createContent(dashboardView, "Dashboard", false);
27 | toolWindow.getContentManager().addContent(deploy);
28 | // messages tab
29 | ConsoleLogView commandExecuteView = new ConsoleLogView(project);
30 | commandExecuteView.attachProject();
31 | Content messages = contentFactory.createContent(commandExecuteView, "Console", false);
32 | toolWindow.getContentManager().addContent(messages);
33 |
34 | // make sure every time you click on the tool window is the console
35 | project.getMessageBus().connect().subscribe(ToolWindowManagerListener.TOPIC, new ToolWindowManagerListener() {
36 | @Override
37 | public void stateChanged() {
38 | boolean messagesSelected = toolWindow.getContentManager().isSelected(messages);
39 | if (!toolWindow.isVisible() && messagesSelected) {
40 | toolWindow.getContentManager().setSelectedContent(deploy);
41 | }
42 | }
43 | });
44 |
45 | ApplicationContext.getApplicationContext().addApplicationListener(dashboardView.getConsoleUi());
46 | ApplicationContext.getApplicationContext().addApplicationListener(new UploadProfileSelectedListener());
47 | }
48 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/file/ConsoleTransferListener.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.file;
2 |
3 | import com.intellij.openapi.util.text.StringUtil;
4 | import net.schmizz.sshj.common.StreamCopier;
5 | import net.schmizz.sshj.xfer.TransferListener;
6 | import tech.lin2j.idea.plugin.ssh.CommandLog;
7 | import tech.lin2j.idea.plugin.uitl.FileTransferSpeed;
8 |
9 | import java.util.stream.Stream;
10 |
11 | /**
12 | * @author linjinjia
13 | * @date 2024/4/13 16:09
14 | */
15 | public class ConsoleTransferListener implements TransferListener {
16 | private final String relPath;
17 | private final CommandLog console;
18 | private final FileTransferSpeed fileTransferSpeed = new FileTransferSpeed();
19 |
20 | public ConsoleTransferListener(String relPath, CommandLog console) {
21 | if (!relPath.endsWith("/")) {
22 | relPath += "/";
23 | }
24 | this.relPath = relPath;
25 | this.console = console;
26 | }
27 |
28 | @Override
29 | public TransferListener directory(String name) {
30 | return new ConsoleTransferListener(relPath + name + "/", console);
31 | }
32 |
33 | @Override
34 | public StreamCopier.Listener file(final String name, final long size) {
35 | String path = relPath + name;
36 | console.info("Transfer file: " + path + ", Size: " + StringUtil.formatFileSize(size) + "\n");
37 | return transferred -> {
38 | String speed = fileTransferSpeed.accept(transferred);
39 |
40 | double fileProgress = 0;
41 | if (size > 0) {
42 | fileProgress = transferred / (double) size;
43 | }
44 | boolean fileCompleted = Math.abs(1 - fileProgress) < 1e-6;
45 | printProgress((int) (fileProgress * 100), fileCompleted, speed);
46 |
47 | };
48 | }
49 |
50 | private void printProgress(int complete, boolean completed, String speed) {
51 | StringBuilder sb = new StringBuilder("[");
52 | Stream.generate(() -> '#').limit(complete).forEach(sb::append);
53 | Stream.generate(() -> '_').limit(100 - complete).forEach(sb::append);
54 | sb.append("] ");
55 | if (completed) {
56 | sb.append("complete, speed: ").append(speed).append("\n");
57 | } else {
58 | sb.append(complete).append("% , speed: ").append(speed);
59 | }
60 | console.print("\r");
61 | console.print(sb.toString());
62 | }
63 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/file/DirectoryInfo.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.file;
2 |
3 | /**
4 | * @author linjinjia
5 | * @date 2024/4/18 06:37
6 | */
7 | public class DirectoryInfo {
8 |
9 | private long size;
10 | private int files;
11 | private boolean isDirectory;
12 |
13 | public long getSize() {
14 | return size;
15 | }
16 |
17 | public void setSize(long size) {
18 | this.size = size;
19 | }
20 |
21 | public int getFiles() {
22 | return files;
23 | }
24 |
25 | public void setFiles(int files) {
26 | this.files = files;
27 | }
28 |
29 | public boolean isDirectory() {
30 | return isDirectory;
31 | }
32 |
33 | public void setDirectory(boolean directory) {
34 | isDirectory = directory;
35 | }
36 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/file/TableFile.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.file;
2 |
3 | import org.jetbrains.annotations.NotNull;
4 |
5 | import javax.swing.Icon;
6 |
7 | /**
8 | * @author linjinjia
9 | * @date 2024/4/6 10:08
10 | */
11 | public interface TableFile extends Comparable {
12 |
13 | Icon getIcon();
14 |
15 | String getName();
16 |
17 | String getSize();
18 |
19 | String getType();
20 |
21 | String getCreated();
22 |
23 | boolean readOnly();
24 |
25 | String getModified();
26 |
27 | boolean isDirectory();
28 |
29 | default boolean isHidden() {
30 | return getName().startsWith(".") || getName().startsWith("$");
31 | }
32 |
33 | String getParent();
34 |
35 | String getFilePath();
36 |
37 | @Override
38 | default int compareTo(@NotNull TableFile f2) {
39 | if (this.isDirectory() && !f2.isDirectory()) {
40 | return -1;
41 | }
42 | if (!this.isDirectory() && f2.isDirectory()) {
43 | return 1;
44 | }
45 | return this.getName().compareTo(f2.getName());
46 | }
47 |
48 | default String getAccess() {
49 | return "";
50 | }
51 |
52 | default String getOwner() {
53 | return "";
54 | }
55 |
56 | default String getGroup() {
57 | return "";
58 | }
59 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/file/fileTypes/ConfigFileType.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.file.fileTypes;
2 |
3 | import com.intellij.icons.AllIcons;
4 | import com.intellij.openapi.fileTypes.FileType;
5 | import com.intellij.openapi.vfs.VirtualFile;
6 | import org.jetbrains.annotations.NotNull;
7 | import org.jetbrains.annotations.Nullable;
8 |
9 | import javax.swing.Icon;
10 |
11 | /**
12 | * @author linjinjia
13 | * @date 2024/4/21 15:19
14 | */
15 | public class ConfigFileType implements FileType {
16 |
17 | public static final ConfigFileType INSTANCE = new ConfigFileType();
18 |
19 | @NotNull
20 | @Override
21 | public String getName() {
22 | return "Config";
23 | }
24 |
25 | @NotNull
26 | @Override
27 | public String getDescription() {
28 | return "Config";
29 | }
30 |
31 | @NotNull
32 | @Override
33 | public String getDefaultExtension() {
34 | return "cfg";
35 | }
36 |
37 | @Nullable
38 | @Override
39 | public Icon getIcon() {
40 | return AllIcons.FileTypes.Config;
41 | }
42 |
43 | @Override
44 | public boolean isBinary() {
45 | return false;
46 | }
47 |
48 | @Override
49 | public boolean isReadOnly() {
50 | return false;
51 | }
52 |
53 | @Nullable
54 | @Override
55 | public String getCharset(@NotNull VirtualFile file, @NotNull byte[] content) {
56 | return null;
57 | }
58 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/file/fileTypes/DmgFileType.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.file.fileTypes;
2 |
3 | import com.intellij.openapi.fileTypes.FileType;
4 | import com.intellij.openapi.vfs.VirtualFile;
5 | import icons.MyIcons;
6 | import org.jetbrains.annotations.NotNull;
7 | import org.jetbrains.annotations.Nullable;
8 |
9 | import javax.swing.Icon;
10 |
11 | /**
12 | * @author linjinjia
13 | * @date 2024/4/21 13:23
14 | */
15 | public class DmgFileType implements FileType {
16 |
17 | public static final DmgFileType INSTANCE = new DmgFileType();
18 |
19 | @NotNull
20 | @Override
21 | public String getName() {
22 | return "Disk Image";
23 | }
24 |
25 | @NotNull
26 | @Override
27 | public String getDescription() {
28 | return "Disk Image";
29 | }
30 |
31 | @NotNull
32 | @Override
33 | public String getDefaultExtension() {
34 | return "dmg";
35 | }
36 |
37 | @Nullable
38 | @Override
39 | public Icon getIcon() {
40 | return MyIcons.FileType.Dmg;
41 | }
42 |
43 | @Override
44 | public boolean isBinary() {
45 | return false;
46 | }
47 |
48 | @Override
49 | public boolean isReadOnly() {
50 | return false;
51 | }
52 |
53 | @Nullable
54 | @Override
55 | public String getCharset(@NotNull VirtualFile file, @NotNull byte[] content) {
56 | return null;
57 | }
58 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/file/fileTypes/EbookFileType.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.file.fileTypes;
2 |
3 | import com.intellij.openapi.fileTypes.FileType;
4 | import com.intellij.openapi.util.text.StringUtil;
5 | import com.intellij.openapi.vfs.VirtualFile;
6 | import icons.MyIcons;
7 | import org.jetbrains.annotations.NotNull;
8 | import org.jetbrains.annotations.Nullable;
9 |
10 | import javax.swing.Icon;
11 |
12 | /**
13 | * @author linjinjia
14 | * @date 2024/4/21 15:19
15 | */
16 | public class EbookFileType implements FileType {
17 | private final String ext;
18 |
19 | public EbookFileType(String ext) {
20 | this.ext = StringUtil.toUpperCase(ext);
21 | }
22 |
23 | @NotNull
24 | @Override
25 | public String getName() {
26 | return ext;
27 | }
28 |
29 | @NotNull
30 | @Override
31 | public String getDescription() {
32 | return ext;
33 | }
34 |
35 | @NotNull
36 | @Override
37 | public String getDefaultExtension() {
38 | return "epub";
39 | }
40 |
41 | @Nullable
42 | @Override
43 | public Icon getIcon() {
44 | return MyIcons.FileType.EBook;
45 | }
46 |
47 | @Override
48 | public boolean isBinary() {
49 | return false;
50 | }
51 |
52 | @Override
53 | public boolean isReadOnly() {
54 | return false;
55 | }
56 |
57 | @Nullable
58 | @Override
59 | public String getCharset(@NotNull VirtualFile file, @NotNull byte[] content) {
60 | return null;
61 | }
62 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/file/fileTypes/ExcelFileType.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.file.fileTypes;
2 |
3 | import com.intellij.openapi.fileTypes.FileType;
4 | import com.intellij.openapi.vfs.VirtualFile;
5 | import icons.MyIcons;
6 | import org.jetbrains.annotations.NotNull;
7 | import org.jetbrains.annotations.Nullable;
8 |
9 | import javax.swing.Icon;
10 |
11 | /**
12 | * @author linjinjia
13 | * @date 2024/4/21 15:19
14 | */
15 | public class ExcelFileType implements FileType {
16 |
17 | public static final ExcelFileType INSTANCE = new ExcelFileType();
18 |
19 | @NotNull
20 | @Override
21 | public String getName() {
22 | return "Excel";
23 | }
24 |
25 | @NotNull
26 | @Override
27 | public String getDescription() {
28 | return "Excel";
29 | }
30 |
31 | @NotNull
32 | @Override
33 | public String getDefaultExtension() {
34 | return "xlsx";
35 | }
36 |
37 | @Nullable
38 | @Override
39 | public Icon getIcon() {
40 | return MyIcons.FileType.Excel;
41 | }
42 |
43 | @Override
44 | public boolean isBinary() {
45 | return false;
46 | }
47 |
48 | @Override
49 | public boolean isReadOnly() {
50 | return false;
51 | }
52 |
53 | @Nullable
54 | @Override
55 | public String getCharset(@NotNull VirtualFile file, @NotNull byte[] content) {
56 | return null;
57 | }
58 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/file/fileTypes/LogFileType.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.file.fileTypes;
2 |
3 | import com.intellij.openapi.fileTypes.FileType;
4 | import com.intellij.openapi.vfs.VirtualFile;
5 | import icons.MyIcons;
6 | import org.jetbrains.annotations.NotNull;
7 | import org.jetbrains.annotations.Nullable;
8 |
9 | import javax.swing.Icon;
10 |
11 | /**
12 | * @author linjinjia
13 | * @date 2024/4/21 15:19
14 | */
15 | public class LogFileType implements FileType {
16 |
17 | public static final LogFileType INSTANCE = new LogFileType();
18 |
19 | @NotNull
20 | @Override
21 | public String getName() {
22 | return "Log";
23 | }
24 |
25 | @NotNull
26 | @Override
27 | public String getDescription() {
28 | return "Log";
29 | }
30 |
31 | @NotNull
32 | @Override
33 | public String getDefaultExtension() {
34 | return "log";
35 | }
36 |
37 | @Nullable
38 | @Override
39 | public Icon getIcon() {
40 | return MyIcons.FileType.Log;
41 | }
42 |
43 | @Override
44 | public boolean isBinary() {
45 | return false;
46 | }
47 |
48 | @Override
49 | public boolean isReadOnly() {
50 | return false;
51 | }
52 |
53 | @Nullable
54 | @Override
55 | public String getCharset(@NotNull VirtualFile file, @NotNull byte[] content) {
56 | return null;
57 | }
58 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/file/fileTypes/PdfFileType.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.file.fileTypes;
2 |
3 | import com.intellij.openapi.fileTypes.FileType;
4 | import com.intellij.openapi.vfs.VirtualFile;
5 | import icons.MyIcons;
6 | import org.jetbrains.annotations.NotNull;
7 | import org.jetbrains.annotations.Nullable;
8 |
9 | import javax.swing.Icon;
10 |
11 | /**
12 | * @author linjinjia
13 | * @date 2024/4/21 15:19
14 | */
15 | public class PdfFileType implements FileType {
16 |
17 | public static final PdfFileType INSTANCE = new PdfFileType();
18 |
19 | @NotNull
20 | @Override
21 | public String getName() {
22 | return "PDF";
23 | }
24 |
25 | @NotNull
26 | @Override
27 | public String getDescription() {
28 | return "PDF";
29 | }
30 |
31 | @NotNull
32 | @Override
33 | public String getDefaultExtension() {
34 | return "pdf";
35 | }
36 |
37 | @Nullable
38 | @Override
39 | public Icon getIcon() {
40 | return MyIcons.FileType.PDF;
41 | }
42 |
43 | @Override
44 | public boolean isBinary() {
45 | return false;
46 | }
47 |
48 | @Override
49 | public boolean isReadOnly() {
50 | return false;
51 | }
52 |
53 | @Nullable
54 | @Override
55 | public String getCharset(@NotNull VirtualFile file, @NotNull byte[] content) {
56 | return null;
57 | }
58 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/file/fileTypes/PptFileType.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.file.fileTypes;
2 |
3 | import com.intellij.openapi.fileTypes.FileType;
4 | import com.intellij.openapi.vfs.VirtualFile;
5 | import icons.MyIcons;
6 | import org.jetbrains.annotations.NotNull;
7 | import org.jetbrains.annotations.Nullable;
8 |
9 | import javax.swing.Icon;
10 |
11 | /**
12 | * @author linjinjia
13 | * @date 2024/4/21 15:19
14 | */
15 | public class PptFileType implements FileType {
16 |
17 | public static final PptFileType INSTANCE = new PptFileType();
18 |
19 | @NotNull
20 | @Override
21 | public String getName() {
22 | return "PPT";
23 | }
24 |
25 | @NotNull
26 | @Override
27 | public String getDescription() {
28 | return "PPT";
29 | }
30 |
31 | @NotNull
32 | @Override
33 | public String getDefaultExtension() {
34 | return "ppt";
35 | }
36 |
37 | @Nullable
38 | @Override
39 | public Icon getIcon() {
40 | return MyIcons.FileType.PPT;
41 | }
42 |
43 | @Override
44 | public boolean isBinary() {
45 | return false;
46 | }
47 |
48 | @Override
49 | public boolean isReadOnly() {
50 | return false;
51 | }
52 |
53 | @Nullable
54 | @Override
55 | public String getCharset(@NotNull VirtualFile file, @NotNull byte[] content) {
56 | return null;
57 | }
58 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/file/fileTypes/SFTPFileType.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.file.fileTypes;
2 |
3 | import com.intellij.openapi.fileTypes.FileType;
4 | import com.intellij.openapi.vfs.VirtualFile;
5 | import icons.MyIcons;
6 | import org.jetbrains.annotations.NonNls;
7 | import org.jetbrains.annotations.NotNull;
8 | import org.jetbrains.annotations.Nullable;
9 |
10 | import javax.swing.Icon;
11 |
12 | /**
13 | * @author linjinjia
14 | * @date 2024/3/31 02:24
15 | */
16 | public class SFTPFileType implements FileType {
17 | @Override
18 | public @NonNls @NotNull String getName() {
19 | return "FTP Console";
20 | }
21 |
22 | @Override
23 | public @NotNull String getDescription() {
24 | return "A-FTP console";
25 | }
26 |
27 | @Override
28 | public @NotNull String getDefaultExtension() {
29 | return "";
30 | }
31 |
32 | @Override
33 | public @Nullable Icon getIcon() {
34 | return MyIcons.SFTP;
35 | }
36 |
37 | @Override
38 | public boolean isBinary() {
39 | return false;
40 | }
41 |
42 | @Override
43 | public boolean isReadOnly() {
44 | return true;
45 | }
46 |
47 | @Override
48 | public @NonNls @Nullable String getCharset(@NotNull VirtualFile file, byte @NotNull [] content) {
49 | return null;
50 | }
51 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/file/fileTypes/SpecifiedArchiveFileType.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.file.fileTypes;
2 |
3 | import com.intellij.openapi.fileTypes.FileType;
4 | import com.intellij.openapi.util.text.StringUtil;
5 | import com.intellij.openapi.vfs.VirtualFile;
6 | import org.jetbrains.annotations.NotNull;
7 | import org.jetbrains.annotations.Nullable;
8 |
9 | import javax.swing.Icon;
10 |
11 | /**
12 | * @author linjinjia
13 | * @date 2024/4/21 11:45
14 | */
15 | public class SpecifiedArchiveFileType implements FileType {
16 |
17 | private final FileType origin;
18 | private final String ext;
19 |
20 | public SpecifiedArchiveFileType(FileType origin, String ext) {
21 | this.origin = origin;
22 | this.ext = StringUtil.toUpperCase(ext);
23 | }
24 |
25 | @NotNull
26 | @Override
27 | public String getName() {
28 | return ext + " " + origin.getName();
29 | }
30 |
31 | @NotNull
32 | @Override
33 | public String getDescription() {
34 | return getName();
35 | }
36 |
37 | @NotNull
38 | @Override
39 | public String getDefaultExtension() {
40 | return ext;
41 | }
42 |
43 | @Nullable
44 | @Override
45 | public Icon getIcon() {
46 | return origin.getIcon();
47 | }
48 |
49 | @Override
50 | public boolean isBinary() {
51 | return origin.isBinary();
52 | }
53 |
54 | @Override
55 | public boolean isReadOnly() {
56 | return origin.isReadOnly();
57 | }
58 |
59 | @Nullable
60 | @Override
61 | public String getCharset(@NotNull VirtualFile file, @NotNull byte[] content) {
62 | return null;
63 | }
64 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/file/fileTypes/VideoFileType.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.file.fileTypes;
2 |
3 | import com.intellij.openapi.fileTypes.FileType;
4 | import com.intellij.openapi.util.text.StringUtil;
5 | import com.intellij.openapi.vfs.VirtualFile;
6 | import icons.MyIcons;
7 | import org.jetbrains.annotations.NotNull;
8 | import org.jetbrains.annotations.Nullable;
9 |
10 | import javax.swing.Icon;
11 |
12 | /**
13 | * @author linjinjia
14 | * @date 2024/4/21 13:31
15 | */
16 | public class VideoFileType implements FileType {
17 |
18 | private final String ext;
19 |
20 | public VideoFileType(String ext) {
21 | this.ext = StringUtil.toUpperCase(ext);
22 | }
23 |
24 | @NotNull
25 | @Override
26 | public String getName() {
27 | return ext;
28 | }
29 |
30 | @NotNull
31 | @Override
32 | public String getDescription() {
33 | return ext + " Video";
34 | }
35 |
36 | @NotNull
37 | @Override
38 | public String getDefaultExtension() {
39 | return ext;
40 | }
41 |
42 | @Nullable
43 | @Override
44 | public Icon getIcon() {
45 | return MyIcons.FileType.Video;
46 | }
47 |
48 | @Override
49 | public boolean isBinary() {
50 | return false;
51 | }
52 |
53 | @Override
54 | public boolean isReadOnly() {
55 | return false;
56 | }
57 |
58 | @Nullable
59 | @Override
60 | public String getCharset(@NotNull VirtualFile file, @NotNull byte[] content) {
61 | return null;
62 | }
63 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/file/fileTypes/WordFileType.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.file.fileTypes;
2 |
3 | import com.intellij.openapi.fileTypes.FileType;
4 | import com.intellij.openapi.vfs.VirtualFile;
5 | import icons.MyIcons;
6 | import org.jetbrains.annotations.NotNull;
7 | import org.jetbrains.annotations.Nullable;
8 |
9 | import javax.swing.Icon;
10 |
11 | /**
12 | * @author linjinjia
13 | * @date 2024/4/21 15:19
14 | */
15 | public class WordFileType implements FileType {
16 |
17 | public static final WordFileType INSTANCE = new WordFileType();
18 |
19 | @NotNull
20 | @Override
21 | public String getName() {
22 | return "Word";
23 | }
24 |
25 | @NotNull
26 | @Override
27 | public String getDescription() {
28 | return "Word";
29 | }
30 |
31 | @NotNull
32 | @Override
33 | public String getDefaultExtension() {
34 | return "docx";
35 | }
36 |
37 | @Nullable
38 | @Override
39 | public Icon getIcon() {
40 | return MyIcons.FileType.Word;
41 | }
42 |
43 | @Override
44 | public boolean isBinary() {
45 | return false;
46 | }
47 |
48 | @Override
49 | public boolean isReadOnly() {
50 | return false;
51 | }
52 |
53 | @Nullable
54 | @Override
55 | public String getCharset(@NotNull VirtualFile file, @NotNull byte[] content) {
56 | return null;
57 | }
58 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/file/filter/ConsoleFileFilter.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.file.filter;
2 |
3 | import org.jetbrains.annotations.NotNull;
4 | import tech.lin2j.idea.plugin.ssh.CommandLog;
5 |
6 | import java.util.LinkedList;
7 | import java.util.List;
8 |
9 | /**
10 | *
11 | * @author linjinjia
12 | * @date 2024/11/27 22:23
13 | */
14 | public class ConsoleFileFilter implements ListableFileFilter {
15 | private final CommandLog commandLog;
16 | private final LinkedList filters = new LinkedList<>();
17 |
18 | public ConsoleFileFilter(CommandLog commandLog) {
19 | this.commandLog = commandLog;
20 | }
21 |
22 | public ConsoleFileFilter(@NotNull FileFilter fileFilter, @NotNull CommandLog commandLog) {
23 | this.commandLog = commandLog;
24 | filters.add(fileFilter);
25 | }
26 |
27 | @Override
28 | public boolean accept(String filename) {
29 | for (FileFilter filter : filters) {
30 | if (!filter.accept(filename)) {
31 | return false;
32 | }
33 | }
34 | return true;
35 | }
36 |
37 | @Override
38 | public void accept(String filename, FileAction action) throws Exception {
39 | boolean accept = accept(filename);
40 | action.execute(accept);
41 | }
42 |
43 | @Override
44 | public void addFilter(FileFilter filter) {
45 | filters.add(filter);
46 | }
47 |
48 | @Override
49 | public void removeLast() {
50 | filters.removeLast();
51 | }
52 |
53 | @Override
54 | public void remove(FileFilter filter) {
55 | filters.remove(filter);
56 | }
57 |
58 | @Override
59 | public List getFilters() {
60 | return filters;
61 | }
62 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/file/filter/ExtExcludeFilter.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.file.filter;
2 |
3 | import com.intellij.openapi.util.text.StringUtil;
4 | import tech.lin2j.idea.plugin.ssh.CommandLog;
5 |
6 | import java.util.Arrays;
7 | import java.util.HashSet;
8 | import java.util.Set;
9 | import java.util.stream.Collectors;
10 |
11 | /**
12 | * @author linjinjia
13 | * @date 2022/12/9 23:54
14 | */
15 | public class ExtExcludeFilter implements FileFilter {
16 | private final String extensions;
17 | private final Set extensionSet;
18 | private final CommandLog commandLog;;
19 |
20 | public ExtExcludeFilter(String extensions, CommandLog commandLog) {
21 | this.commandLog = commandLog;
22 | if (StringUtil.isEmpty(extensions)) {
23 | this.extensions = "";
24 | this.extensionSet = new HashSet<>();
25 | return;
26 | }
27 | this.extensions = extensions;
28 | extensionSet = Arrays.stream(extensions.split(";"))
29 | .map(s -> s.replaceAll("\\*?\\.?", ""))
30 | .collect(Collectors.toSet());
31 | }
32 |
33 | @Override
34 | public boolean accept(String f) {
35 | if (StringUtil.isEmpty(extensions)) {
36 | return true;
37 | }
38 |
39 | int dot = f.lastIndexOf('.');
40 | if (dot == -1) {
41 | return true;
42 | }
43 | String suffix = f.substring(dot + 1);
44 | boolean contains = extensionSet.contains(suffix);
45 | if (contains) {
46 | commandLog.info("[" + f + "] excluded by '" + extensions + "'");
47 | }
48 | return !contains;
49 | }
50 |
51 | public String getExtensions() {
52 | return extensions;
53 | }
54 |
55 | public Set getExtensionSet() {
56 | return extensionSet;
57 | }
58 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/file/filter/FileAction.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.file.filter;
2 |
3 | import java.io.IOException;
4 |
5 | /**
6 | * @author linjinjia
7 | * @date 2022/12/11 20:47
8 | */
9 | @FunctionalInterface
10 | public interface FileAction {
11 |
12 | /**
13 | * Performs this operation on the given argument.
14 | *
15 | * @param t the input argument
16 | * @throws IOException IOException
17 | */
18 | void execute(T t) throws Exception;
19 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/file/filter/FileFilter.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.file.filter;
2 |
3 | import java.io.IOException;
4 |
5 | /**
6 | * FileFilter is an interface used by scp for filtering
7 | * the set of files uploaded to ssh server
8 | *
9 | * @author linjinjia
10 | * @date 2022/12/9 22:54
11 | */
12 | public interface FileFilter {
13 |
14 | /**
15 | * Whether the given file is accepted by this filter.
16 | *
17 | * @param filename the name of a file to test
18 | * @return true if the file is to be accepted
19 | */
20 | boolean accept(String filename);
21 |
22 | /**
23 | * Test whether the file needs to be filtered,
24 | * and then perform a file operation
25 | *
26 | * @param filename the name of a file to test
27 | * @param action execute a {@link FileAction}
28 | * @throws IOException IOException
29 | */
30 | default void accept(String filename, FileAction action) throws Exception {
31 | boolean result = accept(filename);
32 | action.execute(result);
33 | }
34 |
35 |
36 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/file/filter/ListableFileFilter.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.file.filter;
2 |
3 | import java.util.List;
4 |
5 | /**
6 | * @author linjinjia
7 | * @date 2024/11/30 13:40
8 | */
9 | public interface ListableFileFilter extends FileFilter {
10 |
11 | void addFilter(FileFilter filter);
12 |
13 | void removeLast();
14 |
15 | void remove(FileFilter filter);
16 |
17 | List getFilters();
18 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/file/filter/RegexFileFilter.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.file.filter;
2 |
3 | import com.intellij.util.PathUtil;
4 | import tech.lin2j.idea.plugin.ssh.CommandLog;
5 |
6 | import java.util.regex.Pattern;
7 |
8 | /**
9 | * @author linjinjia
10 | * @date 2024/11/30 13:21
11 | */
12 | public class RegexFileFilter implements FileFilter {
13 | private final Pattern pattern;
14 | private final String regex;
15 | private final CommandLog commandLog;
16 |
17 | public RegexFileFilter(String regex, CommandLog commandLog) {
18 | this.regex = regex;
19 | this.pattern = Pattern.compile(regex);
20 | this.commandLog = commandLog;
21 | }
22 |
23 | @Override
24 | public boolean accept(String filename) {
25 | String name = PathUtil.getFileName(filename);
26 | boolean matches = pattern.matcher(name).matches();
27 | if (matches) {
28 | commandLog.info("[" + filename + "] matches pattern '" + regex + "'");
29 | }
30 | return matches;
31 | }
32 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/model/ConfigImportExport.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.model;
2 |
3 | import tech.lin2j.idea.plugin.ssh.SshServer;
4 |
5 | import java.util.List;
6 |
7 | /**
8 | * @author linjinjia
9 | * @date 2024/7/17 20:52
10 | */
11 | public class ConfigImportExport {
12 |
13 | private ExportOptions options;
14 |
15 | private String version;
16 |
17 | private List serverTags;
18 |
19 | private List hostInfos;
20 |
21 | public ExportOptions getOptions() {
22 | return options;
23 | }
24 |
25 | public void setOptions(ExportOptions options) {
26 | this.options = options;
27 | }
28 |
29 | public String getVersion() {
30 | return version;
31 | }
32 |
33 | public void setVersion(String version) {
34 | this.version = version;
35 | }
36 |
37 | public List getServerTags() {
38 | return serverTags;
39 | }
40 |
41 | public void setServerTags(List serverTags) {
42 | this.serverTags = serverTags;
43 | }
44 |
45 | public List getHostInfos() {
46 | return hostInfos;
47 | }
48 |
49 | public void setHostInfos(List hostInfos) {
50 | this.hostInfos = hostInfos;
51 | }
52 |
53 | public static class HostInfo {
54 | private SshServer server;
55 | private List commands;
56 | private List uploadProfiles;
57 |
58 | public SshServer getServer() {
59 | return server;
60 | }
61 |
62 | public void setServer(SshServer server) {
63 | this.server = server;
64 | }
65 |
66 | public List getCommands() {
67 | return commands;
68 | }
69 |
70 | public void setCommands(List commands) {
71 | this.commands = commands;
72 | }
73 |
74 | public List getUploadProfiles() {
75 | return uploadProfiles;
76 | }
77 |
78 | public void setUploadProfiles(List uploadProfiles) {
79 | this.uploadProfiles = uploadProfiles;
80 | }
81 |
82 | }
83 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/model/EDPluginUpdateChecker.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.model;
2 |
3 | import com.intellij.ide.plugins.StandalonePluginUpdateChecker;
4 | import com.intellij.notification.NotificationGroup;
5 | import com.intellij.openapi.components.Service;
6 | import icons.MyIcons;
7 | import tech.lin2j.idea.plugin.enums.Constant;
8 | import tech.lin2j.idea.plugin.uitl.EasyDeployPluginUtil;
9 |
10 | /**
11 | * @author linjinjia
12 | * @date 2024/12/1 11:17
13 | */
14 | @Service(Service.Level.APP)
15 | public final class EDPluginUpdateChecker extends StandalonePluginUpdateChecker {
16 |
17 | public EDPluginUpdateChecker() {
18 | super(EasyDeployPluginUtil.PLUGIN_ID,
19 | Constant.UPDATE_CHECKER_PROPERTY,
20 | NotificationGroup.findRegisteredGroup(Constant.EASY_DEPLOY),
21 | MyIcons.EasyDeploy);
22 | }
23 |
24 | @Override
25 | public boolean skipUpdateCheck() {
26 | return !EasyDeployPluginUtil.isEnabled();
27 | }
28 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/model/ExportOptions.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.model;
2 |
3 | import java.util.Objects;
4 |
5 | /**
6 | * @author linjinjia
7 | * @date 2024/7/17 20:57
8 | */
9 | public class ExportOptions implements Cloneable {
10 |
11 | private boolean command;
12 |
13 | private boolean uploadProfile;
14 |
15 | private boolean serverTags;
16 |
17 | /**
18 | * always export server info
19 | */
20 | public boolean isServer() {
21 | return true;
22 | }
23 |
24 | public boolean isCommand() {
25 | return command;
26 | }
27 |
28 | public void setCommand(boolean command) {
29 | this.command = command;
30 | }
31 |
32 | public boolean isUploadProfile() {
33 | return uploadProfile;
34 | }
35 |
36 | public void setUploadProfile(boolean uploadProfile) {
37 | this.uploadProfile = uploadProfile;
38 | }
39 |
40 | public boolean isServerTags() {
41 | return serverTags;
42 | }
43 |
44 | public void setServerTags(boolean serverTags) {
45 | this.serverTags = serverTags;
46 | }
47 |
48 | @Override
49 | public ExportOptions clone() {
50 | try {
51 | return (ExportOptions) super.clone();
52 | } catch (CloneNotSupportedException e) {
53 | ExportOptions newOne = new ExportOptions();
54 | newOne.setServerTags(serverTags);
55 | newOne.setCommand(command);
56 | newOne.setUploadProfile(uploadProfile);
57 | return newOne;
58 | }
59 | }
60 |
61 | @Override
62 | public boolean equals(Object o) {
63 | if (this == o) return true;
64 | if (o == null || getClass() != o.getClass()) return false;
65 | ExportOptions options = (ExportOptions) o;
66 | return command == options.command
67 | && uploadProfile == options.uploadProfile
68 | && serverTags == options.serverTags;
69 | }
70 |
71 | @Override
72 | public int hashCode() {
73 | return Objects.hash(command, uploadProfile, serverTags);
74 | }
75 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/model/HotReloadPersistence.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.model;
2 |
3 | import com.intellij.openapi.components.PersistentStateComponent;
4 | import com.intellij.openapi.components.Service;
5 | import com.intellij.openapi.components.State;
6 | import com.intellij.openapi.components.Storage;
7 | import com.intellij.util.xmlb.XmlSerializerUtil;
8 | import org.apache.commons.lang3.RandomUtils;
9 | import org.jetbrains.annotations.NotNull;
10 | import org.jetbrains.annotations.Nullable;
11 |
12 | import java.util.Random;
13 |
14 | /**
15 | * @author linjinjia
16 | * @date 2024/11/7 22:28
17 | */
18 | @State(
19 | name = "EasyDeployHotReload",
20 | storages = {@Storage("workspace.xml")}
21 | )
22 | @Service(Service.Level.PROJECT)
23 | public final class HotReloadPersistence implements PersistentStateComponent {
24 |
25 | private Integer sshId;
26 |
27 | private Integer pid;
28 |
29 | private Integer httpPort;
30 |
31 | public Integer getSshId() {
32 | return sshId;
33 | }
34 |
35 | public void setSshId(Integer sshId) {
36 | this.sshId = sshId;
37 | }
38 |
39 | public Integer getPid() {
40 | return pid;
41 | }
42 |
43 | public void setPid(Integer pid) {
44 | this.pid = pid;
45 | }
46 |
47 | public Integer getHttpPort() {
48 | return httpPort;
49 | }
50 |
51 | public void setHttpPort(Integer httpPort) {
52 | this.httpPort = httpPort;
53 | }
54 |
55 | @Override
56 | public @Nullable HotReloadPersistence getState() {
57 | return this;
58 | }
59 |
60 | @Override
61 | public void loadState(@NotNull HotReloadPersistence hotReloadPersistence) {
62 | XmlSerializerUtil.copyBean(hotReloadPersistence, this);
63 | }
64 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/model/NoneCommand.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.model;
2 |
3 | /**
4 | * @author linjinjia
5 | * @date 2022/5/7 09:19
6 | */
7 | public class NoneCommand extends Command {
8 |
9 | public static final NoneCommand INSTANCE = new NoneCommand();
10 |
11 | public NoneCommand() {
12 | setTitle("None");
13 | }
14 |
15 | @Override
16 | public String toString() {
17 | return "None";
18 | }
19 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/model/PluginConfigInitializer.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.model;
2 |
3 | import com.intellij.ide.AppLifecycleListener;
4 | import com.intellij.openapi.diagnostic.Logger;
5 | import org.jetbrains.annotations.NotNull;
6 |
7 | import java.util.List;
8 |
9 | /**
10 | *
11 | * @author linjinjia
12 | * @date 2024/8/9 21:40
13 | */
14 | public class PluginConfigInitializer implements AppLifecycleListener {
15 | private static final Logger log = Logger.getInstance(PluginConfigInitializer.class);
16 |
17 | @Override
18 | public void appFrameCreated(@NotNull List commandLineArgs) {
19 | try {
20 | ConfigHelper.ensureConfigLoadInMemory();
21 | } catch (Exception e) {
22 | log.error("Easy-Deploy plugin load configuration failed: " + e.getMessage(), e);
23 | }
24 | }
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/model/SeparatorCommand.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.model;
2 |
3 | /**
4 | * @author linjinjia
5 | * @date 2022/5/7 09:19
6 | */
7 | public class SeparatorCommand extends Command {
8 |
9 | public static final SeparatorCommand INSTANCE = new SeparatorCommand();
10 |
11 | public SeparatorCommand() {
12 | setTitle("---------------- Sharable ----------------");
13 | }
14 |
15 | @Override
16 | public String toString() {
17 | return "Sharable Separator";
18 | }
19 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/model/UniqueModel.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.model;
2 | /**
3 | *
4 | * @author linjinjia
5 | * @date 2024/8/11 22:18
6 | */
7 | public interface UniqueModel {
8 |
9 | String getUid();
10 |
11 | void setUid(String uid);
12 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/model/event/CommandAddEvent.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.model.event;
2 |
3 | import tech.lin2j.idea.plugin.event.ApplicationEvent;
4 |
5 | /**
6 | * @author linjinjia
7 | * @date 2022/4/29 10:06
8 | */
9 | public class CommandAddEvent extends ApplicationEvent {
10 | public CommandAddEvent(Object source) {
11 | super(source);
12 | }
13 |
14 | public CommandAddEvent() {
15 | super(new Object());
16 | }
17 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/model/event/FileTransferEvent.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.model.event;
2 |
3 | import tech.lin2j.idea.plugin.enums.TransferEventType;
4 | import tech.lin2j.idea.plugin.event.ApplicationEvent;
5 |
6 | /**
7 | * @author linjinjia
8 | * @date 2024/4/4 12:23
9 | */
10 | public class FileTransferEvent extends ApplicationEvent {
11 |
12 | private final TransferEventType state;
13 |
14 | private final boolean isUpload;
15 |
16 | public FileTransferEvent(Object source, boolean isUpload, TransferEventType state) {
17 | super(source);
18 | this.isUpload = isUpload;
19 | this.state = state;
20 | }
21 |
22 | public FileTransferEvent(boolean isUpload, TransferEventType state) {
23 | super(new Object());
24 | this.isUpload = isUpload;
25 | this.state = state;
26 | }
27 |
28 | public TransferEventType getState() {
29 | return state;
30 | }
31 |
32 | public boolean isUpload() {
33 | return isUpload;
34 | }
35 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/model/event/TableRefreshEvent.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.model.event;
2 |
3 | import tech.lin2j.idea.plugin.event.ApplicationEvent;
4 | import tech.lin2j.idea.plugin.ssh.SshServer;
5 |
6 | import java.util.List;
7 |
8 | /**
9 | * @author linjinjia
10 | * @date 2022/4/27 10:28
11 | */
12 | public class TableRefreshEvent extends ApplicationEvent {
13 |
14 | private boolean tagRefresh;
15 |
16 | List sshServers;
17 |
18 | public TableRefreshEvent(List sshServers) {
19 | super(new Object());
20 | this.sshServers = sshServers;
21 | }
22 |
23 | public TableRefreshEvent() {
24 | super(new Object());
25 | }
26 |
27 | public TableRefreshEvent(boolean tagRefresh) {
28 | super(new Object());
29 | this.tagRefresh = tagRefresh;
30 | }
31 |
32 | public List getSshServers() {
33 | return sshServers;
34 | }
35 |
36 | public boolean isTagRefresh() {
37 | return tagRefresh;
38 | }
39 |
40 | public void setTagRefresh(boolean tagRefresh) {
41 | this.tagRefresh = tagRefresh;
42 | }
43 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/model/event/UploadProfileAddEvent.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.model.event;
2 |
3 | import tech.lin2j.idea.plugin.event.ApplicationEvent;
4 |
5 | /**
6 | * @author linjinjia
7 | * @date 2022/4/29 10:06
8 | */
9 | public class UploadProfileAddEvent extends ApplicationEvent {
10 | public UploadProfileAddEvent(Object source) {
11 | super(source);
12 | }
13 |
14 | public UploadProfileAddEvent() {
15 | super(new Object());
16 | }
17 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/model/event/UploadProfileExecuteEvent.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.model.event;
2 |
3 | import tech.lin2j.idea.plugin.event.ApplicationEvent;
4 |
5 | /**
6 | * @author linjinjia
7 | * @date 2022/7/25 17:15
8 | */
9 | public class UploadProfileExecuteEvent extends ApplicationEvent {
10 |
11 | private Boolean success;
12 |
13 | private String uploadResult;
14 |
15 | private Boolean needExecCommand;
16 |
17 | public UploadProfileExecuteEvent() {
18 | super(new Object());
19 | }
20 |
21 | public String getUploadResult() {
22 | return uploadResult;
23 | }
24 |
25 | public void setUploadResult(String uploadResult) {
26 | this.uploadResult = uploadResult;
27 | }
28 |
29 | public Boolean isSuccess() {
30 | return success;
31 | }
32 |
33 | public void setSuccess(Boolean success) {
34 | this.success = success;
35 | }
36 |
37 | public Boolean getNeedExecCommand() {
38 | return needExecCommand;
39 | }
40 |
41 | public void setNeedExecCommand(Boolean needExecCommand) {
42 | this.needExecCommand = needExecCommand;
43 | }
44 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/model/event/UploadProfileSelectedEvent.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.model.event;
2 |
3 | import tech.lin2j.idea.plugin.event.ApplicationEvent;
4 |
5 | /**
6 | * @author linjinjia
7 | * @date 2022/4/29 10:06
8 | */
9 | public class UploadProfileSelectedEvent extends ApplicationEvent {
10 | public UploadProfileSelectedEvent(Object source) {
11 | super(source);
12 | }
13 |
14 | public UploadProfileSelectedEvent() {
15 | super(new Object());
16 | }
17 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/runner/ContentManagerAdapter.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.runner;
2 |
3 | import com.intellij.ui.content.ContentManagerEvent;
4 | import com.intellij.ui.content.ContentManagerListener;
5 | import org.jetbrains.annotations.NotNull;
6 |
7 | /**
8 | * @author linjinjia
9 | * @date 2024/7/28 21:48
10 | */
11 | public class ContentManagerAdapter implements ContentManagerListener {
12 | @Override
13 | public void contentAdded(@NotNull ContentManagerEvent contentManagerEvent) {
14 |
15 | }
16 |
17 | @Override
18 | public void contentRemoved(@NotNull ContentManagerEvent contentManagerEvent) {
19 |
20 | }
21 |
22 | @Override
23 | public void contentRemoveQuery(@NotNull ContentManagerEvent contentManagerEvent) {
24 |
25 | }
26 |
27 | @Override
28 | public void selectionChanged(@NotNull ContentManagerEvent contentManagerEvent) {
29 |
30 | }
31 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/runner/DeployConfigurationFactory.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.runner;
2 |
3 | import com.intellij.execution.configurations.ConfigurationFactory;
4 | import com.intellij.execution.configurations.ConfigurationType;
5 | import com.intellij.execution.configurations.RunConfiguration;
6 | import com.intellij.openapi.components.BaseState;
7 | import com.intellij.openapi.project.Project;
8 | import org.jetbrains.annotations.NotNull;
9 | import org.jetbrains.annotations.Nullable;
10 |
11 | /**
12 | * @author linjinjia
13 | * @date 2024/4/24 21:57
14 | */
15 | public class DeployConfigurationFactory extends ConfigurationFactory {
16 |
17 | protected DeployConfigurationFactory(ConfigurationType type) {
18 | super(type);
19 | }
20 |
21 | @Override
22 | public @NotNull String getId() {
23 | return DeployRunConfigurationType.ID;
24 | }
25 |
26 | @NotNull
27 | @Override
28 | public RunConfiguration createTemplateConfiguration(
29 | @NotNull Project project) {
30 | return new DeployRunConfiguration(project, this, "Easy Deploy");
31 | }
32 |
33 | @Nullable
34 | @Override
35 | public Class extends BaseState> getOptionsClass() {
36 | return DeployRunConfigurationOptions.class;
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/runner/DeployRunConfigurationOptions.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.runner;
2 |
3 | import com.intellij.execution.configurations.RunConfigurationOptions;
4 | import com.intellij.openapi.components.StoredProperty;
5 |
6 | import java.util.Set;
7 |
8 | /**
9 | * @author linjinjia
10 | * @date 2024/4/24 21:57
11 | */
12 | public class DeployRunConfigurationOptions extends RunConfigurationOptions {
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/runner/DeployRunConfigurationType.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.runner;
2 |
3 | import com.intellij.execution.configurations.ConfigurationTypeBase;
4 | import com.intellij.openapi.util.NotNullLazyValue;
5 | import icons.MyIcons;
6 |
7 | /**
8 | * @author linjinjia
9 | * @date 2024/4/24 21:57
10 | */
11 | public class DeployRunConfigurationType extends ConfigurationTypeBase {
12 | static final String ID = "EasyDeployRunConfiguration";
13 |
14 | DeployRunConfigurationType() {
15 | super(ID, "Easy Deploy", "Deploy service to remote server",
16 | NotNullLazyValue.createValue(() -> MyIcons.EasyDeploy));
17 | addFactory(new DeployConfigurationFactory(this));
18 | }
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/runner/process/UploadProcessHandler.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.runner.process;
2 |
3 | import com.intellij.execution.ExecutionResult;
4 | import com.intellij.execution.process.ProcessHandler;
5 | import com.intellij.execution.ui.ConsoleView;
6 | import org.jetbrains.annotations.Nullable;
7 | import tech.lin2j.idea.plugin.enums.Constant;
8 |
9 | import java.io.OutputStream;
10 |
11 | /**
12 | *
13 | * @see com.intellij.execution.process.NopProcessHandler
14 | * @author linjinjia
15 | * @date 2024/7/28 20:42
16 | */
17 | public class UploadProcessHandler extends ProcessHandler {
18 |
19 | private String name;
20 | private ConsoleView console;
21 | private ExecutionResult executionResult;
22 |
23 | public UploadProcessHandler() {
24 | super();
25 | }
26 |
27 | @Override
28 | protected void destroyProcessImpl() {
29 | notifyProcessTerminated(0);
30 | }
31 |
32 | @Override
33 | protected void detachProcessImpl() {
34 | notifyProcessDetached();
35 | }
36 |
37 | @Override
38 | public boolean detachIsDefault() {
39 | return false;
40 | }
41 |
42 | @Nullable
43 | @Override
44 | public OutputStream getProcessInput() {
45 | return null;
46 | }
47 |
48 | @Override
49 | public void notifyProcessTerminated(int exitCode) {
50 | super.notifyProcessTerminated(exitCode);
51 | }
52 |
53 | @Override
54 | protected void notifyProcessDetached() {
55 | super.notifyProcessDetached();
56 | }
57 |
58 | public ConsoleView getConsole() {
59 | return console;
60 | }
61 |
62 | public void setConsole(ConsoleView console) {
63 | this.console = console;
64 | }
65 |
66 | public ExecutionResult getExecutionResult() {
67 | return executionResult;
68 | }
69 |
70 | public void setExecutionResult(ExecutionResult executionResult) {
71 | this.executionResult = executionResult;
72 | }
73 |
74 | public String getName() {
75 | return name;
76 | }
77 |
78 | public void setName(String name) {
79 | this.name = Constant.RUN_TAB_PREFIX + name;
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/service/ISshService.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.service;
2 |
3 | import net.schmizz.sshj.xfer.TransferListener;
4 | import tech.lin2j.idea.plugin.file.filter.FileFilter;
5 | import tech.lin2j.idea.plugin.ssh.CommandLog;
6 | import tech.lin2j.idea.plugin.ssh.SshServer;
7 | import tech.lin2j.idea.plugin.ssh.SshStatus;
8 | import tech.lin2j.idea.plugin.ssh.sshj.SshjConnection;
9 |
10 | /**
11 | * @author linjinjia
12 | * @date 2023/12/21 22:20
13 | */
14 | public interface ISshService {
15 |
16 | /**
17 | * test whether the server information is available
18 | *
19 | * @param sshServer server information
20 | * @return execution result
21 | */
22 | SshStatus isValid(SshServer sshServer);
23 |
24 | /**
25 | * block if the command is not finished,
26 | * so do not execute command like "tail -f"
27 | * because it will block the thread
28 | *
29 | * @param sshServer server information
30 | * @param command command
31 | * @return execution result
32 | */
33 | SshStatus execute(SshServer sshServer, String command);
34 |
35 | void executeAsync(CommandLog commandLog, SshServer sshServer, String command);
36 |
37 | void executeAsync(CommandLog commandLog, SshjConnection connection, String command);
38 |
39 | SshStatus upload(FileFilter filter, SshServer server, String localFile,
40 | String remoteDir, TransferListener listener);
41 |
42 | boolean upload(FileFilter filter, SshjConnection connection,
43 | String localFile, String remoteDir,
44 | CommandLog commandLog, boolean createRemoteDir);
45 |
46 | /**
47 | * get file from remote server
48 | *
49 | * @param sshServer server information
50 | * @param remoteFile remote file absolute path
51 | * @param localFile local file absolute path
52 | * @return download result
53 | */
54 | SshStatus download(SshServer sshServer, String remoteFile, String localFile);
55 |
56 | /**
57 | * test whether the remote target directory is existed.
58 | *
59 | * @param server ssh server information
60 | * @param remoteTargetDir remote target directory
61 | * @return return true if the remote target directory is existed, or return false
62 | */
63 | SshStatus isDirExist(SshServer server, String remoteTargetDir);
64 |
65 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/service/impl/PluginNotificationService.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.service.impl;
2 |
3 | import com.intellij.notification.Notification;
4 | import com.intellij.notification.NotificationGroup;
5 | import com.intellij.notification.NotificationGroupManager;
6 | import com.intellij.notification.NotificationType;
7 | import com.intellij.openapi.actionSystem.AnAction;
8 | import com.intellij.openapi.components.Service;
9 | import com.intellij.openapi.project.Project;
10 | import tech.lin2j.idea.plugin.enums.Constant;
11 |
12 | /**
13 | * @author linjinjia
14 | * @date 2024/11/17 19:31
15 | */
16 | @Service
17 | public final class PluginNotificationService {
18 |
19 | private final NotificationGroup notificationGroup;
20 |
21 | public PluginNotificationService() {
22 | notificationGroup = NotificationGroupManager.getInstance().getNotificationGroup(Constant.EASY_DEPLOY);
23 | }
24 |
25 | public void showNotification(Project project, String title, String message) {
26 | Notification notification = notificationGroup.createNotification(title, message, NotificationType.INFORMATION);
27 | notification.setTitle(title);
28 | notification.setContent(message);
29 | notification.notify(project);
30 | }
31 |
32 | public void showNotification(Project project, String title, String message, AnAction action) {
33 | Notification notification = notificationGroup.createNotification(title, message, NotificationType.INFORMATION);
34 | notification.setTitle(title);
35 | notification.setContent(message);
36 | notification.addAction(action);
37 | notification.notify(project);
38 | }
39 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/ssh/ClosableCloudTerminalProcess.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.ssh;
2 |
3 | import org.jetbrains.plugins.terminal.cloud.CloudTerminalProcess;
4 |
5 | /**
6 | * @author linjinjia
7 | * @date 2024/5/16 23:40
8 | */
9 | public class ClosableCloudTerminalProcess extends CloudTerminalProcess {
10 |
11 | private final CustomTtyConnector connector;
12 |
13 | public ClosableCloudTerminalProcess(CustomTtyConnector connector) {
14 | super(connector.getOutputStream(), connector.getInputStream());
15 | this.connector = connector;
16 | }
17 |
18 | @Override
19 | public void destroy() {
20 | super.destroy();
21 | if (connector != null) {
22 | connector.close();
23 | }
24 | }
25 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/ssh/CommandLog.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.ssh;
2 |
3 | import com.intellij.execution.ui.ConsoleView;
4 | import com.intellij.execution.ui.ConsoleViewContentType;
5 | import com.intellij.openapi.util.Key;
6 |
7 | /**
8 | *
9 | * @author linjinjia
10 | * @date 2024/11/28 22:14
11 | */
12 | public interface CommandLog {
13 | Key COMMAND_LOG_KEY = Key.create("ProjectCommandLog");
14 |
15 | ConsoleView getConsole();
16 |
17 | void print(String msg, ConsoleViewContentType contentType);
18 |
19 | default void print(String msg) {
20 | print(msg, ConsoleViewContentType.NORMAL_OUTPUT);
21 | }
22 |
23 | default void info(String msg) {
24 | print("[INFO] ", ConsoleViewContentType.LOG_INFO_OUTPUT);
25 | if (msg != null && !msg.endsWith("\n")) {
26 | msg += "\n";
27 | }
28 | print(msg, ConsoleViewContentType.NORMAL_OUTPUT);
29 | }
30 |
31 | default void println(String msg) {
32 | print(msg + "\n", ConsoleViewContentType.NORMAL_OUTPUT);
33 | }
34 |
35 | default void error(String msg) {
36 | print("[ERROR] ", ConsoleViewContentType.LOG_ERROR_OUTPUT);
37 | if (msg != null && !msg.endsWith("\n")) {
38 | msg += "\n";
39 | }
40 | print(msg, ConsoleViewContentType.ERROR_OUTPUT);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/ssh/ConsoleCommandLog.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.ssh;
2 |
3 | import com.intellij.execution.ui.ConsoleView;
4 | import com.intellij.execution.ui.ConsoleViewContentType;
5 |
6 | public class ConsoleCommandLog implements CommandLog {
7 | private final ConsoleView console;
8 |
9 | public ConsoleCommandLog(ConsoleView console) {
10 | this.console = console;
11 | }
12 |
13 | @Override
14 | public ConsoleView getConsole() {
15 | return console;
16 | }
17 |
18 | @Override
19 | public void print(String msg, ConsoleViewContentType contentType) {
20 | console.print(msg, contentType);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/ssh/CustomTtyConnector.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.ssh;
2 |
3 | import com.jediterm.terminal.TtyConnector;
4 | import org.jetbrains.annotations.NotNull;
5 |
6 | import java.awt.Dimension;
7 | import java.io.InputStream;
8 | import java.io.OutputStream;
9 |
10 | /**
11 | * @author linjinjia
12 | * @date 2022/6/24 21:41
13 | */
14 | public interface CustomTtyConnector extends TtyConnector {
15 |
16 | /**
17 | * JSch, implementation of SSH2
18 | */
19 | @Deprecated
20 | String JSCH = "JSch";
21 |
22 | /**
23 | * SSHJ, implementation of SSH2
24 | */
25 | String SSHJ = "SSHJ";
26 |
27 | InputStream getInputStream();
28 |
29 | OutputStream getOutputStream();
30 |
31 | void setName(String title);
32 |
33 | void resize(@NotNull Dimension termSize);
34 |
35 | void resizeImmediately();
36 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/ssh/JavaProcess.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.ssh;
2 |
3 | import com.intellij.openapi.util.text.StringUtil;
4 | import org.jetbrains.annotations.NotNull;
5 |
6 | import java.util.Objects;
7 |
8 | /**
9 | * @author linjinjia
10 | * @date 2024/11/7 21:48
11 | */
12 | public class JavaProcess implements Comparable {
13 |
14 | private final int pid;
15 | private final String name;
16 | private final String process;
17 |
18 | public JavaProcess(String process) {
19 | Objects.requireNonNull(process);
20 |
21 | this.process = StringUtil.trim(process);
22 |
23 | String[] ss = process.split(" ");
24 | pid = Integer.parseInt(ss[0]);
25 | name = StringUtil.trim(ss[1]);
26 | }
27 |
28 | public int getPid() {
29 | return pid;
30 | }
31 |
32 | public String getName() {
33 | return name;
34 | }
35 |
36 | @Override
37 | public String toString() {
38 | return process;
39 | }
40 |
41 | @Override
42 | public int compareTo(@NotNull JavaProcess o) {
43 | return this.name.compareTo(o.name);
44 | }
45 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/ssh/SshConnection.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.ssh;
2 |
3 |
4 | import java.io.IOException;
5 | import java.util.concurrent.FutureTask;
6 | import java.util.concurrent.atomic.AtomicBoolean;
7 |
8 | /**
9 | * @author linjinjia
10 | * @date 2022/6/24 20:46
11 | */
12 | public interface SshConnection {
13 |
14 | /**
15 | * Return whether the SSH connection has been successfully established.
16 | * @return true if established, false otherwise
17 | */
18 | boolean isConnected();
19 |
20 | /**
21 | * upload file from local to remote server
22 | * @param local the absolute path of local file
23 | * @param dest the absolute path of remote destination
24 | */
25 | void upload(String local, String dest) throws IOException;
26 |
27 | /**
28 | * download file from remote server
29 | * @param remote the absolute path of remote file
30 | * @param dest the absolute path that the file will be stored
31 | */
32 | void download(String remote, String dest) throws IOException;
33 |
34 | void scpUpload(String local, String dest) throws IOException;
35 |
36 | void scpDownload(String remote, String dest) throws IOException;
37 |
38 | /**
39 | * execute command
40 | * note that command like 'tail -f' will block the thread
41 | * @param cmd command
42 | * @return the execution result of the command, some commands
43 | * return results while others indicate errors, requiring the
44 | * caller to discern
45 | */
46 | SshStatus execute(String cmd) throws IOException;
47 |
48 | FutureTask executeAsync(CommandLog commandLog, String cmd,
49 | AtomicBoolean cancel, boolean closeAfterFinished);
50 |
51 | /**
52 | * Create a directory, automatically creating parent directories
53 | * if they do not exist.
54 | *
55 | * @param dir directory path
56 | * @throws IOException IOException
57 | */
58 | void mkdirs(String dir) throws IOException;
59 |
60 | /**
61 | * close the ssh connection
62 | */
63 | void close();
64 |
65 | /**
66 | * return true when the connection has closed, otherwise return false;
67 | * @return turn only if the connection has closed, otherwise return false
68 | */
69 | boolean isClosed();
70 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/ssh/SshProcess.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.ssh;
2 |
3 | import java.io.InputStream;
4 | import java.io.OutputStream;
5 |
6 | /**
7 | * @author linjinjia
8 | * @date 2022/6/25 00:36
9 | */
10 | public class SshProcess extends Process {
11 |
12 | private final CustomTtyConnector ttyConnector;
13 |
14 | public SshProcess(CustomTtyConnector customTtyConnector) {
15 | this.ttyConnector = customTtyConnector;
16 | }
17 |
18 | @Override
19 | public OutputStream getOutputStream() {
20 | return ttyConnector.getOutputStream();
21 | }
22 |
23 | @Override
24 | public InputStream getInputStream() {
25 | return ttyConnector.getInputStream();
26 | }
27 |
28 | @Override
29 | public InputStream getErrorStream() {
30 | return ttyConnector.getInputStream();
31 | }
32 |
33 | @Override
34 | public int waitFor() throws InterruptedException {
35 | while(isAlive()) {
36 | this.wait();
37 | }
38 | return exitValue();
39 | }
40 |
41 | @Override
42 | public int exitValue() {
43 | if (ttyConnector.isConnected()) {
44 | throw new IllegalThreadStateException();
45 | }
46 | return 0;
47 | }
48 |
49 | @Override
50 | public void destroy() {
51 | try {
52 | ttyConnector.close();
53 | } catch (Exception e) {
54 | //
55 | }
56 | }
57 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/ssh/SshStatus.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.ssh;
2 |
3 | /**
4 | * @author linjinjia
5 | * @date 2022/4/25 21:13
6 | */
7 | public class SshStatus {
8 |
9 | private boolean success;
10 |
11 | private String message;
12 |
13 | private Object data;
14 |
15 | public SshStatus(boolean success, String message) {
16 | this.success = success;
17 | this.message = message;
18 | }
19 |
20 | public SshStatus(boolean success, String message, Object data) {
21 | this.success = success;
22 | this.message = message;
23 | this.data = data;
24 | }
25 |
26 | public boolean isSuccess() {
27 | return success;
28 | }
29 |
30 | public void setSuccess(boolean success) {
31 | this.success = success;
32 | }
33 |
34 | public String getMessage() {
35 | return message;
36 | }
37 |
38 | public void setMessage(String message) {
39 | this.message = message;
40 | }
41 |
42 | public Object getData() {
43 | return data;
44 | }
45 |
46 | public void setData(Object data) {
47 | this.data = data;
48 | }
49 |
50 |
51 | @Override
52 | public String toString() {
53 | return "SshStatus{" +
54 | "success=" + success +
55 | ", message='" + message + '\'' +
56 | '}';
57 | }
58 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/ssh/SshUploadTask.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.ssh;
2 |
3 | import com.intellij.execution.ui.ConsoleView;
4 | import tech.lin2j.idea.plugin.model.ConfigHelper;
5 | import tech.lin2j.idea.plugin.model.DeployProfile;
6 | import tech.lin2j.idea.plugin.model.UploadProfile;
7 | import tech.lin2j.idea.plugin.uitl.CommandUtil;
8 |
9 | import java.util.Objects;
10 |
11 | /**
12 | * @author linjinjia
13 | * @date 2024/5/2 17:11
14 | */
15 | public class SshUploadTask implements Runnable {
16 | private final int sshId;
17 | private final int profileId;
18 | private final ConsoleView console;
19 |
20 | private UploadProfile profile;
21 | private SshServer server;
22 | private String taskName;
23 |
24 | public SshUploadTask(ConsoleView console, DeployProfile deployProfile) {
25 | this.sshId = deployProfile.getSshId();
26 | this.profileId = deployProfile.getProfileId();
27 | this.console = console;
28 | this.server = getServer();
29 | this.profile = getProfile();
30 |
31 | this.taskName = String.format("%s - %s", server.getIp(), profile.getName());
32 | }
33 |
34 | public SshUploadTask(ConsoleView console, int sshId, int profileId) {
35 | this.console = console;
36 | this.sshId = sshId;
37 | this.profileId = profileId;
38 | }
39 |
40 | @Override
41 | public void run() {
42 | UploadProfile profile = getProfile();
43 | SshServer server = getServer();
44 | ConsoleCommandLog commandLog = new ConsoleCommandLog(console);
45 | CommandUtil.executeUpload(profile, server, commandLog);
46 | }
47 |
48 | public UploadProfile getProfile() {
49 | if (profile == null) {
50 | profile = ConfigHelper.getOneUploadProfileById(sshId, profileId);
51 | }
52 | Objects.requireNonNull(profile);
53 | return profile;
54 | }
55 |
56 | public SshServer getServer() {
57 | if (server == null) {
58 | server = ConfigHelper.getSshServerById(sshId);
59 | }
60 | Objects.requireNonNull(server);
61 | return server;
62 | }
63 |
64 | public String getTaskName() {
65 | return taskName;
66 | }
67 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/ssh/exception/RemoteSdkException.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.ssh.exception;
2 |
3 | /**
4 | * @author linjinjia
5 | * @date 2022/6/26 14:09
6 | */
7 | public class RemoteSdkException extends RuntimeException{
8 |
9 | public RemoteSdkException(String msg, Throwable e) {
10 | super(msg, e);
11 | }
12 |
13 | public RemoteSdkException(String msg) {
14 | super(msg);
15 | }
16 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/ui/component/ArrowLabel.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.ui.component;
2 |
3 | import com.intellij.ui.components.JBLabel;
4 |
5 | import java.awt.Dimension;
6 | import java.awt.Graphics;
7 | import java.awt.Graphics2D;
8 | import java.awt.RenderingHints;
9 |
10 | /**
11 | * @author linjinjia
12 | * @date 2024/5/19 11:30
13 | */
14 | public class ArrowLabel extends JBLabel {
15 | private final boolean curved;
16 | private final boolean leftToRight;
17 |
18 | public ArrowLabel(boolean curved, boolean leftToRight) {
19 | this.curved = curved;
20 | this.leftToRight = leftToRight;
21 | }
22 |
23 | @Override
24 | protected void paintComponent(Graphics g) {
25 | super.paintComponent(g);
26 | Graphics2D g2d = (Graphics2D) g.create();
27 | g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
28 | int midY = getHeight() / 2;
29 | int startX = leftToRight ? 0 : getWidth();
30 | int endX = leftToRight ? getWidth() : 0;
31 |
32 | if (curved) {
33 | startX = endX = getWidth() / 2;
34 | int startY = 0;
35 | int endY = getHeight();
36 | g2d.drawLine(startX, startY, endX, endY);
37 | g2d.drawLine(endX, endY, endX - 5, endY - 5);
38 | g2d.drawLine(endX, endY, endX + 5, endY - 5);
39 | } else {
40 | g2d.drawLine(startX, midY, endX, midY);
41 | g2d.drawLine(endX, midY, endX - (leftToRight ? 5 : -5), midY - 5);
42 | g2d.drawLine(endX, midY, endX - (leftToRight ? 5 : -5), midY + 5);
43 | }
44 | g2d.dispose();
45 | }
46 |
47 | @Override
48 | public Dimension getPreferredSize() {
49 | return new Dimension(30, 30);
50 | }
51 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/ui/component/HostChainItem.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.ui.component;
2 |
3 | import tech.lin2j.idea.plugin.ssh.SshServer;
4 |
5 | /**
6 | * @author linjinjia
7 | * @date 2024/5/19 11:42
8 | */
9 | public class HostChainItem {
10 |
11 | private SshServer server;
12 |
13 | /**
14 | * the dependencies of some of host from a cycle
15 | */
16 | private Boolean cycle;
17 |
18 | public HostChainItem(SshServer server, Boolean cycle) {
19 | this.server = server;
20 | this.cycle = cycle;
21 | }
22 |
23 | public SshServer getServer() {
24 | return server;
25 | }
26 |
27 | public Boolean isCycle() {
28 | return cycle;
29 | }
30 |
31 | public void setServer(SshServer server) {
32 | this.server = server;
33 | }
34 |
35 | public void setCycle(Boolean cycle) {
36 | this.cycle = cycle;
37 | }
38 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/ui/component/ManualProxyPanel.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.ui.component;
2 |
3 | public class ManualProxyPanel {
4 | }
5 |
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/ui/dialog/ImportConfigPreviewDialog.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.ui.dialog;
2 |
3 | //import com.intellij.json.JsonFileType;
4 | import com.intellij.lang.Language;
5 | import com.intellij.openapi.fileTypes.PlainTextFileType;
6 | import com.intellij.openapi.project.Project;
7 | import com.intellij.openapi.ui.DialogWrapper;
8 | import com.intellij.ui.AdditionalPageAtBottomEditorCustomization;
9 | import com.intellij.ui.EditorCustomization;
10 | import com.intellij.ui.EditorTextField;
11 | import com.intellij.ui.EditorTextFieldProvider;
12 | import com.intellij.ui.SoftWrapsEditorCustomization;
13 | import org.jetbrains.annotations.Nullable;
14 |
15 | import javax.swing.JComponent;
16 | import java.awt.Dimension;
17 | import java.util.HashSet;
18 | import java.util.Set;
19 |
20 | /**
21 | * @author linjinjia
22 | * @date 2024/7/19 23:32
23 | */
24 | public class ImportConfigPreviewDialog extends DialogWrapper {
25 | private final Project project;
26 | private final String content;
27 | private EditorTextField editor;
28 |
29 | public ImportConfigPreviewDialog(@Nullable Project project, String content) {
30 | super(project);
31 | this.project = project;
32 | this.content = content;
33 |
34 | initEditor();
35 |
36 | setTitle("Import Configuration Preview");
37 | setOKButtonText("Import");
38 | init();
39 | }
40 |
41 | @Nullable
42 | @Override
43 | public JComponent createCenterPanel() {
44 | return editor;
45 | }
46 |
47 | private void initEditor() {
48 | Set features = new HashSet<>();
49 | features.add(SoftWrapsEditorCustomization.ENABLED);
50 | features.add(AdditionalPageAtBottomEditorCustomization.DISABLED);
51 | features.add(editor -> editor.setBackgroundColor(null));
52 | features.add((editor -> editor.getSettings().setLineNumbersShown(true)));
53 |
54 | // Language json = JsonFileType.INSTANCE.getLanguage();
55 | Language text = PlainTextFileType.INSTANCE.getLanguage();
56 | editor = EditorTextFieldProvider.getInstance().getEditorField(text, project, features);
57 |
58 | // Global editor color scheme is set by EditorTextField logic.
59 | // We also need to use font from it and not from the current LaF.
60 | editor.setFontInheritedFromLAF(false);
61 | editor.setPreferredSize(new Dimension(650, 750));
62 | editor.setText(content);
63 | }
64 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/ui/dialog/PasswordInputDialog.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.ui.dialog;
2 |
3 | import com.intellij.openapi.ui.DialogWrapper;
4 | import com.intellij.util.ui.FormBuilder;
5 | import org.jetbrains.annotations.Nullable;
6 |
7 | import javax.swing.JComponent;
8 | import javax.swing.JPanel;
9 |
10 | /**
11 | * @author linjinjia
12 | * @date 2024/5/5 01:11
13 | */
14 | public class PasswordInputDialog extends DialogWrapper {
15 |
16 | private final JPanel root;
17 |
18 | protected PasswordInputDialog(StringBuilder password) {
19 | super(true);
20 |
21 |
22 | root = FormBuilder.createFormBuilder()
23 | .getPanel();
24 |
25 | init();
26 | }
27 |
28 | @Nullable
29 | @Override
30 | protected JComponent createCenterPanel() {
31 | return root;
32 | }
33 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/ui/dialog/PluginSettingsDialog.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.ui.dialog;
2 |
3 | import com.intellij.ide.actions.ShowSettingsUtilImpl;
4 | import com.intellij.openapi.options.Configurable;
5 | import com.intellij.openapi.options.ConfigurableGroup;
6 | import com.intellij.openapi.project.Project;
7 | import org.jetbrains.annotations.NotNull;
8 | import tech.lin2j.idea.plugin.ui.settings.GeneralConfigurable;
9 | import tech.lin2j.idea.plugin.ui.settings.SFTPConfigurable;
10 | import tech.lin2j.idea.plugin.ui.settings.ServerTagConfigurable;
11 |
12 | import java.util.Collections;
13 |
14 | /**
15 | * @author linjinjia
16 | * @date 2024/4/21 18:42
17 | */
18 | public class PluginSettingsDialog {
19 | public static Configurable[] createNewConfigurable(Project project) {
20 | return new Configurable[]{
21 | new GeneralConfigurable(),
22 | new ServerTagConfigurable(),
23 | new SFTPConfigurable()
24 | };
25 | }
26 |
27 | public static void show(Project project) {
28 | show(project, createNewConfigurable(project), 0);
29 | }
30 |
31 | public static void show(Project project, Configurable[] configurable, int toSelect) {
32 | CoolConfigurableGroup coolConfigurableGroup = new CoolConfigurableGroup(configurable);
33 | // SwingUtilities.invokeLater(() -> {
34 | ShowSettingsUtilImpl.getDialog(
35 | project,
36 | Collections.singletonList(coolConfigurableGroup),
37 | configurable[toSelect]
38 | ).show();
39 | // });
40 | }
41 |
42 |
43 | static class CoolConfigurableGroup implements ConfigurableGroup {
44 | private final Configurable[] configurables;
45 |
46 | public CoolConfigurableGroup(Configurable[] configurables) {
47 | this.configurables = configurables;
48 | }
49 |
50 | @Override
51 | public String getDisplayName() {
52 | return "Easy Deploy";
53 | }
54 |
55 | @Override
56 | public Configurable @NotNull [] getConfigurables() {
57 | return configurables;
58 | }
59 | }
60 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/ui/dialog/SelectServerDialog.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.ui.dialog;
2 |
3 | import com.intellij.openapi.project.Project;
4 | import com.intellij.openapi.ui.ComboBox;
5 | import com.intellij.openapi.ui.DialogWrapper;
6 | import com.intellij.ui.CollectionComboBoxModel;
7 | import com.intellij.util.ui.FormBuilder;
8 | import org.jetbrains.annotations.Nullable;
9 | import tech.lin2j.idea.plugin.model.ConfigHelper;
10 | import tech.lin2j.idea.plugin.model.HotReloadPersistence;
11 | import tech.lin2j.idea.plugin.ssh.SshServer;
12 |
13 | import javax.swing.JComponent;
14 |
15 | /**
16 | * @author linjinjia
17 | * @date 2024/11/23 10:47
18 | */
19 | public class SelectServerDialog extends DialogWrapper {
20 |
21 | private final Project project;
22 | private final ComboBox sshServers;
23 |
24 | public SelectServerDialog(@Nullable Project project) {
25 | super(project);
26 | this.project = project;
27 |
28 | sshServers = new ComboBox<>();
29 |
30 | setTitle("Select Server");
31 | setSize(200, 0);
32 | init();
33 | }
34 |
35 | @Override
36 | protected @Nullable JComponent createCenterPanel() {
37 | sshServers.setModel(new CollectionComboBoxModel<>(ConfigHelper.sshServers()));
38 | return FormBuilder.createFormBuilder()
39 | .addComponent(sshServers)
40 | .getPanel();
41 | }
42 |
43 | @Override
44 | protected void doOKAction() {
45 | SshServer selectedValue = (SshServer) sshServers.getSelectedItem();
46 | if (selectedValue != null) {
47 | HotReloadPersistence state = project.getService(HotReloadPersistence.class).getState();
48 | state.setSshId(selectedValue.getId());
49 | }
50 | super.doOKAction();
51 | }
52 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/ui/dialog/TransferConfirmDialog.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.ui.dialog;
2 |
3 | import javax.swing.JPanel;
4 |
5 | /**
6 | * @author linjinjia
7 | * @date 2024/4/18 06:31
8 | */
9 | public class TransferConfirmDialog {
10 | private JPanel root;
11 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/ui/editor/SFTPEditorProvider.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.ui.editor;
2 |
3 | import com.intellij.openapi.fileEditor.FileEditor;
4 | import com.intellij.openapi.fileEditor.FileEditorPolicy;
5 | import com.intellij.openapi.fileEditor.FileEditorProvider;
6 | import com.intellij.openapi.fileEditor.FileEditorState;
7 | import com.intellij.openapi.project.DumbAware;
8 | import com.intellij.openapi.project.Project;
9 | import com.intellij.openapi.vfs.VirtualFile;
10 | import org.jdom.Element;
11 | import org.jetbrains.annotations.NonNls;
12 | import org.jetbrains.annotations.NotNull;
13 |
14 | /**
15 | * @author linjinjia
16 | * @date 2024/4/22 21:56
17 | */
18 | public class SFTPEditorProvider implements FileEditorProvider, DumbAware {
19 | @Override
20 | public boolean accept(@NotNull Project project, @NotNull VirtualFile virtualFile) {
21 | return virtualFile instanceof SFTPVirtualFile;
22 | }
23 |
24 | @Override
25 | public @NotNull FileEditor createEditor(@NotNull Project project, @NotNull VirtualFile virtualFile) {
26 | return new SFTPEditor(virtualFile);
27 | }
28 |
29 | @Override
30 | public void disposeEditor(@NotNull FileEditor editor) {
31 | FileEditorProvider.super.disposeEditor(editor);
32 | }
33 |
34 | @Override
35 | public @NotNull FileEditorState readState(@NotNull Element sourceElement, @NotNull Project project, @NotNull VirtualFile file) {
36 | return FileEditorProvider.super.readState(sourceElement, project, file);
37 | }
38 |
39 | @Override
40 | public void writeState(@NotNull FileEditorState state, @NotNull Project project, @NotNull Element targetElement) {
41 | FileEditorProvider.super.writeState(state, project, targetElement);
42 | }
43 |
44 | @Override
45 | public @NotNull
46 | @NonNls String getEditorTypeId() {
47 | return "Redis Console";
48 | }
49 |
50 | @Override
51 | public @NotNull FileEditorPolicy getPolicy() {
52 | return FileEditorPolicy.HIDE_DEFAULT_EDITOR;
53 | }
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/ui/ftp/container/FileTableContainer.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.ui.ftp.container;
2 |
3 | import com.intellij.openapi.project.Project;
4 | import com.intellij.ui.table.JBTable;
5 | import net.schmizz.sshj.sftp.SFTPClient;
6 | import tech.lin2j.idea.plugin.file.TableFile;
7 |
8 | import java.io.IOException;
9 | import java.util.List;
10 |
11 | /**
12 | * @author linjinjia
13 | * @date 2024/4/6 21:11
14 | */
15 | public interface FileTableContainer {
16 |
17 | default boolean isLocal() {
18 | return true;
19 | }
20 |
21 | JBTable getTable();
22 |
23 | List getFileList();
24 |
25 | List getSelectedFiles();
26 |
27 | void setPath(String path);
28 |
29 | String getPath();
30 |
31 | String getHomePath();
32 |
33 | String getParentPath();
34 |
35 | void deleteFileAndDir(TableFile tf);
36 |
37 | boolean createNewFolder(String path) throws IOException;
38 |
39 | boolean showHiddenFileAndDir();
40 |
41 | void reversedHiddenFlag();
42 |
43 | void refreshFileList();
44 |
45 | Project getProject();
46 |
47 | default SFTPClient getFTPClient() {
48 | throw new UnsupportedOperationException();
49 | }
50 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/ui/module/DashboardView.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.ui.module;
2 |
3 | import com.intellij.openapi.project.Project;
4 | import com.intellij.openapi.ui.SimpleToolWindowPanel;
5 | import com.intellij.ui.JBSplitter;
6 |
7 | /**
8 | * @author linjinjia
9 | * @date 2022/4/24 17:01
10 | */
11 | public class DashboardView extends SimpleToolWindowPanel {
12 |
13 | private final Project project;
14 | private final tech.lin2j.idea.plugin.ui.DashboardView consoleUi;
15 |
16 | public DashboardView(Project project) {
17 | super(false, true);
18 | this.project = project;
19 | this.consoleUi = new tech.lin2j.idea.plugin.ui.DashboardView(project);
20 |
21 | JBSplitter splitter = new JBSplitter(false);
22 | splitter.setSplitterProportionKey("main.splitter.key");
23 | splitter.setFirstComponent(consoleUi);
24 | splitter.setProportion(0.3f);
25 | setContent(splitter);
26 | }
27 |
28 | public Project getProject() {
29 | return project;
30 | }
31 |
32 | public tech.lin2j.idea.plugin.ui.DashboardView getConsoleUi() {
33 | return consoleUi;
34 | }
35 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/ui/render/CommandColoredListCellRenderer.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.ui.render;
2 |
3 | import com.intellij.icons.AllIcons;
4 | import com.intellij.openapi.util.text.StringUtil;
5 | import com.intellij.ui.ColoredListCellRenderer;
6 | import com.intellij.ui.SimpleTextAttributes;
7 | import org.jetbrains.annotations.NotNull;
8 | import tech.lin2j.idea.plugin.model.Command;
9 | import tech.lin2j.idea.plugin.model.ConfigHelper;
10 | import tech.lin2j.idea.plugin.model.SeparatorCommand;
11 | import tech.lin2j.idea.plugin.ssh.SshServer;
12 |
13 | import javax.swing.JList;
14 | import java.util.Objects;
15 |
16 | /**
17 | * @author linjinjia
18 | * @date 2024/4/27 11:08
19 | */
20 | public class CommandColoredListCellRenderer extends ColoredListCellRenderer {
21 |
22 | public static final String TEXT_PADDING = " ";
23 |
24 | private final Integer sshId;
25 |
26 | public CommandColoredListCellRenderer(Integer sshId) {
27 | this.sshId = sshId;
28 | }
29 |
30 | @Override
31 | protected void customizeCellRenderer(@NotNull JList extends Command> list, Command value,
32 | int index, boolean selected, boolean hasFocus) {
33 | if (value instanceof SeparatorCommand) {
34 | append(value.getTitle(), SimpleTextAttributes.GRAY_ATTRIBUTES);
35 | return;
36 | }
37 | setIcon(AllIcons.Debugger.Console);
38 | if (StringUtil.isNotEmpty(value.getTitle())) {
39 | append(value.getTitle());
40 | append(TEXT_PADDING);
41 | }
42 | // server info
43 | if (!Objects.equals(sshId, value.getSshId()) && value.getSharable()) {
44 | SshServer server = ConfigHelper.getSshServerById(value.getSshId());
45 | if (server != null) {
46 | append("Shared by [" + server.getIp() + "]", SimpleTextAttributes.GRAY_ATTRIBUTES);
47 | append(TEXT_PADDING);
48 | }
49 | }
50 | append(Objects.toString(value), SimpleTextAttributes.GRAY_ATTRIBUTES);
51 | }
52 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/ui/render/UploadProfileColoredListCellRenderer.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.ui.render;
2 |
3 | import com.intellij.ui.ColoredListCellRenderer;
4 | import icons.MyIcons;
5 | import org.jetbrains.annotations.NotNull;
6 | import tech.lin2j.idea.plugin.model.UploadProfile;
7 |
8 | import javax.swing.JList;
9 |
10 | /**
11 | * @author linjinjia
12 | * @date 2024/4/27 11:08
13 | */
14 | public class UploadProfileColoredListCellRenderer extends ColoredListCellRenderer {
15 |
16 | @Override
17 | protected void customizeCellRenderer(@NotNull JList extends UploadProfile> list, UploadProfile value,
18 | int index, boolean selected, boolean hasFocus) {
19 | setIcon(MyIcons.UploadProfile);
20 | append(value.getName());
21 | }
22 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/ui/table/ActionCellEditor.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.ui.table;
2 |
3 | import com.intellij.openapi.project.Project;
4 | import tech.lin2j.idea.plugin.ui.component.HostActionPanel;
5 |
6 | import javax.swing.AbstractCellEditor;
7 | import javax.swing.JTable;
8 | import javax.swing.table.TableCellEditor;
9 | import java.awt.Component;
10 | import java.util.EventObject;
11 | import java.util.Objects;
12 |
13 | /**
14 | * @author linjinjia
15 | * @date 2024/5/5 17:00
16 | */
17 | public class ActionCellEditor extends AbstractCellEditor implements TableCellEditor {
18 | private final Project project;
19 |
20 | private HostActionPanel actionPane;
21 |
22 | public ActionCellEditor(Project project) {
23 | this.project = project;
24 | }
25 |
26 | @Override
27 | public Component getTableCellEditorComponent(JTable table, Object value,
28 | boolean isSelected, int row, int column) {
29 | int sshId = Integer.parseInt(Objects.toString(value));
30 | actionPane = new HostActionPanel(sshId, project);
31 | return actionPane;
32 | }
33 |
34 | @Override
35 | public Object getCellEditorValue() {
36 | return actionPane.getState();
37 | }
38 |
39 | @Override
40 | public boolean isCellEditable(EventObject anEvent) {
41 | return true;
42 | }
43 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/ui/table/ActionCellRenderer.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.ui.table;
2 |
3 | import com.intellij.openapi.project.Project;
4 | import tech.lin2j.idea.plugin.ui.component.HostActionPanel;
5 |
6 | import javax.swing.JTable;
7 | import javax.swing.table.DefaultTableCellRenderer;
8 | import java.awt.Component;
9 | import java.util.Objects;
10 |
11 | /**
12 | * @author linjinjia
13 | * @date 2024/5/5 17:00
14 | */
15 | public class ActionCellRenderer extends DefaultTableCellRenderer {
16 |
17 | private final Project project;
18 |
19 | public ActionCellRenderer(Project project) {
20 | this.project = project;
21 | }
22 |
23 | @Override
24 | public Component getTableCellRendererComponent(JTable table, Object value,
25 | boolean isSelected, boolean hasFocus, int row, int column) {
26 | Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
27 | int sshId = Integer.parseInt(Objects.toString(value));
28 | HostActionPanel actionPane = new HostActionPanel(sshId, project);
29 | actionPane.setForeground(c.getForeground());
30 | actionPane.setBackground(c.getBackground());
31 | return actionPane;
32 | }
33 |
34 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/ui/table/FileNameCellRenderer.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.ui.table;
2 |
3 | import com.intellij.util.ui.table.IconTableCellRenderer;
4 | import org.jetbrains.annotations.NotNull;
5 | import org.jetbrains.annotations.Nullable;
6 | import tech.lin2j.idea.plugin.file.TableFile;
7 |
8 | import javax.swing.Icon;
9 | import javax.swing.JLabel;
10 | import javax.swing.JTable;
11 | import java.awt.Component;
12 |
13 | /**
14 | * @author linjinjia
15 | * @date 2024/4/6 13:51
16 | */
17 | public class FileNameCellRenderer extends IconTableCellRenderer {
18 |
19 | @Override
20 | public Component getTableCellRendererComponent(JTable table, Object value, boolean selected, boolean focus, int row, int column) {
21 | Component component = super.getTableCellRendererComponent(table, value, selected, focus, row, column);
22 | ((JLabel) component).setText(((TableFile)value).getName());
23 | return component;
24 | }
25 |
26 | @Nullable
27 | @Override
28 | protected Icon getIcon(@NotNull TableFile value, JTable table, int row) {
29 | return value.getIcon();
30 | }
31 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/ui/table/ProgressCell.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.ui.table;
2 |
3 | import com.intellij.openapi.progress.util.ColorProgressBar;
4 | import com.intellij.ui.table.JBTable;
5 | import tech.lin2j.idea.plugin.file.DirectoryInfo;
6 |
7 | import javax.swing.table.TableModel;
8 |
9 | /**
10 | * @author linjinjia
11 | * @date 2024/4/15 22:23
12 | */
13 | public class ProgressCell {
14 | private final JBTable table;
15 | private final ColorProgressBar colorProgressBar;
16 | private DirectoryInfo directoryInfo;
17 | private int row;
18 | private long transferred;
19 |
20 | public ProgressCell(JBTable table, int row, ColorProgressBar colorProgressBar) {
21 | this.table = table;
22 | this.row = row;
23 | this.colorProgressBar = colorProgressBar;
24 | }
25 |
26 | public JBTable getTable() {
27 | return table;
28 | }
29 |
30 | public int getRow() {
31 | return row;
32 | }
33 |
34 | public void setRow(int row) {
35 | this.row = row;
36 | }
37 |
38 | public ColorProgressBar getColorProgressBar() {
39 | return colorProgressBar;
40 | }
41 |
42 | public boolean isDirectoryRow() {
43 | return directoryInfo.isDirectory();
44 | }
45 |
46 | public long getDirectorySize() {
47 | return directoryInfo.getSize();
48 | }
49 |
50 | public TableModel getTableModel() {
51 | return table.getModel();
52 | }
53 |
54 | public void setDirectoryInfo(DirectoryInfo directoryInfo) {
55 | this.directoryInfo = directoryInfo;
56 | }
57 |
58 | public long getTransferred() {
59 | return transferred;
60 | }
61 |
62 | public void addTransferred(long transferred) {
63 | this.transferred += transferred;
64 | }
65 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/uitl/EasyDeployPluginUtil.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.uitl;
2 |
3 | import com.intellij.ide.plugins.PluginManagerCore;
4 | import com.intellij.openapi.extensions.PluginId;
5 | import com.intellij.ui.components.JBLabel;
6 | import com.intellij.util.IconUtil;
7 | import icons.MyIcons;
8 |
9 | import javax.swing.Icon;
10 |
11 | /**
12 | * @author linjinjia
13 | * @date 2024/5/26 15:14
14 | */
15 | public class EasyDeployPluginUtil {
16 |
17 | public static final PluginId PLUGIN_ID = PluginId.getId("tech.lin2j.simple-deployment");
18 | public static final String version = PluginManagerCore.getPlugin(PLUGIN_ID).getVersion();
19 |
20 | public static String version() {
21 | return version;
22 | }
23 |
24 | public static boolean isEnabled() {
25 | return PluginManagerCore.getPlugin(PLUGIN_ID).isEnabled();
26 | }
27 |
28 | public static JBLabel versionLabel() {
29 | return new JBLabel("Version: " + EasyDeployPluginUtil.version());
30 | }
31 |
32 | public static JBLabel pluginIconLabel() {
33 | JBLabel label = new JBLabel();
34 | Icon icon = IconUtil.scale(MyIcons.EasyDeploy, label,4f);
35 | label.setIcon(icon);
36 | return label;
37 | }
38 |
39 |
40 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/uitl/FTPUtil.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.uitl;
2 |
3 | import net.schmizz.sshj.sftp.FileMode;
4 | import net.schmizz.sshj.sftp.RemoteResourceInfo;
5 | import net.schmizz.sshj.sftp.SFTPClient;
6 | import tech.lin2j.idea.plugin.file.DirectoryInfo;
7 |
8 | import java.io.IOException;
9 | import java.util.List;
10 |
11 | /**
12 | * @author linjinjia
13 | * @date 2024/4/14 14:54
14 | */
15 | public class FTPUtil {
16 |
17 | /**
18 | * Calculates the size of a directory on a remote FTP server recursively.
19 | *
20 | * @param ftpClient The FTP client connected to the server.
21 | * @param remoteDir The remote directory whose size needs to be calculated.
22 | * @return The total size of the remote directory and its contents, in bytes.
23 | * @throws IOException If an I/O error occurs while accessing the FTP server.
24 | */
25 | public static DirectoryInfo calcDirectorySize(SFTPClient ftpClient, String remoteDir) throws IOException {
26 | DirectoryInfo di = new DirectoryInfo();
27 | FileMode.Type type = ftpClient.type(remoteDir);
28 | if (type != FileMode.Type.DIRECTORY) {
29 | di.setDirectory(false);
30 | di.setSize(ftpClient.stat(remoteDir).getSize());
31 | di.setFiles(1);
32 | return di;
33 | }
34 | di.setDirectory(true);
35 | List files = ftpClient.ls(remoteDir);
36 | if (files != null) {
37 | for (RemoteResourceInfo file : files) {
38 | DirectoryInfo subDi = calcDirectorySize(ftpClient, remoteDir + "/" + file.getName());
39 | di.setFiles(di.getFiles() + subDi.getFiles());
40 | di.setSize(di.getSize() + subDi.getSize());
41 | }
42 | }
43 | return di;
44 | }
45 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/uitl/FileTransferSpeed.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.uitl;
2 |
3 | /**
4 | * @author linjinjia
5 | * @date 2024/11/24 20:49
6 | */
7 | public class FileTransferSpeed {
8 | private static final int UPDATE_INTERVAL = 750;
9 | private long lastTransferred;
10 | private long lastUpdateTime;
11 | private String speed = "-- B/s";
12 |
13 | public FileTransferSpeed() {
14 | lastUpdateTime = System.currentTimeMillis();
15 | lastTransferred = 0;
16 | }
17 |
18 | public String accept(long transferred) {
19 | long currentTime = System.currentTimeMillis();
20 |
21 | if (currentTime - lastUpdateTime >= UPDATE_INTERVAL) {
22 | long deltaBytes = transferred - lastTransferred;
23 | long elapsedTime = currentTime - lastUpdateTime;
24 |
25 | double speed = deltaBytes / (elapsedTime / 1000.0); // B/s
26 | this.speed = formatSpeed(speed);
27 |
28 | lastUpdateTime = currentTime;
29 | lastTransferred = transferred;
30 | }
31 |
32 | return speed;
33 | }
34 |
35 | private String formatSpeed(double speed) {
36 | final String[] units = {"B/s", "KB/s", "MB/s", "GB/s", "TB/s"};
37 | int unitIndex = 0;
38 |
39 | while (speed >= 1024 && unitIndex < units.length - 1) {
40 | speed /= 1024;
41 | unitIndex++;
42 | }
43 |
44 | // 如果速度为 0 或非常小,直接返回 "0 B/s"
45 | if (speed < 1e-6) {
46 | return "-- B/s";
47 | }
48 |
49 | return String.format("%.2f %s", speed, units[unitIndex]);
50 | }
51 | }
--------------------------------------------------------------------------------
/src/main/java/tech/lin2j/idea/plugin/uitl/MessagesBundle.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2024 XIN LIN HOU
3 | * ResourceBundleUtils.java is part of Cool Request
4 | *
5 | * License: GPL-3.0+
6 | *
7 | * Cool Request is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * Cool Request is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with Cool Request. If not, see .
19 | */
20 |
21 | package tech.lin2j.idea.plugin.uitl;
22 |
23 |
24 | import tech.lin2j.idea.plugin.model.ConfigHelper;
25 |
26 | import java.util.Locale;
27 | import java.util.ResourceBundle;
28 |
29 | /**
30 | * i18n
31 | *
32 | * @author linjinjia 2024/5/4 16:13
33 | */
34 | public class MessagesBundle {
35 |
36 | public static String getText(String key) {
37 | int languageValue = ConfigHelper.language();
38 | if (languageValue == -1) return getText(key, Locale.ENGLISH);
39 | if (languageValue == 0) return getText(key, Locale.ENGLISH);
40 | if (languageValue == 1) return getText(key, Locale.CHINESE);
41 | return getText(key, Locale.getDefault());
42 | }
43 |
44 | private static String getText(String key, Locale locale) {
45 | ResourceBundle bundle = ResourceBundle.getBundle("messages", locale);
46 | return bundle.getString(key);
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/main/resources/arthas.tar.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lin2j/easy-deploy/b9fc0ec2029ef5149418180c6d737ffd8feadec8/src/main/resources/arthas.tar.gz
--------------------------------------------------------------------------------
/src/main/resources/icons/actions/copy.svg:
--------------------------------------------------------------------------------
1 |
3 |
--------------------------------------------------------------------------------
/src/main/resources/icons/actions/export_import.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/main/resources/icons/actions/github.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/main/resources/icons/actions/home-page.svg:
--------------------------------------------------------------------------------
1 |
3 |
--------------------------------------------------------------------------------
/src/main/resources/icons/actions/host.svg:
--------------------------------------------------------------------------------
1 |
3 |
--------------------------------------------------------------------------------
/src/main/resources/icons/actions/my-add.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/main/resources/icons/actions/my_clean.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/main/resources/icons/actions/my_connect.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/main/resources/icons/actions/my_export.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/main/resources/icons/actions/my_import.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/main/resources/icons/actions/my_settings.svg:
--------------------------------------------------------------------------------
1 |
3 |
--------------------------------------------------------------------------------
/src/main/resources/icons/actions/my_share.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/main/resources/icons/actions/my_upload.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/main/resources/icons/actions/paste.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/main/resources/icons/actions/showHiddens.svg:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/src/main/resources/icons/actions/showHiddens_dark.svg:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/src/main/resources/icons/deploy.svg:
--------------------------------------------------------------------------------
1 |
3 |
--------------------------------------------------------------------------------
/src/main/resources/icons/deploy_dark.svg:
--------------------------------------------------------------------------------
1 |
3 |
--------------------------------------------------------------------------------
/src/main/resources/icons/easy-deploy.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/main/resources/icons/fileTypes/c.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/src/main/resources/icons/fileTypes/c_dark.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/src/main/resources/icons/fileTypes/cpp.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/src/main/resources/icons/fileTypes/cpp_dark.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/src/main/resources/icons/fileTypes/dmg.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/main/resources/icons/fileTypes/ebook.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/main/resources/icons/fileTypes/excel.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/main/resources/icons/fileTypes/pdf.svg:
--------------------------------------------------------------------------------
1 |
3 |
--------------------------------------------------------------------------------
/src/main/resources/icons/fileTypes/ppt.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/main/resources/icons/fileTypes/video.svg:
--------------------------------------------------------------------------------
1 |
3 |
--------------------------------------------------------------------------------
/src/main/resources/icons/fileTypes/word.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/main/resources/icons/filter.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/main/resources/icons/message_blue.svg:
--------------------------------------------------------------------------------
1 |
3 |
--------------------------------------------------------------------------------
/src/main/resources/icons/sftp.svg:
--------------------------------------------------------------------------------
1 |
3 |
--------------------------------------------------------------------------------
/src/main/resources/icons/tag.svg:
--------------------------------------------------------------------------------
1 |
2 |
5 |
--------------------------------------------------------------------------------
/src/main/resources/icons/tag_dark.svg:
--------------------------------------------------------------------------------
1 |
2 |
5 |
--------------------------------------------------------------------------------
/src/main/resources/icons/transferToolWindow.svg:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/src/main/resources/icons/transferToolWindow_dark.svg:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/src/test/java/tech/lin2j/idea/plugin/file/FilterTest.java:
--------------------------------------------------------------------------------
1 | package tech.lin2j.idea.plugin.file;
2 |
3 | import com.intellij.execution.ui.ConsoleView;
4 | import com.intellij.execution.ui.ConsoleViewContentType;
5 | import org.junit.Test;
6 | import tech.lin2j.idea.plugin.file.filter.ExtExcludeFilter;
7 | import tech.lin2j.idea.plugin.ssh.CommandLog;
8 |
9 | /**
10 | * @author linjinjia
11 | * @date 2022/12/11 00:00
12 | */
13 | public class FilterTest {
14 |
15 | @Test
16 | public void testExtensionFilter() {
17 | String extensions = "*.iml;.log;****.bat";
18 | ExtExcludeFilter fileFilter = new ExtExcludeFilter(extensions, new TestCommandLog());
19 | String[] suffix = {"bat", "log", "iml"};
20 | for (String s : suffix) {
21 | assert fileFilter.getExtensionSet().contains(s);
22 | }
23 | assert !fileFilter.accept("abc.iml");
24 | assert fileFilter.accept("abc.txt");
25 | assert fileFilter.accept("abc.");
26 | }
27 |
28 | private class TestCommandLog implements CommandLog {
29 |
30 | @Override
31 | public ConsoleView getConsole() {
32 | return null;
33 | }
34 |
35 | @Override
36 | public void print(String msg, ConsoleViewContentType contentType) {
37 |
38 | }
39 | }
40 | }
--------------------------------------------------------------------------------