mirror of
https://github.com/TermoraDev/termora.git
synced 2026-01-16 02:12:58 +08:00
chore: support plugin incompatibility
This commit is contained in:
@@ -1,13 +1,23 @@
|
||||
package app.termora.plugin;
|
||||
|
||||
import app.termora.I18n;
|
||||
import app.termora.OptionPane;
|
||||
import app.termora.TermoraRestarter;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.UIManager;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
|
||||
record ExtensionProxy(Plugin plugin, Extension extension) implements InvocationHandler {
|
||||
private static final Logger log = LoggerFactory.getLogger(ExtensionProxy.class);
|
||||
@@ -30,14 +40,72 @@ record ExtensionProxy(Plugin plugin, Extension extension) implements InvocationH
|
||||
return method.invoke(extension, args);
|
||||
} catch (InvocationTargetException e) {
|
||||
final Throwable target = e.getTargetException();
|
||||
// 尽可能避免抛出致命性错误
|
||||
if (target instanceof Error && !(target instanceof VirtualMachineError)) {
|
||||
|
||||
if (target instanceof Error) {
|
||||
if (log.isErrorEnabled()) {
|
||||
log.error("Error Invoking method {}", method.getName(), target);
|
||||
}
|
||||
throw new IllegalCallerException(target.getMessage(), target);
|
||||
}
|
||||
|
||||
// 二进制不兼容情况
|
||||
if (target instanceof LinkageError) {
|
||||
// 立即卸载
|
||||
uninstallPlugin();
|
||||
// 重启程序
|
||||
restart();
|
||||
}
|
||||
|
||||
|
||||
throw target;
|
||||
}
|
||||
}
|
||||
|
||||
private void restart() {
|
||||
|
||||
if (SwingUtilities.isEventDispatchThread()) {
|
||||
|
||||
OptionPane.INSTANCE.showMessageDialog(null,
|
||||
I18n.INSTANCE.getString("termora.settings.plugin.not-compatible", plugin.getName()),
|
||||
UIManager.getString("OptionPane.messageDialogTitle"),
|
||||
JOptionPane.ERROR_MESSAGE,
|
||||
Duration.ZERO
|
||||
);
|
||||
|
||||
try {
|
||||
// 立即重启
|
||||
TermoraRestarter.Companion.getInstance()
|
||||
.scheduleRestart(null, false, List.of());
|
||||
} catch (Exception e) {
|
||||
if (log.isErrorEnabled()) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
} else {
|
||||
SwingUtilities.invokeLater(this::restart);
|
||||
}
|
||||
}
|
||||
|
||||
private void uninstallPlugin() {
|
||||
final PluginManager pluginManager = PluginManager.Companion.getInstance();
|
||||
final PluginDescriptor[] descriptors = pluginManager.getLoadedPluginDescriptor();
|
||||
for (PluginDescriptor descriptor : descriptors) {
|
||||
if (descriptor.getPlugin() != plugin) continue;
|
||||
final File file = descriptor.getPath();
|
||||
if (file == null) continue;
|
||||
final File uninstalled = FileUtils.getFile(file, "uninstalled");
|
||||
try {
|
||||
if (!uninstalled.createNewFile()) {
|
||||
if (log.isWarnEnabled()) {
|
||||
log.error("Create file: {} failed", uninstalled.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
if (log.isErrorEnabled()) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,9 +16,8 @@ import java.awt.Dimension
|
||||
import java.awt.event.WindowAdapter
|
||||
import java.awt.event.WindowEvent
|
||||
import java.io.File
|
||||
import java.time.Duration
|
||||
import javax.swing.*
|
||||
import kotlin.time.Duration
|
||||
import kotlin.time.Duration.Companion.milliseconds
|
||||
|
||||
object OptionPane {
|
||||
private val coroutineScope = swingCoroutineScope
|
||||
@@ -95,7 +94,7 @@ object OptionPane {
|
||||
message: String,
|
||||
title: String = UIManager.getString("OptionPane.messageDialogTitle"),
|
||||
messageType: Int = JOptionPane.INFORMATION_MESSAGE,
|
||||
duration: Duration = 0.milliseconds,
|
||||
duration: Duration = Duration.ZERO,
|
||||
) {
|
||||
val label = JTextPane()
|
||||
label.contentType = "text/html"
|
||||
@@ -105,11 +104,12 @@ object OptionPane {
|
||||
label.border = BorderFactory.createEmptyBorder()
|
||||
val pane = JOptionPane(label, messageType, JOptionPane.DEFAULT_OPTION)
|
||||
val dialog = initDialog(pane.createDialog(parentComponent, title))
|
||||
if (duration.inWholeMilliseconds > 0) {
|
||||
|
||||
if (duration.toMillis() > 0) {
|
||||
dialog.addWindowListener(object : WindowAdapter() {
|
||||
override fun windowOpened(e: WindowEvent) {
|
||||
coroutineScope.launch(Dispatchers.Swing) {
|
||||
delay(duration.inWholeMilliseconds)
|
||||
delay(duration.toMillis())
|
||||
if (dialog.isVisible) {
|
||||
dialog.isVisible = false
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import org.apache.commons.io.FileUtils
|
||||
import org.apache.commons.lang3.StringUtils
|
||||
import org.slf4j.LoggerFactory
|
||||
import java.awt.Component
|
||||
import java.awt.event.WindowEvent
|
||||
import java.nio.file.Paths
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
import javax.swing.JOptionPane
|
||||
@@ -118,9 +119,11 @@ class TermoraRestarter {
|
||||
Restarter.restart(commands.toTypedArray())
|
||||
}
|
||||
|
||||
for (window in TermoraFrameManager.getInstance().getWindows()) {
|
||||
window.dispose()
|
||||
val instance = TermoraFrameManager.getInstance()
|
||||
for (window in instance.getWindows()) {
|
||||
window.dispatchEvent(WindowEvent(window, WindowEvent.WINDOW_CLOSED))
|
||||
}
|
||||
Disposer.dispose(instance)
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -73,20 +73,16 @@ termora.settings.about.termora=<html><b>${termora.title}</b> ({0}) is a cross-pl
|
||||
|
||||
termora.settings.plugin=Plugins
|
||||
termora.settings.plugin.install=Install
|
||||
termora.settings.plugin.subscribe=Subscribe
|
||||
termora.settings.plugin.install-subscription-confirm=Subscription required to install <b>{0}</b>
|
||||
termora.settings.plugin.installed=Installed
|
||||
termora.settings.plugin.marketplace=Marketplace
|
||||
termora.settings.plugin.uninstall=Uninstall
|
||||
termora.settings.plugin.update=Update
|
||||
termora.settings.plugin.uninstalled=Uninstalled
|
||||
termora.settings.plugin.cannot-uninstall=System built-in plugins cannot be uninstalled
|
||||
termora.settings.plugin.uninstall-confirm=Are you sure you want to uninstall <b>{0}</b> ?
|
||||
termora.settings.plugin.uninstall-failed=Uninstall failed
|
||||
termora.settings.plugin.install-failed=Install failed, please try again later
|
||||
termora.settings.plugin.install-from-disk=Install Plugin from Disk...
|
||||
termora.settings.plugin.manage-plugin-repository=Manage Plugin Repository...
|
||||
termora.settings.plugin.install-from-disk-warning=<b>{0}</b> plugin will have access to all your data. Are you sure you want to install it?
|
||||
termora.settings.plugin.not-compatible=The plugin <b>{0}</b> is incompatible with the current version. Please reinstall <b>{0}</b>
|
||||
|
||||
termora.settings.account=Account
|
||||
termora.settings.account.register=Register
|
||||
@@ -320,12 +316,10 @@ termora.transport.table.owner=Owner
|
||||
# contextmenu
|
||||
termora.transport.table.contextmenu.transfer=Transfer
|
||||
termora.transport.table.contextmenu.edit=${termora.keymgr.edit}
|
||||
termora.transport.table.contextmenu.edit-command=You must configure the "Edit Command" in "Settings - SFTP" before you can edit the file
|
||||
termora.transport.table.contextmenu.copy-path=Copy Path
|
||||
termora.transport.table.contextmenu.open-in-folder=Open in ${termora.finder}
|
||||
termora.transport.table.contextmenu.rename=${termora.welcome.contextmenu.rename}
|
||||
termora.transport.table.contextmenu.delete=${termora.remove}
|
||||
termora.transport.table.contextmenu.delete-warning=If the folder is too large, deleting it may take some time
|
||||
termora.transport.table.contextmenu.rm-warning=Using the rm -rf command to delete a file is very dangerous
|
||||
termora.transport.table.contextmenu.change-permissions=Change Permissions...
|
||||
termora.transport.table.contextmenu.refresh=Refresh
|
||||
@@ -434,7 +428,6 @@ termora.visual-window.system-information.used-total=Used / Total
|
||||
termora.visual-window.nvidia-smi=NVIDIA SMI
|
||||
|
||||
|
||||
termora.floating-toolbar.not-supported=This action is not supported
|
||||
termora.floating-toolbar.close-in-current-tab=Close in current tab
|
||||
|
||||
|
||||
|
||||
@@ -274,12 +274,10 @@ termora.transport.table.owner=Владелец
|
||||
# contextmenu
|
||||
termora.transport.table.contextmenu.transfer=Файлы
|
||||
termora.transport.table.contextmenu.edit=${termora.keymgr.edit}
|
||||
termora.transport.table.contextmenu.edit-command=Прежде чем редактировать файл, необходимо настроить «Команду редактирования» в разделе «Настройки — SFTP».
|
||||
termora.transport.table.contextmenu.copy-path=Копировать Путь
|
||||
termora.transport.table.contextmenu.open-in-folder=Открыть в {0}
|
||||
termora.transport.table.contextmenu.rename=${termora.welcome.contextmenu.rename}
|
||||
termora.transport.table.contextmenu.delete=${termora.remove}
|
||||
termora.transport.table.contextmenu.delete-warning=Если папка слишком большая, ее удаление может занять некоторое время.
|
||||
termora.transport.table.contextmenu.rm-warning=Использование команды rm -rf для удаления файла очень опасно.
|
||||
termora.transport.table.contextmenu.change-permissions=Изменить Разрешения...
|
||||
termora.transport.table.contextmenu.refresh=Обновить
|
||||
@@ -377,7 +375,6 @@ termora.visual-window.system-information.used-total=Использовано /
|
||||
termora.visual-window.nvidia-smi=NVIDIA SMI
|
||||
|
||||
|
||||
termora.floating-toolbar.not-supported=Это действие не поддерживается
|
||||
termora.floating-toolbar.close-in-current-tab=Закрыть в текущей вкладке
|
||||
|
||||
|
||||
|
||||
@@ -89,17 +89,14 @@ termora.settings.plugin=插件
|
||||
termora.settings.plugin.install=安装
|
||||
termora.settings.plugin.installed=已安装
|
||||
termora.settings.plugin.marketplace=市场
|
||||
termora.settings.plugin.subscribe=订阅
|
||||
termora.settings.plugin.install-subscription-confirm=安装 <b>{0}</b> 需要订阅
|
||||
termora.settings.plugin.uninstall=卸载
|
||||
termora.settings.plugin.uninstalled=已卸载
|
||||
termora.settings.plugin.cannot-uninstall=系统内置插件不可以卸载
|
||||
termora.settings.plugin.uninstall-confirm=你确定要卸载 <b>{0}</b> 吗?
|
||||
termora.settings.plugin.uninstall-failed=卸载失败
|
||||
termora.settings.plugin.install-from-disk=从磁盘安装插件...
|
||||
termora.settings.plugin.manage-plugin-repository=管理插件仓库...
|
||||
termora.settings.plugin.install-failed=安装失败,请稍后再试
|
||||
termora.settings.plugin.install-from-disk-warning=<b>{0}</b> 插件可以访问你的所有数据,你确定要安装吗?
|
||||
termora.settings.plugin.not-compatible=插件 <b>{0}</b> 与当前版本不兼容,请重新安装 <b>{0}</b>
|
||||
|
||||
termora.settings.account=账号
|
||||
termora.settings.account.login=登录
|
||||
@@ -317,7 +314,6 @@ termora.transport.table.owner=所有者
|
||||
# contextmenu
|
||||
termora.transport.table.contextmenu.transfer=传输
|
||||
termora.transport.table.contextmenu.copy-path=复制路径
|
||||
termora.transport.table.contextmenu.edit-command=你必须在 “设置 - SFTP” 中配置 “编辑命令” 后才能编辑文件
|
||||
termora.transport.table.contextmenu.open-in-folder=在${termora.finder}中打开
|
||||
termora.transport.table.contextmenu.change-permissions=更改权限...
|
||||
termora.transport.table.contextmenu.refresh=刷新
|
||||
@@ -327,7 +323,6 @@ termora.transport.table.contextmenu.extract.here=解压到当前目录
|
||||
termora.transport.table.contextmenu.extract.single=解压到 {0}\\
|
||||
termora.transport.table.contextmenu.extract.multi=解压到 *\\*
|
||||
termora.transport.table.contextmenu.new.file=${termora.transport.table.contextmenu.new}文件
|
||||
termora.transport.table.contextmenu.delete-warning=如果文件夹太大,删除可能需要耗费一定时间
|
||||
termora.transport.table.contextmenu.rm-warning=使用 rm -rf 命令删除文件存在很大风险
|
||||
|
||||
termora.transport.sftp=传输
|
||||
@@ -426,7 +421,6 @@ termora.visual-window.system-information.swap=交换
|
||||
termora.visual-window.system-information.filesystem=文件系统
|
||||
termora.visual-window.system-information.used-total=使用 / 大小
|
||||
|
||||
termora.floating-toolbar.not-supported=不允许此操作
|
||||
termora.floating-toolbar.close-in-current-tab=在当前标签页关闭
|
||||
|
||||
|
||||
|
||||
@@ -99,17 +99,14 @@ termora.settings.plugin=插件
|
||||
termora.settings.plugin.install=安裝
|
||||
termora.settings.plugin.installed=已安裝
|
||||
termora.settings.plugin.marketplace=市場
|
||||
termora.settings.plugin.subscribe=訂閱
|
||||
termora.settings.plugin.install-subscription-confirm=安裝 <b>{0}</b> 需要訂閱
|
||||
termora.settings.plugin.uninstall=解除安裝
|
||||
termora.settings.plugin.uninstalled=已解除安裝
|
||||
termora.settings.plugin.cannot-uninstall=系統內建插件無法卸載
|
||||
termora.settings.plugin.uninstall-confirm=你確定要卸載 <b>{0}</b> 嗎?
|
||||
termora.settings.plugin.uninstall-failed=解除安裝失敗
|
||||
termora.settings.plugin.install-from-disk=從磁碟安裝插件...
|
||||
termora.settings.plugin.manage-plugin-repository=管理插件倉庫...
|
||||
termora.settings.plugin.install-failed=安裝失敗,請稍後再試
|
||||
termora.settings.plugin.install-from-disk-warning=<b>{0}</b> 插件可以存取你的所有數據,你確定要安裝嗎?
|
||||
termora.settings.plugin.not-compatible=插件 <b>{0}</b> 與目前版本不相容,請重新安裝 <b>{0}</b>
|
||||
|
||||
termora.settings.account=帳號
|
||||
termora.settings.account.login=登入
|
||||
@@ -312,7 +309,6 @@ termora.transport.table.owner=所有者
|
||||
# contextmenu
|
||||
termora.transport.table.contextmenu.transfer=傳輸
|
||||
termora.transport.table.contextmenu.copy-path=複製路徑
|
||||
termora.transport.table.contextmenu.edit-command=你必須在 “設定 - SFTP” 中設定 “編輯指令” 後才能編輯文件
|
||||
termora.transport.table.contextmenu.open-in-folder=在${termora.finder}中打開
|
||||
termora.transport.table.contextmenu.change-permissions=更改權限...
|
||||
termora.transport.table.contextmenu.refresh=刷新
|
||||
@@ -322,7 +318,6 @@ termora.transport.table.contextmenu.extract.here=解壓縮到目前目錄
|
||||
termora.transport.table.contextmenu.extract.single=解壓縮到 {0}\\
|
||||
termora.transport.table.contextmenu.extract.multi=解壓縮到 *\\*
|
||||
termora.transport.table.contextmenu.new.file=${termora.transport.table.contextmenu.new}文件
|
||||
termora.transport.table.contextmenu.delete-warning=如果資料夾太大,刪除可能需要耗費一定時間
|
||||
termora.transport.table.contextmenu.rm-warning=使用 rm -rf 命令刪除資料存在很大風險
|
||||
|
||||
termora.transport.sftp=傳輸
|
||||
@@ -413,7 +408,6 @@ termora.visual-window.system-information.swap=交換
|
||||
termora.visual-window.system-information.filesystem=檔案系統
|
||||
termora.visual-window.system-information.used-total=使用 / 大小
|
||||
|
||||
termora.floating-toolbar.not-supported=不允許此操作
|
||||
termora.floating-toolbar.close-in-current-tab=在目前標籤頁關閉
|
||||
|
||||
# zmodem
|
||||
|
||||
Reference in New Issue
Block a user