diff --git a/designer-base/src/main/java/com/fr/design/DesignerEnvManager.java b/designer-base/src/main/java/com/fr/design/DesignerEnvManager.java index b57ad6c7a..3f37d8751 100644 --- a/designer-base/src/main/java/com/fr/design/DesignerEnvManager.java +++ b/designer-base/src/main/java/com/fr/design/DesignerEnvManager.java @@ -214,6 +214,8 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter { private boolean useOptimizedUPM4Adapter; + private boolean propertiesUsable; + /** * DesignerEnvManager. */ @@ -676,6 +678,15 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter { this.useOptimizedUPM4Adapter = useOptimizedUPM4Adapter; } + public boolean isPropertiesUsable() { + // todo + return false; + } + + public void setPropertiesUsable(boolean propertiesUsable) { + this.propertiesUsable = propertiesUsable; + } + /** * 知否自动备份 * 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 2534de526..8f732a02e 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 @@ -4,6 +4,7 @@ package com.fr.design.mainframe; import com.fr.base.BaseUtils; +import com.fr.base.OptimizeUtil; import com.fr.design.DesignModelAdapter; import com.fr.design.DesignerEnvManager; import com.fr.design.ExtraDesignClassManager; @@ -42,6 +43,7 @@ import com.fr.design.lock.LockInfoDialog; import com.fr.event.EventDispatcher; import com.fr.exception.DecryptTemplateException; import com.fr.exception.TplLockedException; +import com.fr.exit.ConfigToPropMigrator; import com.fr.exit.DesignerExiter; import com.fr.file.FILE; import com.fr.file.FILEFactory; @@ -1071,6 +1073,10 @@ public class DesignerFrame extends JFrame implements JTemplateActionListener, Ta DesignerEnvManager.getEnvManager().setLastEastRegionContainerWidth( EastRegionContainerPane.getInstance().getContainerWidth()); + OptimizeUtil.open(() -> { + ConfigToPropMigrator.getInstance().execute(); + }); + DesignerEnvManager.getEnvManager().saveXMLFile(); } diff --git a/designer-base/src/main/java/com/fr/env/utils/WorkspaceUtils.java b/designer-base/src/main/java/com/fr/env/utils/WorkspaceUtils.java new file mode 100644 index 000000000..3979b4eee --- /dev/null +++ b/designer-base/src/main/java/com/fr/env/utils/WorkspaceUtils.java @@ -0,0 +1,27 @@ +package com.fr.env.utils; + +import com.fr.design.DesignerEnvManager; +import com.fr.design.env.DesignerWorkspaceInfo; +import com.fr.design.env.LocalDesignerWorkspaceInfo; +import com.fr.stable.StringUtils; + +/** + * @author hades + * @version 11.0 + * Created by hades on 2022/3/10 + */ +public class WorkspaceUtils { + + private static final String SPECIFY_WORKSPACE = "fr.designer.workspace"; + + public static DesignerWorkspaceInfo getWorkspaceInfo() { + String workspacePath; + String current = DesignerEnvManager.getEnvManager().getCurEnvName(); + if (StringUtils.isNotEmpty(workspacePath = System.getProperty(SPECIFY_WORKSPACE))) { + return LocalDesignerWorkspaceInfo.create(StringUtils.EMPTY, workspacePath); + } else { + return DesignerEnvManager.getEnvManager().getWorkspaceInfo(current); + } + } + +} diff --git a/designer-base/src/main/java/com/fr/exit/ConfigToPropMigrator.java b/designer-base/src/main/java/com/fr/exit/ConfigToPropMigrator.java new file mode 100644 index 000000000..909768bee --- /dev/null +++ b/designer-base/src/main/java/com/fr/exit/ConfigToPropMigrator.java @@ -0,0 +1,111 @@ +package com.fr.exit; + +import com.fr.config.dao.PropertiesConstants; +import com.fr.design.DesignerEnvManager; +import com.fr.log.FineLoggerFactory; +import com.fr.stable.CommonUtils; +import com.fr.stable.StableUtils; +import com.fr.stable.project.ProjectConstants; +import com.fr.workspace.WorkContext; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.sql.Blob; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Properties; + +/** + * 设计器关闭前的配置缓存一份到Properties + * + * @author hades + * @version 11.0 + * Created by hades on 2022/3/1 + */ +public class ConfigToPropMigrator { + + private static final String SELECT_FOR_ENTITY = "select id, value from fine_conf_entity"; + + private static final String SELECT_FOR_CLASSNAME = "select id, classname from fine_conf_classname"; + + private static final String SELECT_FOR_XML_ENTITY = "select id, value from fine_conf_xmlentity"; + + private static final ConfigToPropMigrator INSTANCE = new ConfigToPropMigrator(); + + public static ConfigToPropMigrator getInstance() { + return INSTANCE; + } + + public void execute() { + + if (WorkContext.getCurrent().isLocal()) { + + String url = "jdbc:hsqldb:file://" + WorkContext.getCurrent().getPath() + "/" + ProjectConstants.EMBED_DB_DIRECTORY + "/finedb/db;hsqldb.tx=mvcc"; + + try { + Class.forName("com.fr.third.org.hsqldb.jdbcDriver"); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + return ; + } + + initDirectory(); + + try (Connection c = DriverManager.getConnection(url); + FileOutputStream entityOut = new FileOutputStream(PropertiesConstants.ENTITY_PROP_PATH); + FileOutputStream classHelperOut = new FileOutputStream(PropertiesConstants.CLASS_NAME_PROP_PATH); + FileOutputStream xmlEntityOut = new FileOutputStream(PropertiesConstants.XML_ENTITY_PROP_PATH)) { + + processClassOrEntity(c, new Properties(), SELECT_FOR_ENTITY, entityOut); + processClassOrEntity(c, new Properties(), SELECT_FOR_CLASSNAME, classHelperOut); + processXmlEntity(c, new Properties(), xmlEntityOut); + DesignerEnvManager.getEnvManager().setPropertiesUsable(true); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + deletePropertiesCache(); + } + } + } + + private void initDirectory() { + File directory = new File(StableUtils.pathJoin(WorkContext.getCurrent().getPath(), ProjectConstants.EMBED_DB_DIRECTORY, ProjectConstants.PROPERTIES_CACHE_FOR_CONFIG)); + if (!directory.exists()) { + directory.mkdir(); + } + } + + private void processClassOrEntity(Connection c, Properties map, String sql, FileOutputStream outputStream) throws SQLException, IOException { + PreparedStatement query = c.prepareStatement(sql); + ResultSet resultSet = query.executeQuery(); + while (resultSet.next()) { + String id = resultSet.getString(1); + String value = resultSet.getString(2); + if (id != null && value != null) { + map.setProperty(id, value); + } + } + map.store(outputStream, null); + } + + private void processXmlEntity(Connection c, Properties map, FileOutputStream outputStream) throws SQLException, IOException { + PreparedStatement query = c.prepareStatement(SELECT_FOR_XML_ENTITY); + ResultSet resultSet = query.executeQuery(); + while (resultSet.next()) { + String id = resultSet.getString(1); + Blob value = resultSet.getBlob(2); + byte[] bytes = value.getBytes(1L, (int) value.length()); + map.setProperty(id, new String(bytes)); + } + map.store(outputStream, null); + } + + public void deletePropertiesCache() { + CommonUtils.deleteFile(new File(PropertiesConstants.ENTITY_PROP_PATH)); + CommonUtils.deleteFile(new File(PropertiesConstants.XML_ENTITY_PROP_PATH)); + CommonUtils.deleteFile(new File(PropertiesConstants.CLASS_NAME_PROP_PATH)); + } + +} diff --git a/designer-base/src/main/java/com/fr/start/BaseDesigner.java b/designer-base/src/main/java/com/fr/start/BaseDesigner.java index 6165ff7f7..2633cedd4 100644 --- a/designer-base/src/main/java/com/fr/start/BaseDesigner.java +++ b/designer-base/src/main/java/com/fr/start/BaseDesigner.java @@ -32,6 +32,7 @@ import com.fr.process.engine.core.CarryMessageEvent; import com.fr.process.engine.core.FineProcessContext; import com.fr.stable.OperatingSystem; +import com.fr.start.event.LazyStartupEvent; import com.fr.workspace.base.WorkspaceStatus; import java.awt.Window; import java.io.File; @@ -86,6 +87,7 @@ public abstract class BaseDesigner extends ToolBarMenuDock { eventPipe.fire(new CarryMessageEvent(ReportState.STOP.getValue())); } EventDispatcher.fire(WorkspaceStatus.Prepared); + EventDispatcher.asyncFire(LazyStartupEvent.INSTANCE); collectUserInformation(); } }); diff --git a/designer-base/src/main/java/com/fr/start/event/LazyStartupEvent.java b/designer-base/src/main/java/com/fr/start/event/LazyStartupEvent.java new file mode 100644 index 000000000..fcef2ffc1 --- /dev/null +++ b/designer-base/src/main/java/com/fr/start/event/LazyStartupEvent.java @@ -0,0 +1,14 @@ +package com.fr.start.event; + +import com.fr.event.Event; +import com.fr.event.Null; + +/** + * @author hades + * @version 11.0 + * Created by hades on 2022/3/7 + */ +public enum LazyStartupEvent implements Event { + + INSTANCE +} 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 56af5583f..30d2f56cc 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,10 +1,16 @@ package com.fr.start.module; +import com.fr.base.OptimizeUtil; import com.fr.concurrent.NamedThreadFactory; +import com.fr.config.dao.DaoSelector; +import com.fr.config.dao.DaoSelectorFactory; +import com.fr.decision.webservice.v10.encryption.EncryptionConstants; import com.fr.design.DesignerEnvManager; import com.fr.design.RestartHelper; import com.fr.design.dialog.TipDialog; +import com.fr.design.env.DesignerWorkspaceInfo; +import com.fr.design.env.DesignerWorkspaceType; import com.fr.design.fun.OemProcessor; import com.fr.design.fun.impl.GlobalListenerProviderManager; import com.fr.design.i18n.Toolkit; @@ -14,10 +20,15 @@ import com.fr.design.mainframe.messagecollect.entity.DesignerErrorMessage; import com.fr.design.ui.util.UIUtil; import com.fr.design.utils.DesignUtils; import com.fr.design.utils.DesignerPort; +import com.fr.env.utils.WorkspaceUtils; +import com.fr.event.Event; +import com.fr.event.Listener; +import com.fr.event.Null; import com.fr.exit.DesignerExiter; import com.fr.general.ComparatorUtils; import com.fr.log.FineLoggerFactory; import com.fr.module.Activator; +import com.fr.module.extension.Prepare; import com.fr.record.analyzer.EnableMetrics; import com.fr.record.analyzer.Metrics; import com.fr.stable.ArrayUtils; @@ -25,12 +36,14 @@ import com.fr.stable.BuildContext; import com.fr.stable.ProductConstants; import com.fr.stable.StableUtils; import com.fr.stable.StringUtils; +import com.fr.stable.project.ProjectConstants; import com.fr.start.DesignerProcessType; import com.fr.start.OemHandler; import com.fr.start.ServerStarter; import com.fr.start.SplashContext; import com.fr.start.SplashStrategy; import com.fr.start.common.SplashCommon; +import com.fr.start.event.LazyStartupEvent; import com.fr.start.server.FineEmbedServer; import com.fr.value.NotNullLazyValue; import org.jetbrains.annotations.NotNull; @@ -59,6 +72,9 @@ public class DesignerStartup extends Activator { checkDebugStart(); // 都是在启动过程中读取,这边提前初始化xml配置 DesignerEnvManager.getEnvManager(); + + registerDaoSelector(); + // 初始化look and feel DesignUtils.initLookAndFeel(); if (DesignUtils.isPortOccupied()) { @@ -125,13 +141,21 @@ public class DesignerStartup extends Activator { || FineEmbedServer.isRunning()) { return; } + if (DaoSelectorFactory.getDaoSelector().useCacheDao()) { + listenEvent(LazyStartupEvent.INSTANCE, new Listener(Integer.MIN_VALUE) { + @Override + public void on(Event event, Null param) { + startEmbeddedServer(); + } + }); + } else { + startEmbeddedServer(); + } + } + + private void startEmbeddedServer() { ExecutorService service = newSingleThreadExecutor(new NamedThreadFactory("FineEmbedServerStart")); - service.submit(new Runnable() { - @Override - public void run() { - FineEmbedServer.start(); - } - }); + service.submit(FineEmbedServer::start); service.shutdown(); } @@ -176,6 +200,21 @@ public class DesignerStartup extends Activator { } } + private void registerDaoSelector() { + // 注入设计器db cache 是否可用 + DesignerWorkspaceInfo info = WorkspaceUtils.getWorkspaceInfo(); + if (info.getType() == DesignerWorkspaceType.Remote) { + DaoSelectorFactory.registerDaoSelector(() -> false); + } else { + String dbConfigPath = StableUtils.pathJoin(WorkspaceUtils.getWorkspaceInfo().getPath(), ProjectConstants.CONFIG_DIRECTORY, + EncryptionConstants.PROPERTY_NAME); + // + DaoSelectorFactory.registerDaoSelector(() -> DesignerEnvManager.getEnvManager().isPropertiesUsable() + && OptimizeUtil.isOpen() + && !new File(dbConfigPath).exists()); + } + } + /** * 端口改一下,环境配置文件改一下。便于启动两个设计器,进行对比调试 */ diff --git a/designer-realize/src/main/java/com/fr/start/module/DesignerWorkspaceProvider.java b/designer-realize/src/main/java/com/fr/start/module/DesignerWorkspaceProvider.java index 724f947c9..de57164bc 100644 --- a/designer-realize/src/main/java/com/fr/start/module/DesignerWorkspaceProvider.java +++ b/designer-realize/src/main/java/com/fr/start/module/DesignerWorkspaceProvider.java @@ -9,6 +9,7 @@ import com.fr.design.env.DesignerWorkspaceGenerator; import com.fr.design.env.DesignerWorkspaceInfo; import com.fr.design.env.LocalDesignerWorkspaceInfo; import com.fr.design.versioncheck.VersionCheckUtils; +import com.fr.env.utils.WorkspaceUtils; import com.fr.event.Event; import com.fr.event.EventDispatcher; import com.fr.event.Listener; @@ -28,7 +29,6 @@ import org.jetbrains.annotations.NotNull; */ public class DesignerWorkspaceProvider extends Activator { - private static final String SPECIFY_WORKSPACE = "fr.designer.workspace"; private NotNullLazyValue startupArgs = new NotNullLazyValue() { @NotNull @@ -46,15 +46,10 @@ public class DesignerWorkspaceProvider extends Activator { if (startupArgs.getValue().isDemo()) { DesignerEnvManager.getEnvManager().setCurrentEnv2Default(); } else { - String workspacePath; DesignerWorkspaceInfo workspaceInfo = null; try { String current = DesignerEnvManager.getEnvManager().getCurEnvName(); - if (StringUtils.isNotEmpty(workspacePath = System.getProperty(SPECIFY_WORKSPACE))) { - workspaceInfo = LocalDesignerWorkspaceInfo.create(StringUtils.EMPTY, workspacePath); - } else { - workspaceInfo = DesignerEnvManager.getEnvManager().getWorkspaceInfo(current); - } + workspaceInfo = WorkspaceUtils.getWorkspaceInfo(); Workspace workspace = DesignerWorkspaceGenerator.generate(workspaceInfo); boolean checkValid = workspace != null && workspaceInfo.checkValid(); if (!checkValid) { diff --git a/designer-realize/src/main/java/com/fr/start/module/optimized/BaseDBActivator4Designer.java b/designer-realize/src/main/java/com/fr/start/module/optimized/BaseDBActivator4Designer.java new file mode 100644 index 000000000..4c5492651 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/start/module/optimized/BaseDBActivator4Designer.java @@ -0,0 +1,30 @@ +package com.fr.start.module.optimized; + +import com.fr.config.activator.BaseDBActivator; +import com.fr.config.dao.DaoSelectorFactory; +import com.fr.event.Event; +import com.fr.event.Listener; +import com.fr.event.Null; +import com.fr.start.event.LazyStartupEvent; + +/** + * @author hades + * @version 11.0 + * Created by hades on 2022/3/7 + */ +public class BaseDBActivator4Designer extends BaseDBActivator { + + @Override + public void start() { + if (DaoSelectorFactory.getDaoSelector().useCacheDao()) { + listenEvent(LazyStartupEvent.INSTANCE, new Listener(Integer.MAX_VALUE) { + @Override + public void on(Event event, Null param) { + BaseDBActivator4Designer.super.start(); + } + }); + } else { + super.start(); + } + } +} diff --git a/designer-realize/src/main/java/com/fr/start/module/optimized/ConfigurationActivator4Designer.java b/designer-realize/src/main/java/com/fr/start/module/optimized/ConfigurationActivator4Designer.java new file mode 100644 index 000000000..35863aa48 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/start/module/optimized/ConfigurationActivator4Designer.java @@ -0,0 +1,27 @@ +package com.fr.start.module.optimized; + +import com.fr.config.activator.ConfigurationActivator; +import com.fr.config.dao.DaoContext; +import com.fr.config.dao.DaoSelectorFactory; +import com.fr.config.dao.impl.PropertiesClassHelperDao; +import com.fr.config.dao.impl.PropertiesEntityDao; +import com.fr.config.dao.impl.PropertiesXmlEntityDao; + +/** + * @author hades + * @version 11.0 + * Created by hades on 2022/3/7 + */ +public class ConfigurationActivator4Designer extends ConfigurationActivator { + + @Override + protected void initLocalDao() { + if (DaoSelectorFactory.getDaoSelector().useCacheDao()) { + DaoContext.setClassHelperDao(new PropertiesClassHelperDao()); + DaoContext.setEntityDao(new PropertiesEntityDao()); + DaoContext.setXmlEntityDao(new PropertiesXmlEntityDao()); + } else { + super.initLocalDao(); + } + } +} diff --git a/designer-realize/src/main/java/com/fr/start/module/optimized/TenantDBAdapter4Designer.java b/designer-realize/src/main/java/com/fr/start/module/optimized/TenantDBAdapter4Designer.java new file mode 100644 index 000000000..25e609ded --- /dev/null +++ b/designer-realize/src/main/java/com/fr/start/module/optimized/TenantDBAdapter4Designer.java @@ -0,0 +1,42 @@ +package com.fr.start.module.optimized; + +import com.fr.config.dao.DaoSelectorFactory; +import com.fr.config.dao.swicter.DaoSwitcher; +import com.fr.design.DesignerEnvManager; +import com.fr.event.Event; +import com.fr.event.Listener; +import com.fr.event.Null; +import com.fr.exit.ConfigToPropMigrator; +import com.fr.stable.db.tenant.TenantDBAdapter; +import com.fr.start.event.LazyStartupEvent; + +/** + * @author hades + * @version 11.0 + * Created by hades on 2022/3/7 + */ +public class TenantDBAdapter4Designer extends TenantDBAdapter { + + @Override + public void start() { + if (DaoSelectorFactory.getDaoSelector().useCacheDao()) { + listenEvent(LazyStartupEvent.INSTANCE, new Listener() { + @Override + public void on(Event event, Null param) { + TenantDBAdapter4Designer.super.start(); + afterStart(); + } + }); + + } else { + super.start(); + } + } + + private void afterStart() { + DaoSwitcher.executeSwitch(); + ConfigToPropMigrator.getInstance().deletePropertiesCache(); + DesignerEnvManager.getEnvManager().setPropertiesUsable(false); + DesignerEnvManager.getEnvManager().saveXMLFile(); + } +}