Browse Source

Pull request #3167: KERNEL-6380 在部分插件切换的时候,需要有一个集中刷新缓存的地方

Merge in DESIGN/design from ~HADES/design:KERNEL-6380 to release/10.0

* commit '8e34fc7c12c1d4220e89794d62d6047913339281':
  KERNEL-6380  调整下返回点
  KERNEL-6380  添加一些注释
  KERNEL-6380 修改名称
  KERNEL-6380 调整下接口调用
  KERNEL-6380 解耦 仅处理插件afterRun生命周期 + 重命名
  KERNEL-6380 在部分插件切换的时候,需要有一个集中刷新缓存的地方
  KERNEL-6380 格式调整
  KERNEL-6380 在部分插件切换的时候,需要有一个集中刷新缓存的地方
  KERNEL-6380 在部分插件切换的时候,需要有一个集中刷新缓存的地方
feature/big-screen
ju|剧浩宇 4 years ago
parent
commit
36eeab068f
  1. 78
      designer-base/src/main/java/com/fr/design/PluginClassRefreshManager.java
  2. 32
      designer-base/src/main/java/com/fr/design/data/datapane/TableDataTreePane.java
  3. 104
      designer-base/src/main/java/com/fr/design/file/HistoryTemplateListCache.java
  4. 1
      designer-base/src/main/java/com/fr/design/gui/frpane/HyperlinkGroupPane.java
  5. 8
      designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java
  6. 29
      designer-base/src/test/java/com/fr/base/ClassHelperTest.java
  7. 2
      designer-realize/src/main/java/com/fr/start/module/DesignerInitActivator.java
  8. 4
      designer-realize/src/main/java/com/fr/start/module/DesignerWorkspaceActivator.java

78
designer-base/src/main/java/com/fr/design/PluginClassRefreshManager.java

@ -0,0 +1,78 @@
package com.fr.design;
import com.fr.design.constants.DesignerLaunchStatus;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.fun.HyperlinkProvider;
import com.fr.design.fun.TableDataDefineProvider;
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 java.util.HashSet;
import java.util.Set;
/**
*
* @author hades
* @version 10.0
* Created by hades on 2020/12/17
*/
public class PluginClassRefreshManager {
private static final PluginClassRefreshManager INSTANCE = new PluginClassRefreshManager();
private final Set<String> context = new HashSet<>();
private final PluginEventListener pluginAfterRunEventListener = new PluginEventListener() {
@Override
public void on(PluginEvent event) {
// 兼容之前版本特性
for (String tag : context) {
if (event.getContext().contain(tag)) {
HistoryTemplateListCache.getInstance().reloadAllEditingTemplate();
return;
}
}
// 重新载入模板xml内容 到 Workbook/Form对象中
HistoryTemplateListCache.getInstance().reloadAllEditingTemplateByPlugin(event.getContext());
}
};
public static PluginClassRefreshManager getInstance() {
return INSTANCE;
}
public void load() {
context.add(TableDataDefineProvider.XML_TAG);
context.add(HyperlinkProvider.XML_TAG);
}
private PluginClassRefreshManager() {
PluginListenerRegistration.getInstance().listen(PluginEventType.BeforeAllActive, new PluginEventListener() {
@Override
public void on(PluginEvent event) {
removePluginListener();
}
});
PluginListenerRegistration.getInstance().listen(PluginEventType.AfterAllActive, new PluginEventListener() {
@Override
public void on(PluginEvent event) {
addPluginListener();
if (DesignerLaunchStatus.getStatus() != DesignerLaunchStatus.WORKSPACE_INIT_COMPLETE) {
HistoryTemplateListCache.getInstance().reloadAllEditingTemplate();
}
}
});
}
public void removePluginListener() {
PluginListenerRegistration.getInstance().stopListen(this.pluginAfterRunEventListener);
}
public void addPluginListener() {
PluginListenerRegistration.getInstance().listen(PluginEventType.AfterRun, this.pluginAfterRunEventListener);
}
}

32
designer-base/src/main/java/com/fr/design/data/datapane/TableDataTreePane.java

