package com.fr.start.module; import com.fanruan.product.BuildContext; import com.fr.base.OptimizeUtil; import com.fr.concurrent.NamedThreadFactory; import com.fr.config.dao.DaoSelectorFactory; import com.fr.config.dao.PropertiesConstants; 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.impl.GlobalListenerProviderManager; import com.fr.design.i18n.Toolkit; import com.fr.design.mainframe.messagecollect.StartErrorMessageCollector; import com.fr.design.mainframe.messagecollect.StartupMessageCollector; import com.fr.design.mainframe.messagecollect.entity.DesignerErrorMessage; import com.fr.design.utils.DesignUtils; 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.log.FineLoggerFactory; import com.fr.module.Activator; import com.fr.record.analyzer.EnableMetrics; import com.fr.record.analyzer.Metrics; import com.fr.stable.ArrayUtils; 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.ServerStarter; import com.fr.start.common.DesignerStartupContext; import com.fr.start.event.LazyStartupEvent; import com.fr.start.preload.PreLoadService; import com.fr.start.server.FineEmbedServer; import com.fr.third.guava.base.Stopwatch; import com.fr.value.NotNullLazyValue; import org.jetbrains.annotations.NotNull; import java.io.File; import java.util.concurrent.ExecutorService; import java.util.concurrent.TimeUnit; /** * Created by juhaoyu on 2018/1/8. */ @EnableMetrics public class DesignerStartup extends Activator { private NotNullLazyValue startupArgsValue = new NotNullLazyValue() { @NotNull @Override protected StartupArgs compute() { return findSingleton(StartupArgs.class); } }; @Override public void beforeAllStart() { BuildContext.setBuildFilePath("/com/fr/stable/build.properties"); registerDaoSelector(); Stopwatch beforeWatch = Stopwatch.createStarted(); PreLoadService.getInstance().waitForCommon(); FineLoggerFactory.getLogger().debug( "DesignerStartup cost {} ms to wait load", beforeWatch.elapsed(TimeUnit.MILLISECONDS)); if (DesignUtils.isStarted()) { // 如果端口被占用了 说明程序已经运行了一次,也就是说,已经建立一个监听服务器,现在只要给服务器发送命令就好了 final String[] args = startupArgsValue.getValue().get(); if (ArrayUtils.isNotEmpty(args)) { DesignUtils.clientSend(args); } FineLoggerFactory.getLogger().info("The Designer Has Been Started"); if (args.length == 0) { TipDialog dialog = new TipDialog(null, DesignerProcessType.INSTANCE.obtain(), Toolkit.i18nText("Fine-Design_Last_Designer_Process_Not_Exist"), Toolkit.i18nText("Fine-Design_End_Occupied_Process"), Toolkit.i18nText("Fine-Design_Basic_Cancel")) { @Override protected void endEvent() { dispose(); DesignUtils.clientSend(new String[]{"end"}); RestartHelper.restart(); } @Override protected void cancelEvent() { dispose(); } }; dialog.setVisible(true); StartErrorMessageCollector.getInstance().record(DesignerErrorMessage.DESIGNER_PROCESS_OCCUPIED.getId(), DesignerErrorMessage.DESIGNER_PROCESS_OCCUPIED.getMessage(), StringUtils.EMPTY); FineLoggerFactory.getLogger().error(DesignerErrorMessage.DESIGNER_PROCESS_OCCUPIED.getId() + ": " + DesignerErrorMessage.DESIGNER_PROCESS_OCCUPIED.getMessage()); } DesignerExiter.getInstance().execute(); } } @Override @Metrics public void start() { startSub(PreStartActivator.class); startSub("parallel"); //designer模块启动好后,查看demo browserDemoIfNeeded(); startupEmbedServerIfNeeded(); } private void startupEmbedServerIfNeeded() { if (DesignerEnvManager.getEnvManager().isEmbedServerLazyStartup() || FineEmbedServer.isRunning()) { return; } if (DaoSelectorFactory.getDaoSelector().useCacheDao() || DesignerStartupContext.getInstance().isOnStartup()) { listenEvent(LazyStartupEvent.INSTANCE, new Listener(Integer.MIN_VALUE) { @Override public void on(Event event, Null param) { // 有可能被插件之类的 强制启动了 判断下 if (FineEmbedServer.isRunning() || FineEmbedServer.isOnStarting()) { return; } startEmbeddedServer(); } }); } else { startEmbeddedServer(); } } private void startEmbeddedServer() { ExecutorService service = newSingleThreadExecutor(new NamedThreadFactory("FineEmbedServerStart")); service.submit(FineEmbedServer::start); service.shutdown(); } @Override public void afterAllStart() { GlobalListenerProviderManager.getInstance().init(); // 启动日志收集 StartupMessageCollector.getInstance().recordStartupLog(); } private void browserDemoIfNeeded() { if (startupArgsValue.getValue().isDemo()) { ServerStarter.browserDemoURL(); } } private void registerDaoSelector() { // 注入设计器db cache 是否可用 DesignerWorkspaceInfo info = WorkspaceUtils.getWorkspaceInfo(); if (info.getType() == DesignerWorkspaceType.Remote) { DaoSelectorFactory.registerDaoSelector(() -> false); } else { String webInfPath = WorkspaceUtils.getWorkspaceInfo().getPath(); String dbConfigPath = StableUtils.pathJoin(webInfPath, ProjectConstants.CONFIG_DIRECTORY, EncryptionConstants.PROPERTY_NAME); String entityPath = generatePath(webInfPath, PropertiesConstants.ENTITY_PROP); String xmlEntityPath = generatePath(webInfPath, PropertiesConstants.XML_ENTITY_PROP); String classNamePath = generatePath(webInfPath, PropertiesConstants.CLASS_NAME_PROP); // 校验 平台迁移文件/缓存文件 boolean existPropCache = new File(entityPath).exists() && new File(xmlEntityPath).exists() && new File(classNamePath).exists(); DaoSelectorFactory.registerDaoSelector(() -> DesignerEnvManager.getEnvManager().isPropertiesUsable() && OptimizeUtil.isOpen() && existPropCache // demo启动时 前后目录可能会不一致 造成读取缓存失败 && !startupArgsValue.getValue().isDemo() && !new File(dbConfigPath).exists()); } } private String generatePath(String webInfPath, String name) { return StableUtils.pathJoin(webInfPath, ProjectConstants.EMBED_DB_DIRECTORY, ProjectConstants.PROPERTIES_CACHE_FOR_CONFIG, name); } @Override public void stop() { // void } }