diff --git a/designer-base/src/main/java/com/fr/design/DesignModelAdapter.java b/designer-base/src/main/java/com/fr/design/DesignModelAdapter.java index 4ebc64103d..84fd684ae8 100644 --- a/designer-base/src/main/java/com/fr/design/DesignModelAdapter.java +++ b/designer-base/src/main/java/com/fr/design/DesignModelAdapter.java @@ -134,7 +134,7 @@ public abstract class DesignModelAdapter stashFILEMap; + + /** + * 切换环境前将正在编辑的模板暂存起来,并且在新环境中重新读取一遍,暂存的不是模板文件的内容而是模板对象的内容 + *

+ * 防止新环境加载到的同名 Class 和模板对象中的 Class 不一致,在新环境存储失败 + * + * @see HistoryTemplateListCache#load() + */ + public void stash() { + FineLoggerFactory.getLogger().info("Env Change Template Stashing..."); + if (stashFILEMap == null) { + stashFILEMap = new HashMap(); + } 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."); + } + + /** + * 切换环境前将正在编辑的模板暂存起来后,在新环境重新读取一遍 + *

+ * 防止新环境加载到的同名 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); + // 替换当前正在编辑的模板,使用添加并激活的方式,以便使用统一的入口来处理监听事件 + if (isCurrentEditingFile(template.getPath())) { + DesignerContext.getDesignerFrame().addAndActivateJTemplate(template); + setCurrentEditingTemplate(template); + FineLoggerFactory.getLogger().info("Env Change Current Editing 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."); + } } diff --git a/designer-base/src/main/java/com/fr/design/mainframe/AbstractAppProvider.java b/designer-base/src/main/java/com/fr/design/mainframe/AbstractAppProvider.java index 95a9696355..cc859ce178 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/AbstractAppProvider.java +++ b/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 extends AbstractProvider implements App{ +public abstract class AbstractAppProvider extends AbstractProvider implements App { public int currentAPILevel() { return CURRENT_LEVEL; @@ -21,12 +21,12 @@ public abstract class AbstractAppProvider extends AbstractProv @Override public void process() { - DesignerFrame.registApp(this); + JTemplateFactory.register(this); } - + @Override public void undo() { - - DesignerFrame.removeApp(this); + + JTemplateFactory.remove(this); } } diff --git a/designer-base/src/main/java/com/fr/design/mainframe/DesignerFrame.java b/designer-base/src/main/java/com/fr/design/mainframe/DesignerFrame.java index 7ab92165bb..e148a10407 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/DesignerFrame.java +++ b/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> appList = new java.util.ArrayList>(); + private static final Integer TOP_LAYER = 200; private List 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); } } diff --git a/designer-base/src/main/java/com/fr/design/mainframe/JTemplateFactory.java b/designer-base/src/main/java/com/fr/design/mainframe/JTemplateFactory.java new file mode 100644 index 0000000000..c6a6f4a0de --- /dev/null +++ b/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> ALL_APP = new ArrayList>(); + + 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); + } + } +} \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/file/StashedFILE.java b/designer-base/src/main/java/com/fr/file/StashedFILE.java new file mode 100644 index 0000000000..cacb1e9a90 --- /dev/null +++ b/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; + } +} \ No newline at end of file diff --git a/designer-form/src/main/java/com/fr/design/widget/ui/designer/mobile/ParaMobileDefinePane.java b/designer-form/src/main/java/com/fr/design/widget/ui/designer/mobile/ParaMobileDefinePane.java index 7e0f3b940a..b924b5c55a 100644 --- a/designer-form/src/main/java/com/fr/design/widget/ui/designer/mobile/ParaMobileDefinePane.java +++ b/designer-form/src/main/java/com/fr/design/widget/ui/designer/mobile/ParaMobileDefinePane.java @@ -21,7 +21,6 @@ import com.fr.form.ui.container.WParameterLayout; import com.fr.form.ui.container.WSortLayout; import com.fr.general.ComparatorUtils; import com.fr.general.SiteCenter; -import com.fr.json.JSONException; import com.fr.log.FineLoggerFactory; import com.fr.report.ExtraReportClassManager; import com.fr.report.fun.MobileParamStyleProvider; @@ -109,9 +108,9 @@ public class ParaMobileDefinePane extends MobileWidgetDefinePane { Item[] items = new Item[pluginCreators.size() + 1]; MobileParamStyleProvider provider = new DefaultMobileParamStyle(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Default")); items[0] = new Item(provider.descriptor(), provider); - for (int i = 0; i < pluginCreators.size(); i++) { - provider = pluginCreators.iterator().next(); - items[i + 1] = new Item(provider.descriptor(), provider); + int i = 1; + for (MobileParamStyleProvider mobileParamStyleProvider : pluginCreators) { + items[i++] = new Item(mobileParamStyleProvider.descriptor(), mobileParamStyleProvider); } return items; } @@ -161,6 +160,7 @@ public class ParaMobileDefinePane extends MobileWidgetDefinePane { private UIComboBox getParamLocationComboBox() { items = getItems(); + UIComboBox paramLocationComoBox = new UIComboBox(items); paramLocationComoBox.addItemListener(new ItemListener() { @Override @@ -218,7 +218,7 @@ public class ParaMobileDefinePane extends MobileWidgetDefinePane { break; } } - } catch (JSONException e) { + } catch (Exception e) { FineLoggerFactory.getLogger().error(e.getMessage(), e); } paramLocationComboBox.setSelectedIndex(index); diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/app/DesignerAppActivator.java b/designer-realize/src/main/java/com/fr/design/mainframe/app/DesignerAppActivator.java index f91b0d9a10..b13cdca853 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/app/DesignerAppActivator.java +++ b/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 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 appList = rightCollectMutable(App.KEY); for (App app : appList) { - DesignerFrame.removeApp(app); + JTemplateFactory.remove(app); } } diff --git a/designer-realize/src/main/java/com/fr/start/module/DesignerStartup.java b/designer-realize/src/main/java/com/fr/start/module/DesignerStartup.java index 701a6936c1..4a3db7b2cc 100644 --- a/designer-realize/src/main/java/com/fr/start/module/DesignerStartup.java +++ b/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() { + /*切换环境前,关闭所有相关模块,最后执行*/ + listenEvent(WorkspaceEvent.BeforeSwitch, new Listener(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(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(Integer.MAX_VALUE) { + @Override + public void on(Event event, Workspace workspace) { + HistoryTemplateListCache.getInstance().stash(); + } + }); + + /*切换环境后,装载一下打开的所有文件对象,优先级低于默认优先级,要后于 启动相关模块部分 被触发*/ + listenEvent(WorkspaceEvent.AfterSwitch, new Listener(Integer.MIN_VALUE) { + @Override + public void on(Event event, Workspace workspace) { + HistoryTemplateListCache.getInstance().load(); } }); }