Browse Source

REPORT-13202 包含插件控件的模板切换环境后存储出错

bugfix/10.0
yaoh.wu 6 years ago
parent
commit
0966e83473
  1. 33
      designer-base/src/main/java/com/fr/design/file/HistoryTemplateListCache.java
  2. 10
      designer-base/src/main/java/com/fr/design/mainframe/AbstractAppProvider.java
  3. 68
      designer-base/src/main/java/com/fr/design/mainframe/DesignerFrame.java
  4. 63
      designer-base/src/main/java/com/fr/design/mainframe/JTemplateFactory.java
  5. 106
      designer-base/src/main/java/com/fr/file/StashedFILE.java
  6. 6
      designer-realize/src/main/java/com/fr/design/mainframe/app/DesignerAppActivator.java
  7. 15
      designer-realize/src/main/java/com/fr/start/module/DesignerStartup.java
  8. 16
      designer-realize/src/main/java/com/fr/start/module/WorkspaceEventPriority.java

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

@ -2,7 +2,6 @@ package com.fr.design.file;
import com.fr.base.chart.chartdata.CallbackEvent; import com.fr.base.chart.chartdata.CallbackEvent;
import com.fr.base.io.BaseBook; import com.fr.base.io.BaseBook;
import com.fr.base.io.IOFile;
import com.fr.design.DesignerEnvManager; import com.fr.design.DesignerEnvManager;
import com.fr.design.base.mode.DesignModeContext; import com.fr.design.base.mode.DesignModeContext;
import com.fr.design.data.DesignTableDataManager; import com.fr.design.data.DesignTableDataManager;
@ -10,17 +9,18 @@ import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.DesignerContext; import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.DesignerFrameFileDealerPane; import com.fr.design.mainframe.DesignerFrameFileDealerPane;
import com.fr.design.mainframe.JTemplate; import com.fr.design.mainframe.JTemplate;
import com.fr.design.mainframe.JTemplateFactory;
import com.fr.design.mainframe.JVirtualTemplate; import com.fr.design.mainframe.JVirtualTemplate;
import com.fr.design.module.DesignModuleFactory; import com.fr.design.module.DesignModuleFactory;
import com.fr.file.FILE; import com.fr.file.FILE;
import com.fr.file.FileNodeFILE; import com.fr.file.FileNodeFILE;
import com.fr.file.StashedFILE;
import com.fr.general.ComparatorUtils; import com.fr.general.ComparatorUtils;
import com.fr.log.FineLoggerFactory; import com.fr.log.FineLoggerFactory;
import com.fr.stable.CoreConstants; import com.fr.stable.CoreConstants;
import com.fr.stable.StringUtils; import com.fr.stable.StringUtils;
import com.fr.third.org.apache.commons.io.FilenameUtils; import com.fr.third.org.apache.commons.io.FilenameUtils;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
@ -315,7 +315,7 @@ public class HistoryTemplateListCache implements CallbackEvent {
/** /**
* 切换环境时暂存打开的模板内容key 是在历史中的indexvalue 是模板xml 内容byte[] * 切换环境时暂存打开的模板内容key 是在历史中的indexvalue 是模板xml 内容byte[]
*/ */
private Map<Integer, byte[]> bytesMap; private Map<Integer, FILE> stashFILEMap;
/** /**
* 切换环境前将正在编辑的模板暂存起来并且在新环境中重新读取一遍暂存的不是模板文件的内容而是模板对象的内容 * 切换环境前将正在编辑的模板暂存起来并且在新环境中重新读取一遍暂存的不是模板文件的内容而是模板对象的内容
@ -326,20 +326,21 @@ public class HistoryTemplateListCache implements CallbackEvent {
*/ */
public void stash() { public void stash() {
FineLoggerFactory.getLogger().info("Env Change Template Stashing..."); FineLoggerFactory.getLogger().info("Env Change Template Stashing...");
if (bytesMap == null) { if (stashFILEMap == null) {
bytesMap = new HashMap<Integer, byte[]>(); stashFILEMap = new HashMap<Integer, FILE>();
} else { } else {
bytesMap.clear(); stashFILEMap.clear();
} }
int size = historyList.size(); int size = historyList.size();
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
JTemplate<?, ?> template = historyList.get(i); JTemplate<?, ?> template = historyList.get(i);
FILE file = template.getEditingFILE();
try { try {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
BaseBook target = template.getTarget(); BaseBook target = template.getTarget();
if (target != null) { if (target != null) {
target.export(outputStream); target.export(outputStream);
bytesMap.put(i, outputStream.toByteArray()); stashFILEMap.put(i, new StashedFILE(file, outputStream.toByteArray()));
} }
// 如果 target == null 那么这个模板是被模板内存优化功能处理过的,不用处理 // 如果 target == null 那么这个模板是被模板内存优化功能处理过的,不用处理
} catch (Exception e) { } catch (Exception e) {
@ -358,27 +359,25 @@ public class HistoryTemplateListCache implements CallbackEvent {
*/ */
public void load() { public void load() {
FineLoggerFactory.getLogger().info("Env Change Template Loading..."); FineLoggerFactory.getLogger().info("Env Change Template Loading...");
if (bytesMap != null && bytesMap.size() != 0) { if (stashFILEMap != null && stashFILEMap.size() != 0) {
int size = historyList.size(); int size = historyList.size();
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
try { try {
byte[] bytes = bytesMap.get(i); FILE stashedFile = stashFILEMap.get(i);
// 可能有模板 stash 失败的情况,在 load 的时候不更新它 // 可能有模板 stash 失败的情况,在 load 的时候不更新它
if (bytes == null) { // 或者这个模板是被模板内存优化功能处理过的,不用处理
if (stashedFile == null) {
continue; continue;
} }
ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes); JTemplate<?, ?> template = JTemplateFactory.createJTemplate(stashedFile);
BaseBook target = historyList.get(i).getTarget(); if (template != null) {
if (target != null) { historyList.set(i, template);
// todo readStream 这个行为应该上升到 BaseBook 上
((IOFile) target).readStream(inputStream);
} }
// 如果 target == null 那么这个模板是被模板内存优化功能处理过的,不用处理
} catch (Exception e) { } catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e); FineLoggerFactory.getLogger().error(e.getMessage(), e);
} }
} }
bytesMap.clear(); stashFILEMap.clear();
MutilTempalteTabPane.getInstance().refreshOpenedTemplate(historyList); MutilTempalteTabPane.getInstance().refreshOpenedTemplate(historyList);
MutilTempalteTabPane.getInstance().repaint(); MutilTempalteTabPane.getInstance().repaint();
} }

10
designer-base/src/main/java/com/fr/design/mainframe/AbstractAppProvider.java

@ -8,7 +8,7 @@ import com.fr.stable.fun.mark.API;
* Created by Administrator on 2016/3/17/0017. * Created by Administrator on 2016/3/17/0017.
*/ */
@API(level = App.CURRENT_LEVEL) @API(level = App.CURRENT_LEVEL)
public abstract class AbstractAppProvider<T extends IOFile> extends AbstractProvider implements App{ public abstract class AbstractAppProvider<T extends IOFile> extends AbstractProvider implements App {
public int currentAPILevel() { public int currentAPILevel() {
return CURRENT_LEVEL; return CURRENT_LEVEL;
@ -21,12 +21,12 @@ public abstract class AbstractAppProvider<T extends IOFile> extends AbstractProv
@Override @Override
public void process() { public void process() {
DesignerFrame.registApp(this); JTemplateFactory.register(this);
} }
@Override @Override
public void undo() { public void undo() {
DesignerFrame.removeApp(this); JTemplateFactory.remove(this);
} }
} }

68
designer-base/src/main/java/com/fr/design/mainframe/DesignerFrame.java

@ -51,7 +51,6 @@ import com.fr.plugin.injectable.PluginModule;
import com.fr.plugin.manage.PluginFilter; import com.fr.plugin.manage.PluginFilter;
import com.fr.plugin.observer.PluginEvent; import com.fr.plugin.observer.PluginEvent;
import com.fr.plugin.observer.PluginEventListener; import com.fr.plugin.observer.PluginEventListener;
import com.fr.stable.CoreConstants;
import com.fr.stable.OperatingSystem; import com.fr.stable.OperatingSystem;
import com.fr.stable.ProductConstants; import com.fr.stable.ProductConstants;
import com.fr.stable.StringUtils; import com.fr.stable.StringUtils;
@ -115,11 +114,9 @@ public class DesignerFrame extends JFrame implements JTemplateActionListener, Ta
private static final int MENU_HEIGHT = 26; private static final int MENU_HEIGHT = 26;
private static final Integer SECOND_LAYER = new Integer(100); private static final Integer SECOND_LAYER = 100;
private static final Integer TOP_LAYER = new Integer((200)); private static final Integer TOP_LAYER = 200;
private static java.util.List<App<?>> appList = new java.util.ArrayList<App<?>>();
private List<DesignerOpenedListener> designerOpenedListenerList = new ArrayList<>(); private List<DesignerOpenedListener> designerOpenedListenerList = new ArrayList<>();
@ -326,7 +323,7 @@ public class DesignerFrame extends JFrame implements JTemplateActionListener, Ta
this.progressDialog = new ProgressDialog(this); this.progressDialog = new ProgressDialog(this);
} }
public void closeAuthorityEditing(){ public void closeAuthorityEditing() {
DesignModeContext.switchTo(com.fr.design.base.mode.DesignerMode.NORMAL); DesignModeContext.switchTo(com.fr.design.base.mode.DesignerMode.NORMAL);
WestRegionContainerPane.getInstance().replaceDownPane( WestRegionContainerPane.getInstance().replaceDownPane(
TableDataTreePane.getInstance(DesignModelAdapter.getCurrentModelAdapter())); TableDataTreePane.getInstance(DesignModelAdapter.getCurrentModelAdapter()));
@ -342,19 +339,22 @@ public class DesignerFrame extends JFrame implements JTemplateActionListener, Ta
* 注册app. * 注册app.
* *
* @param app 注册app. * @param app 注册app.
* @deprecated use {@link JTemplateFactory#register(App)} instead
*/ */
@Deprecated
public static void registApp(App<?> app) { public static void registApp(App<?> app) {
JTemplateFactory.register(app);
if (app != null) {
appList.add(app);
}
} }
/**
* 移除app
*
* @param app app
* @deprecated use {@link JTemplateFactory#remove(App)} instead
*/
@Deprecated
public static void removeApp(App<?> app) { public static void removeApp(App<?> app) {
JTemplateFactory.remove(app);
if (app != null) {
appList.remove(app);
}
} }
/** /**
@ -1027,39 +1027,17 @@ public class DesignerFrame extends JFrame implements JTemplateActionListener, Ta
*/ */
private void openFile(FILE tplFile) { private void openFile(FILE tplFile) {
String fileName = tplFile.getName(); JTemplate jt = JTemplateFactory.createJTemplate(tplFile);
int indexOfLastDot = fileName.lastIndexOf(CoreConstants.DOT); if (jt == null) {
if (indexOfLastDot < 0) {
return; return;
} }
String fileExtention = fileName.substring(indexOfLastDot + 1); // 新的form不往前兼容
for (int i = 0, len = appList.size(); i < len; i++) { if (inValidDesigner(jt)) {
App<?> app = appList.get(i); this.addAndActivateJTemplate();
String[] defaultAppExtentions = app.defaultExtensions(); MutilTempalteTabPane.getInstance().setTemTemplate(
boolean opened = false; HistoryTemplateListPane.getInstance().getCurrentEditingTemplate());
for (int j = 0; j < defaultAppExtentions.length; j++) { } else {
if (defaultAppExtentions[j].equalsIgnoreCase(fileExtention)) { activeTemplate(jt);
// 不要catch
JTemplate jt = app.openTemplate(tplFile);
if (jt == null) {
return;
}
// 新的form不往前兼容
if (inValidDesigner(jt)) {
this.addAndActivateJTemplate();
MutilTempalteTabPane.getInstance().setTemTemplate(
HistoryTemplateListPane.getInstance().getCurrentEditingTemplate());
} else {
activeTemplate(jt);
}
opened = true;
break;
}
}
if (opened) {
break;
}
} }
} }

63
designer-base/src/main/java/com/fr/design/mainframe/JTemplateFactory.java

@ -0,0 +1,63 @@
package com.fr.design.mainframe;
import com.fr.file.FILE;
import com.fr.stable.CoreConstants;
import com.fr.third.javax.annotation.Nonnull;
import com.fr.third.javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
public final class JTemplateFactory {
private static final List<App<?>> ALL_APP = new ArrayList<App<?>>();
private JTemplateFactory() {
}
/**
* 生成设计器编辑模板对象
*
* @param file 包含了模板名称类型以及内容的文件
* @return 设计器编辑的模板对象
*/
@Nullable
public static JTemplate<?, ?> createJTemplate(@Nonnull FILE file) {
String fileName = file.getName();
int indexOfLastDot = fileName.lastIndexOf(CoreConstants.DOT);
if (indexOfLastDot < 0) {
return null;
}
String fileExtension = fileName.substring(indexOfLastDot + 1);
for (App<?> app : ALL_APP) {
String[] defaultAppExtensions = app.defaultExtensions();
for (String defaultAppExtension : defaultAppExtensions) {
if (defaultAppExtension.equalsIgnoreCase(fileExtension)) {
JTemplate<?, ?> jt = app.openTemplate(file);
if (jt != null) {
return jt;
}
}
}
}
return null;
}
/**
* 注册app.
*
* @param app 注册app.
*/
public static void register(App<?> app) {
if (app != null) {
ALL_APP.add(app);
}
}
public static void remove(App<?> app) {
if (app != null) {
ALL_APP.remove(app);
}
}
}

106
designer-base/src/main/java/com/fr/file/StashedFILE.java

@ -0,0 +1,106 @@
package com.fr.file;
import javax.swing.Icon;
import javax.transaction.NotSupportedException;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.OutputStream;
/**
* 切换环境用于暂存的文件类型
*/
public class StashedFILE implements FILE {
private FILE file;
private byte[] content;
public StashedFILE(FILE file, byte[] content) {
this.file = file;
this.content = content;
}
@Override
public String prefix() {
return file.prefix();
}
@Override
public boolean isDirectory() {
return file.isDirectory();
}
@Override
public String getName() {
return file.getName();
}
@Override
public Icon getIcon() {
return file.getIcon();
}
@Override
public String getPath() {
return file.getPath();
}
@Override
public void setPath(String path) {
throw new UnsupportedOperationException();
}
@Override
public FILE getParent() {
throw new UnsupportedOperationException();
}
@Override
public FILE[] listFiles() {
throw new UnsupportedOperationException();
}
@Override
public boolean createFolder(String name) {
throw new UnsupportedOperationException();
}
@Override
public boolean mkfile() throws Exception {
throw new UnsupportedOperationException();
}
@Override
public boolean exists() {
return false;
}
@Override
public void closeTemplate() throws Exception {
// do nothing
}
@Override
public InputStream asInputStream() throws Exception {
return new ByteArrayInputStream(content);
}
@Override
public OutputStream asOutputStream() throws Exception {
throw new NotSupportedException();
}
@Override
public String getEnvFullName() {
return file.getEnvFullName();
}
@Override
public boolean isMemFile() {
return true;
}
@Override
public boolean isEnvFile() {
return false;
}
}

6
designer-realize/src/main/java/com/fr/design/mainframe/app/DesignerAppActivator.java

@ -1,7 +1,7 @@
package com.fr.design.mainframe.app; package com.fr.design.mainframe.app;
import com.fr.design.mainframe.App; import com.fr.design.mainframe.App;
import com.fr.design.mainframe.DesignerFrame; import com.fr.design.mainframe.JTemplateFactory;
import com.fr.module.Activator; import com.fr.module.Activator;
import com.fr.module.extension.Prepare; import com.fr.module.extension.Prepare;
@ -17,7 +17,7 @@ public class DesignerAppActivator extends Activator implements Prepare {
List<App> appList = rightCollectMutable(App.KEY); List<App> appList = rightCollectMutable(App.KEY);
for (App app : appList) { for (App app : appList) {
DesignerFrame.registApp(app); JTemplateFactory.register(app);
} }
} }
@ -26,7 +26,7 @@ public class DesignerAppActivator extends Activator implements Prepare {
List<App> appList = rightCollectMutable(App.KEY); List<App> appList = rightCollectMutable(App.KEY);
for (App app : appList) { for (App app : appList) {
DesignerFrame.removeApp(app); JTemplateFactory.remove(app);
} }
} }

15
designer-realize/src/main/java/com/fr/start/module/DesignerStartup.java

@ -82,17 +82,16 @@ public class DesignerStartup extends Activator {
*/ */
private void registerEnvListener() { private void registerEnvListener() {
/*切换环境前,关闭所有相关模块,最后执行*/
/*切换环境前,关闭所有相关模块*/ listenEvent(WorkspaceEvent.BeforeSwitch, new Listener<Workspace>(WorkspaceEventPriority.MIN) {
listenEvent(WorkspaceEvent.BeforeSwitch, new Listener<Workspace>() {
@Override @Override
public void on(Event event, Workspace current) { public void on(Event event, Workspace current) {
getSub(EnvBasedModule.class).stop(); getSub(EnvBasedModule.class).stop();
} }
}); });
/*切换环境后,重新启动所有相关模块*/ /*切换环境后,重新启动所有相关模块,最先执行*/
listenEvent(WorkspaceEvent.AfterSwitch, new Listener<Workspace>(Integer.MAX_VALUE) { listenEvent(WorkspaceEvent.AfterSwitch, new Listener<Workspace>(WorkspaceEventPriority.MAX) {
@Override @Override
public void on(Event event, Workspace current) { public void on(Event event, Workspace current) {
@ -110,8 +109,8 @@ public class DesignerStartup extends Activator {
} }
} }
}); });
/*切换环境前,存储一下打开的所有文件对象,优先级高于默认优先级,要先于 关闭相关模块部分 被触发*/ /*切换环境前,存储一下打开的所有文件对象,要先于 关闭相关模块部分 被触发*/
listenEvent(WorkspaceEvent.BeforeSwitch, new Listener<Workspace>(Integer.MAX_VALUE) { listenEvent(WorkspaceEvent.BeforeSwitch, new Listener<Workspace>(WorkspaceEventPriority.MAX) {
@Override @Override
public void on(Event event, Workspace workspace) { public void on(Event event, Workspace workspace) {
HistoryTemplateListCache.getInstance().stash(); HistoryTemplateListCache.getInstance().stash();
@ -119,7 +118,7 @@ public class DesignerStartup extends Activator {
}); });
/*切换环境后,装载一下打开的所有文件对象,优先级低于默认优先级,要后于 启动相关模块部分 被触发*/ /*切换环境后,装载一下打开的所有文件对象,优先级低于默认优先级,要后于 启动相关模块部分 被触发*/
listenEvent(WorkspaceEvent.AfterSwitch, new Listener<Workspace>(Integer.MIN_VALUE) { listenEvent(WorkspaceEvent.AfterSwitch, new Listener<Workspace>(WorkspaceEventPriority.MIN) {
@Override @Override
public void on(Event event, Workspace workspace) { public void on(Event event, Workspace workspace) {
HistoryTemplateListCache.getInstance().load(); HistoryTemplateListCache.getInstance().load();

16
designer-realize/src/main/java/com/fr/start/module/WorkspaceEventPriority.java

@ -0,0 +1,16 @@
package com.fr.start.module;
/**
* 切换环境事件优先级暂时方案
* todo 看是不是需要使用另外的类型处理优先级
*/
public final class WorkspaceEventPriority {
private WorkspaceEventPriority() {
}
public static final int MAX = 999;
public static final int MID = 0;
public static final int MIN = -999;
}
Loading…
Cancel
Save