Browse Source

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

final/10.0
yaoh.wu 6 years ago
parent
commit
4db0d2b996
  1. 2
      designer-base/src/main/java/com/fr/design/DesignModelAdapter.java
  2. 78
      designer-base/src/main/java/com/fr/design/file/HistoryTemplateListCache.java
  3. 10
      designer-base/src/main/java/com/fr/design/mainframe/AbstractAppProvider.java
  4. 68
      designer-base/src/main/java/com/fr/design/mainframe/DesignerFrame.java
  5. 63
      designer-base/src/main/java/com/fr/design/mainframe/JTemplateFactory.java
  6. 106
      designer-base/src/main/java/com/fr/file/StashedFILE.java
  7. 6
      designer-realize/src/main/java/com/fr/design/mainframe/app/DesignerAppActivator.java
  8. 61
      designer-realize/src/main/java/com/fr/start/module/DesignerStartup.java

2
designer-base/src/main/java/com/fr/design/DesignModelAdapter.java

@ -134,7 +134,7 @@ public abstract class DesignModelAdapter<T extends BaseBook, S extends JTemplate
*/
@Deprecated
public Parameter[] getReportParameters() {
return getTableDataParameters();
return getTemplateParameters();
}
/**

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

@ -1,6 +1,7 @@
package com.fr.design.file;
import com.fr.base.chart.chartdata.CallbackEvent;
import com.fr.base.io.BaseBook;
import com.fr.design.DesignerEnvManager;
import com.fr.design.base.mode.DesignModeContext;
import com.fr.design.data.DesignTableDataManager;
@ -8,20 +9,25 @@ import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.DesignerFrameFileDealerPane;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.mainframe.JTemplateFactory;
import com.fr.design.mainframe.JVirtualTemplate;
import com.fr.design.module.DesignModuleFactory;
import com.fr.file.FILE;
import com.fr.file.FileNodeFILE;
import com.fr.file.StashedFILE;
import com.fr.general.ComparatorUtils;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.CoreConstants;
import com.fr.stable.StringUtils;
import com.fr.third.org.apache.commons.io.FilenameUtils;
import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
/**
* 历史模板缓存
@ -305,4 +311,76 @@ public class HistoryTemplateListCache implements CallbackEvent {
}
return true;
}
/**
* 切换环境时暂存打开的模板内容key 是在历史中的indexvalue 是模板xml 内容byte[]
*/
private Map<Integer, FILE> stashFILEMap;
/**
* 切换环境前将正在编辑的模板暂存起来并且在新环境中重新读取一遍暂存的不是模板文件的内容而是模板对象的内容
* <p>
* 防止新环境加载到的同名 Class 和模板对象中的 Class 不一致在新环境存储失败
*
* @see HistoryTemplateListCache#load()
*/
public void stash() {
FineLoggerFactory.getLogger().info("Env Change Template Stashing...");
if (stashFILEMap == null) {
stashFILEMap = new HashMap<Integer, FILE>();
} else {
stashFILEMap.clear();
}
int size = historyList.size();
for (int i = 0; i < size; i++) {
JTemplate<?, ?> template = historyList.get(i);
FILE file = template.getEditingFILE();
try {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
BaseBook target = template.getTarget();
if (target != null) {
target.export(outputStream);
stashFILEMap.put(i, new StashedFILE(file, outputStream.toByteArray()));
}
// 如果 target == null 那么这个模板是被模板内存优化功能处理过的,不用处理
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
FineLoggerFactory.getLogger().info("Env Change Template Stashed.");
}
/**
* 切换环境前将正在编辑的模板暂存起来后在新环境重新读取一遍
* <p>
* 防止新环境加载到的同名 Class 和模板对象中的 Class 不一致在新环境存储失败
*
* @see HistoryTemplateListCache#stash()
*/
public void load() {
FineLoggerFactory.getLogger().info("Env Change Template Loading...");
if (stashFILEMap != null && stashFILEMap.size() != 0) {
int size = historyList.size();
for (int i = 0; i < size; i++) {
try {
FILE stashedFile = stashFILEMap.get(i);
// 可能有模板 stash 失败的情况,在 load 的时候不更新它
// 或者这个模板是被模板内存优化功能处理过的,不用处理
if (stashedFile == null) {
continue;
}
JTemplate<?, ?> template = JTemplateFactory.createJTemplate(stashedFile);
if (template != null) {
historyList.set(i, template);
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
stashFILEMap.clear();
MutilTempalteTabPane.getInstance().refreshOpenedTemplate(historyList);
MutilTempalteTabPane.getInstance().repaint();
}
FineLoggerFactory.getLogger().info("Env Change Template Loaded.");
}
}

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.
*/
@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() {
return CURRENT_LEVEL;
@ -21,12 +21,12 @@ public abstract class AbstractAppProvider<T extends IOFile> extends AbstractProv
@Override
public void process() {
DesignerFrame.registApp(this);
JTemplateFactory.register(this);
}
@Override
public void undo() {
DesignerFrame.removeApp(this);
JTemplateFactory.remove(this);
}
}

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

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

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;
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.extension.Prepare;
@ -17,7 +17,7 @@ public class DesignerAppActivator extends Activator implements Prepare {
List<App> appList = rightCollectMutable(App.KEY);
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);
for (App app : appList) {
DesignerFrame.removeApp(app);
JTemplateFactory.remove(app);
}
}

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

@ -1,6 +1,7 @@
package com.fr.start.module;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.mainframe.DesignerContext;
import com.fr.event.Event;
import com.fr.event.Listener;
@ -28,13 +29,13 @@ public class DesignerStartup extends Activator {
@Override
@Metrics
public void start() {
startSub(PreStartActivator.class);
//启动基础部分
startSub(BasicActivator.class);
final String[] args = getModule().upFindSingleton(StartupArgs.class).get();
final Designer designer = new Designer(args);
startSub(DesignerWorkspaceProvider.class);
registerEnvListener();
//启动env
@ -49,7 +50,7 @@ public class DesignerStartup extends Activator {
}
});
service.submit(new Runnable() {
@Override
public void run() {
try {
@ -63,46 +64,64 @@ public class DesignerStartup extends Activator {
DesignerContext.getDesignerFrame().setVisible(true);
//启动画面结束
SplashContext.getInstance().hide();
DesignerContext.getDesignerFrame().getProgressDialog().setVisible(true);
startSub(StartFinishActivator.class);
FineRuntime.startFinish();
}
private void browserDemo() {
if (getModule().leftFindSingleton(StartupArgs.class) != null && getModule().leftFindSingleton(StartupArgs.class).isDemo()) {
ServerStarter.browserDemoURL();
}
}
/**
* 切换环境时重新启动所有相关模块
* 注册切换环境前后事件监听
*/
private void registerEnvListener() {
listenEvent(WorkspaceEvent.BeforeSwitch, new Listener<Workspace>() {
/*切换环境前,关闭所有相关模块,最后执行*/
listenEvent(WorkspaceEvent.BeforeSwitch, new Listener<Workspace>(Integer.MIN_VALUE) {
@Override
public void on(Event event, Workspace param) {
public void on(Event event, Workspace current) {
getSub(EnvBasedModule.class).stop();
}
});
/*切换环境后,重新启动所有相关模块,最先执行*/
listenEvent(WorkspaceEvent.AfterSwitch, new Listener<Workspace>(Integer.MAX_VALUE) {
@Override
public void on(Event event, Workspace param) {
public void on(Event event, Workspace current) {
getSub(EnvBasedModule.class).start();
ExecutorService service = Executors.newSingleThreadExecutor();
service.submit(new Runnable() {
@Override
public void run() {
FineEmbedServer.start();
}
});
service.shutdown();
// 切换后的环境是本地环境才启动内置服务器
if (current.isLocal()) {
ExecutorService service = Executors.newSingleThreadExecutor();
service.submit(new Runnable() {
@Override
public void run() {
FineEmbedServer.start();
}
});
service.shutdown();
}
}
});
/*切换环境前,存储一下打开的所有文件对象,要先于 关闭相关模块部分 被触发*/
listenEvent(WorkspaceEvent.BeforeSwitch, new Listener<Workspace>(Integer.MAX_VALUE) {
@Override
public void on(Event event, Workspace workspace) {
HistoryTemplateListCache.getInstance().stash();
}
});
/*切换环境后,装载一下打开的所有文件对象,优先级低于默认优先级,要后于 启动相关模块部分 被触发*/
listenEvent(WorkspaceEvent.AfterSwitch, new Listener<Workspace>(Integer.MIN_VALUE) {
@Override
public void on(Event event, Workspace workspace) {
HistoryTemplateListCache.getInstance().load();
}
});
}

Loading…
Cancel
Save