@ -18,8 +18,6 @@ import com.fr.design.dialog.BasicDialog;
import com.fr.design.dialog.BasicPane;
import com.fr.design.dialog.DialogActionAdapter;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.fun.TableDataDefineProvider;
import com.fr.design.fun.TableDataPaneProcessor;
import com.fr.design.gui.ibutton.UIHeadGroup;
import com.fr.design.gui.icontainer.UIScrollPane;
@ -28,7 +26,6 @@ import com.fr.design.gui.itoolbar.UIToolbar;
import com.fr.design.icon.IconPathConstants;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.menu.MenuDef;
import com.fr.design.menu.SeparatorDef;
import com.fr.design.menu.ToolBarDef;
@ -97,7 +94,6 @@ public class TableDataTreePane extends BasicTableDataTreePane {
addMenuDef.setIconPath(IconPathConstants.ADD_POPMENU_ICON_PATH);
createAddMenuDef();
// 创建插件监听
createPluginListener();
@ -160,34 +156,6 @@ public class TableDataTreePane extends BasicTableDataTreePane {
return context.contain(PluginModule.ExtraDesign);
}
});
//监听数据集插件
GeneralContext.listenPluginRunningChanged(new PluginEventListener() {
@Override
public void on(PluginEvent event) {
//REPORT-25577
//如果数据集插件禁用或启用。需要清空当前模板中的缓存
reloadCurrTemplate();
}
private void reloadCurrTemplate() {
JTemplate<?, ?> jt = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
if (accept(jt)) {
jt.refreshResource();
}
}
private boolean accept(JTemplate<?, ?> jt) {
return jt != null && jt.getEditingFILE() != null && jt.getEditingFILE().exists();
}
}, new PluginFilter() {
@Override
public boolean accept(PluginContext pluginContext) {
return pluginContext.contain(TableDataDefineProvider.XML_TAG);
}
});
}

104
designer-base/src/main/java/com/fr/design/file/HistoryTemplateListCache.java

