帆软报表设计器源代码。
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

231 lines
11 KiB

package com.fr.design.mainframe.app;
import com.fr.design.DesignerEnvManager;
import com.fr.design.dialog.DialogActionAdapter;
import com.fr.design.dialog.UIExpandDialog;
import com.fr.design.extra.exe.callback.InstallOnlineCallback;
import com.fr.design.extra.exe.callback.ModifyStatusCallback;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.app.PluginRemote.PluginStatus;
import com.fr.locale.InterProviderFactory;
import com.fr.plugin.context.PluginMarker;
import com.fr.plugin.context.PluginMarkerAdapter;
import com.fr.plugin.manage.PluginManager;
import com.fr.plugin.manage.control.PluginControllerHelper;
import com.fr.plugin.manage.control.PluginExtraInfo;
import com.fr.plugin.manage.control.PluginTask;
import com.fr.plugin.observer.PluginEvent;
import com.fr.plugin.observer.PluginEventListener;
import com.fr.plugin.observer.PluginEventType;
import com.fr.plugin.observer.PluginListenerRegistration;
import com.fr.stable.StringUtils;
import com.fr.stable.TemplateIOErrorContextHolder;
import com.fr.third.guava.cache.Cache;
import com.fr.third.guava.cache.CacheBuilder;
import com.fr.third.guava.collect.Multimap;
import com.fr.workspace.WorkContext;
import javax.swing.SwingUtilities;
import java.time.Duration;
import java.util.Collection;
import java.util.Map;
import java.util.stream.Collectors;
/**
* 设计器app共用工具类
*
* @author vito
* @version 10.0
* Created by vito on 2021/5/27
*/
public class DesignerAppUtils {
private static final int DEFAULT_MAX_CACHE_SIZE = 50;
private static final int DEFAULT_CONCURRENCY_LEVEL = 8;
private static final long DEFAULT_EXPIRE_HOURS = 1;
private volatile static boolean enablePluginTipDialog = true;
private static final Cache<String, Multimap<String, PluginMarkerAdapter>> ERROR_CACHE = CacheBuilder.newBuilder()
.maximumSize(DEFAULT_MAX_CACHE_SIZE)
.expireAfterAccess(Duration.ofHours(DEFAULT_EXPIRE_HOURS))
.concurrencyLevel(DEFAULT_CONCURRENCY_LEVEL)
.build();
public static void initPluginAllActiveListener() {
PluginListenerRegistration.getInstance().listen(PluginEventType.BeforeAllStop, new PluginEventListener() {
@Override
public void on(PluginEvent event) {
enablePluginTipDialog = false;
}
});
PluginListenerRegistration.getInstance().listen(PluginEventType.AfterAllActive, new PluginEventListener() {
@Override
public void on(PluginEvent event) {
enablePluginTipDialog = true;
}
});
}
/**
* 弹出指定的插件信息,
* 并失效缓存
*
* @param key 指定key
* @return 插件安装信息
*/
public static Multimap<String, PluginMarkerAdapter> popPluginInfoMap(String key) {
Multimap<String, PluginMarkerAdapter> ifPresent = ERROR_CACHE.getIfPresent(key);
ERROR_CACHE.invalidate(key);
return ifPresent;
}
/**
* 失效指定的插件信息缓存
*
* @param key 指定key
*/
public static void invalidatePlugins(String key) {
ERROR_CACHE.invalidate(key);
}
/**
* 格式化多行插件错误信息详情并缓存,
* 用于界面展示
*
* @param key 缓存key
* @return 格式化后的多行插件错误信息详情
*/
public static String dealWithErrorDetailMultiLineAndCache(String key) {
if (!DesignerEnvManager.getEnvManager().isShowTemplateMissingPlugin() || !enablePluginTipDialog) {
// 直接清空不提示
TemplateIOErrorContextHolder.reset();
return StringUtils.EMPTY;
}
Multimap<String, PluginMarkerAdapter> pendingPlugins = TemplateIOErrorContextHolder.getPendingPlugin();
if (pendingPlugins.isEmpty()) {
return StringUtils.EMPTY;
}
dealWithRemote(pendingPlugins);
StringBuilder sb = new StringBuilder();
if (WorkContext.getCurrent().isLocal()) {
// 缓存等待后续处理
ERROR_CACHE.put(key, pendingPlugins);
}
Collection<PluginMarkerAdapter> unknownPlugins = pendingPlugins.get(TemplateIOErrorContextHolder.UNKNOWN_PLUGIN);
if (!unknownPlugins.isEmpty()) {
sb.append(InterProviderFactory.getProvider().getLocText("Fine-Core_Plugin_Error_UnknownPlugin")).append(":\n");
for (PluginMarkerAdapter pluginMarker : unknownPlugins) {
sb.append("\"").append(pluginMarker.getPluginID()).append("\"")
.append(InterProviderFactory.getProvider().getLocText("Fine-Dec_Platform_Plugin")).append('\n');
}
}
Collection<PluginMarkerAdapter> notInstalledPlugins = pendingPlugins.get(TemplateIOErrorContextHolder.NOT_INSTALLED_PLUGIN);
if (!notInstalledPlugins.isEmpty()) {
sb.append(InterProviderFactory.getProvider().getLocText("Fine-Core_Plugin_Error_UninstalledPlugins")).append(":\n");
for (PluginMarkerAdapter pluginMarker : notInstalledPlugins) {
sb.append("\"").append(pluginMarker.getPluginName()).append("\"")
.append(InterProviderFactory.getProvider().getLocText("Fine-Dec_Platform_Plugin")).append('\n');
}
}
Collection<PluginMarkerAdapter> disablePlugins = pendingPlugins.get(TemplateIOErrorContextHolder.DISABLE_PLUGIN);
if (!disablePlugins.isEmpty()) {
sb.append(InterProviderFactory.getProvider().getLocText("Fine-Core_Plugin_Error_InactivePlugins")).append(":\n");
for (PluginMarkerAdapter pluginMarker : disablePlugins) {
sb.append("\"").append(pluginMarker.getPluginName()).append("\"")
.append(InterProviderFactory.getProvider().getLocText("Fine-Dec_Platform_Plugin")).append('\n');
}
}
return sb.toString();
}
/**
* 远程环境下需要特殊处理远程服务器尚未安装的插件
*
* @param pendingPlugins 待处理插件
*/
private static void dealWithRemote(Multimap<String, PluginMarkerAdapter> pendingPlugins) {
if (!WorkContext.getCurrent().isLocal()) {
rearrange(pendingPlugins);
}
}
/**
* 远程设计重新整理下列表
*
* @param pendingPlugins 待处理列表
*/
public static void rearrange(Multimap<String, PluginMarkerAdapter> pendingPlugins) {
Map<String, PluginStatus> pluginRemoteStatus = PluginRemote.getInstance().getPluginRemoteStatus();
Collection<PluginMarkerAdapter> unknownPlugins = pendingPlugins.get(TemplateIOErrorContextHolder.UNKNOWN_PLUGIN);
Collection<PluginMarkerAdapter> notInstall = pendingPlugins.get(TemplateIOErrorContextHolder.NOT_INSTALLED_PLUGIN);
Collection<PluginMarkerAdapter> disable = pendingPlugins.get(TemplateIOErrorContextHolder.DISABLE_PLUGIN);
unknownPlugins.removeIf(adapter -> pluginRemoteStatus.containsKey(adapter.getPluginID()));
// 本地未启用名单不准确添加到一起之后重新分配
notInstall.addAll(disable);
disable.clear();
// 从所有未安装中过滤远程未启用的,添加到未启用列表
disable.addAll(notInstall.stream().filter(plugin ->
pluginRemoteStatus.containsKey(plugin.getPluginID())
&& !pluginRemoteStatus.get(plugin.getPluginID()).isRunning())
.collect(Collectors.toList()));
// 清理未安装中所有远程安装过的插件(包含启用和未启用)
notInstall.removeIf(adapter -> pluginRemoteStatus.containsKey(adapter.getPluginID()));
}
/**
* 处理模板读取时的异常
*
* @param path 模板路径
*/
public static void dealWithTemplateIOError(String path) {
// 试图获取多行读取错误提示并缓存待处理列表
String detail = dealWithErrorDetailMultiLineAndCache(path);
if (detail.length() > 0) {
SwingUtilities.invokeLater(() -> {
if (WorkContext.getCurrent().isLocal()) {
UIExpandDialog.Builder()
.owner(DesignerContext.getDesignerFrame())
.title(Toolkit.i18nText("Fine-Design_Basic_Tool_Tips"))
.message(Toolkit.i18nText("Fine-Design_Template_Plugin_Error_Message_Local"))
.detail(detail)
.okText(Toolkit.i18nText("Fine-Design_Template_Plugin_Error_OK_Btn"))
.cancelText(Toolkit.i18nText("Fine-Design_Template_Plugin_Error_Cancel_Btn"))
.dialogActionListener(new DialogActionAdapter() {
public void doOk() {
installAndEnablePlugin(path);
}
@Override
public void doCancel() {
invalidatePlugins(path);
}
}).build().setVisible(true);
} else {
UIExpandDialog.Builder().owner(DesignerContext.getDesignerFrame())
.title(Toolkit.i18nText("Fine-Design_Basic_Tool_Tips"))
.cancelText(StringUtils.EMPTY)
.message(Toolkit.i18nText("Fine-Design_Template_Plugin_Error_Message_Remote"))
.detail(detail)
.build()
.setVisible(true);
}
});
}
}
private static void installAndEnablePlugin(String key) {
Multimap<String, PluginMarkerAdapter> stringPluginMarkerAdapterMultimap = popPluginInfoMap(key);
Collection<PluginMarkerAdapter> disablePlugins = stringPluginMarkerAdapterMultimap.get(TemplateIOErrorContextHolder.DISABLE_PLUGIN);
for (PluginMarkerAdapter disablePlugin : disablePlugins) {
PluginManager.getController().enable(disablePlugin, new ModifyStatusCallback(false));
}
Collection<PluginMarkerAdapter> uninstallPlugins = stringPluginMarkerAdapterMultimap.get(TemplateIOErrorContextHolder.NOT_INSTALLED_PLUGIN);
for (PluginMarker uninstallPlugin : uninstallPlugins) {
PluginTask pluginTask = PluginTask.installTask(uninstallPlugin);
PluginControllerHelper.installOnline(uninstallPlugin, new InstallOnlineCallback(pluginTask), PluginExtraInfo.newBuilder().username(DesignerEnvManager.getEnvManager().getDesignerLoginUsername()).build());
}
}
}