@ -17,7 +17,10 @@ import com.fr.file.FILE;
import com.fr.file.FileNodeFILE;
import com.fr.file.StashedFILE;
import com.fr.general.ComparatorUtils;
import com.fr.invoke.ClassHelper;
import com.fr.log.FineLoggerFactory;
import com.fr.plugin.context.PluginContext;
import com.fr.plugin.manage.PluginManager;
import com.fr.stable.CoreConstants;
import com.fr.stable.StringUtils;
import com.fr.third.org.apache.commons.io.FilenameUtils;
@ -29,6 +32,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Set;
/**
* 历史模板缓存
@ -370,7 +374,6 @@ public class HistoryTemplateListCache implements CallbackEvent {
*/
public void load() {
FineLoggerFactory.getLogger().info("Env Change Template Loading...");
JTemplate currentTemplate = null;
if (stashFILEMap != null && stashFILEMap.size() != 0) {
int size = historyList.size();
for (int i = 0; i < size; i++) {
@ -381,32 +384,14 @@ public class HistoryTemplateListCache implements CallbackEvent {
if (stashedFile == null) {
continue;
}
JTemplate<?, ?> template = JTemplateFactory.createJTemplate(stashedFile);
if (template != null) {
historyList.set(i, template);
// 替换当前正在编辑的模板,使用添加并激活的方式,以便使用统一的入口来处理监听事件
if (isCurrentEditingFile(template.getPath())) {
currentTemplate = template;
}
} else {
// 当模板为空时 说明是一个新建的未保存模板 但是内存中保存了该模板 可以从中获取
JTemplate jt = historyList.get(i);
// 另外如果该模板是正在编辑的模板,需要要激活
if (jt != null && isCurrentEditingFile(jt.getPath())) {
currentTemplate = jt;
}
}
FineLoggerFactory.getLogger().info("{} is being reloaded", stashedFile.getName());
JTemplate<?, ?> template = historyList.get(i);
template.refreshResource(stashedFile);
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
// 最后加载当前正在编辑的模板 以保证数据集刷新正常
if (currentTemplate != null) {
loadCurrentTemplate(currentTemplate);
}
stashFILEMap.clear();
MutilTempalteTabPane.getInstance().refreshOpenedTemplate(historyList);
MutilTempalteTabPane.getInstance().repaint();
}
FineLoggerFactory.getLogger().info("Env Change Template Loaded.");
}
@ -420,12 +405,9 @@ public class HistoryTemplateListCache implements CallbackEvent {
/**
* 重新载入当前模板刷新数据/对象
*/
@Deprecated
public void reloadCurrentTemplate() {
JTemplate<?, ?> jt = getCurrentEditingTemplate();
boolean access = jt != null && jt.getEditingFILE() != null && jt.getEditingFILE().exists();
if (access) {
jt.refreshResource();
}
reloadAllEditingTemplate();
}
/**
@ -440,4 +422,72 @@ public class HistoryTemplateListCache implements CallbackEvent {
});
}
/**
* 插件安装后/启用 重新加载模板资源
*/
private void _reloadAllEditingTemplate(PluginContext context) {
FineLoggerFactory.getLogger().info("Plugin env change reload all template started");
long start = System.currentTimeMillis();
int size = historyList.size();
for (int i = 0; i < size; i++) {
JTemplate<?, ?> template = historyList.get(i);
FILE file = template.getEditingFILE();
boolean needReload = context == null || needReloadTemplate(context, template);
if (needReload) {
try {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
BaseBook target = template.getTarget();
if (target != null) {
FineLoggerFactory.getLogger().info("{} is being reloaded", file.getName());
target.export(outputStream);
FILE stashedFile = new StashedFILE(file, outputStream.toByteArray());
template.refreshResource(stashedFile);
}
// 如果 target == null 那么这个模板是被模板内存优化功能处理过的,不用处理
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
}
FineLoggerFactory.getLogger().info("Plugin env change reload all template ended");
FineLoggerFactory.getLogger().info("Reload all template spend: {} ms", (System.currentTimeMillis() - start));
}
/**
* 根据具体插件来刷新模板
* @param context
*/
public void reloadAllEditingTemplateByPlugin(PluginContext context) {
_reloadAllEditingTemplate(context);
}
/**
* 直接刷新所以模板
*/
public void reloadAllEditingTemplate() {
_reloadAllEditingTemplate(null);
}
private boolean needReloadTemplate(PluginContext context, JTemplate<?, ?> template) {
BaseBook baseBook = template.getTarget();
if (baseBook != null) {
String name = template.getEditingFILE().getName();
String pluginId = context.getID();
long start = System.currentTimeMillis();
Set<ClassLoader> set = ClassHelper.getClassLoaders(baseBook);
FineLoggerFactory.getLogger().info("{} find plugin classloader spend: {} ms", name, (System.currentTimeMillis() - start));
if (set != null) {
for (ClassLoader classLoader : set) {
if (ComparatorUtils.equals(pluginId, PluginManager.detectLeakingPlugin(classLoader))) {
return true;
}
}
} else {
// set为null说明 检测classloader 这里返回true直接刷新 兜底行为
return true;
}
}
return false;
}
}

1
designer-base/src/main/java/com/fr/design/gui/frpane/HyperlinkGroupPane.java

@ -46,7 +46,6 @@ public abstract class HyperlinkGroupPane extends UIListControlPane {
@Override
public void on(PluginEvent event) {
refreshNameableCreator(createNameableCreators());
HistoryTemplateListCache.getInstance().reloadCurrentTemplate();
}
}, new PluginFilter() {

8
designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java

@ -47,6 +47,7 @@ import com.fr.design.menu.MenuDef;
import com.fr.design.menu.NameSeparator;
import com.fr.design.menu.ShortCut;
import com.fr.design.preview.PagePreview;
import com.fr.design.ui.util.UIUtil;
import com.fr.design.write.submit.DBManipulationInWidgetEventPane;
import com.fr.design.write.submit.DBManipulationPane;
import com.fr.event.EventDispatcher;
@ -332,10 +333,15 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
* CenterPane 负责监听改动
* 所以需要同步处理
*/
@Deprecated
public void refreshResource() {
refreshResource(this.editingFILE);
}
public void refreshResource(FILE file) {
try {
this.template = JTemplateFactory.asIOFile(this.editingFILE);
this.template = JTemplateFactory.asIOFile(file);
setTarget(this.template);
// 先移除旧的。

29
designer-base/src/test/java/com/fr/base/ClassHelperTest.java

@ -0,0 +1,29 @@
package com.fr.base;
import com.fr.form.main.Form;
import com.fr.invoke.ClassHelper;
import com.fr.main.impl.WorkBook;
import java.util.Set;
import junit.framework.TestCase;
import org.junit.Assert;
/**
* @author hades
* @version 10.0
* Created by hades on 2020/12/28
*/
public class ClassHelperTest extends TestCase {
public void testGetClassLoaders() {
WorkBook workBook = new WorkBook();
Set<ClassLoader> set = ClassHelper.getClassLoaders(workBook);
Assert.assertFalse(set.isEmpty());
Form form = new Form();
Set<ClassLoader> set1 = ClassHelper.getClassLoaders(form);
Assert.assertFalse(set1.isEmpty());
}
}

2
designer-realize/src/main/java/com/fr/start/module/DesignerInitActivator.java

@ -1,5 +1,6 @@
package com.fr.start.module;
import com.fr.design.PluginClassRefreshManager;
import com.fr.module.Activator;
import com.fr.start.DesignerInitial;
@ -15,6 +16,7 @@ public class DesignerInitActivator extends Activator {
@Override
public void start() {
PluginClassRefreshManager.getInstance().load();
DesignerInitial.init(findSingleton(StartupArgs.class).get());
}

4
designer-realize/src/main/java/com/fr/start/module/DesignerWorkspaceActivator.java

@ -1,6 +1,7 @@
package com.fr.start.module;
import com.fr.concurrent.NamedThreadFactory;
import com.fr.design.PluginRefreshManager;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.event.Event;
import com.fr.event.Listener;
@ -50,7 +51,7 @@ public class DesignerWorkspaceActivator extends Activator {
@Override
public void on(Event event, Workspace workspace) {
PluginRefreshManager.getInstance().removePluginListener();
HistoryTemplateListCache.getInstance().stash();
}
});
@ -62,6 +63,7 @@ public class DesignerWorkspaceActivator extends Activator {
public void on(Event event, Workspace workspace) {
HistoryTemplateListCache.getInstance().load();
PluginRefreshManager.getInstance().addPluginListener();
}
});
}

Loading…
Cancel
Save