Browse Source

Merge pull request #15487 in DESIGN/design from fbp/release to fbp/feature

* commit '81cb11d4dc67da11659e69367c5fdf21a929ac2e':
  REPORT-140121 FBP代码优化第三期-Activator的所有子类删除
fbp/feature
superman 1 week ago
parent
commit
949ee54a35
  1. 158
      designer-base/src/main/java/com/fr/design/record/analyzer/DesignerAnalyzerActivator.java
  2. 27
      designer-base/src/main/java/com/fr/env/EnvPrepare.java
  3. 156
      designer-base/src/main/java/com/fr/start/server/FineEmbedServerActivator.java
  4. 591
      designer-realize/src/main/java/com/fr/start/module/DesignerActivator.java
  5. 26
      designer-realize/src/main/java/com/fr/start/module/DesignerESDActivator.java
  6. 38
      designer-realize/src/main/java/com/fr/start/module/DesignerInitActivator.java
  7. 24
      designer-realize/src/main/java/com/fr/start/module/DesignerShowActivator.java
  8. 200
      designer-realize/src/main/java/com/fr/start/module/DesignerStartup.java
  9. 123
      designer-realize/src/main/java/com/fr/start/module/DesignerWorkspaceActivator.java
  10. 99
      designer-realize/src/main/java/com/fr/start/module/DesignerWorkspaceProvider.java
  11. 21
      designer-realize/src/main/java/com/fr/start/module/EnvBasedModule.java
  12. 59
      designer-realize/src/main/java/com/fr/start/module/PreStartActivator.java
  13. 36
      designer-realize/src/main/java/com/fr/start/module/optimized/BaseDBActivator4Designer.java
  14. 23
      designer-realize/src/main/java/com/fr/start/module/optimized/ConfigurationActivator4Designer.java
  15. 25
      designer-realize/src/main/java/com/fr/start/module/optimized/DesignUpdateActivator.java
  16. 35
      designer-realize/src/main/java/com/fr/start/module/optimized/DesignerPluginActivator.java
  17. 221
      designer-realize/src/main/java/com/fr/start/module/optimized/DesignerStartupPageActivator.java
  18. 32
      designer-realize/src/main/java/com/fr/start/module/optimized/ReportBaseActivator4Designer.java
  19. 1
      designer-realize/src/test/java/com/fr/design/mainframe/app/DesignerAppUtilsTest.java
  20. 50
      designer-realize/src/test/java/com/fr/start/module/DesignerWorkspaceProviderTest.java

158
designer-base/src/main/java/com/fr/design/record/analyzer/DesignerAnalyzerActivator.java

@ -1,158 +0,0 @@
package com.fr.design.record.analyzer;
import com.fr.base.OptimizeUtil;
import com.fr.collect.Collect;
import com.fr.design.record.analyzer.Interceptor.CollectInterceptor;
import com.fr.concurrent.NamedThreadFactory;
import com.fr.design.constants.DesignerLaunchStatus;
import com.fr.design.record.analyzer.advice.CollectAdvice;
import com.fr.design.record.analyzer.advice.DBMonitorAdvice;
import com.fr.design.record.analyzer.advice.FaultToleranceAdvice;
import com.fr.design.record.analyzer.advice.FocusAdvice;
import com.fr.design.record.analyzer.advice.MonitorAdvice;
import com.fr.design.record.analyzer.advice.PerformancePointAdvice;
import com.fr.event.Event;
import com.fr.event.EventDispatcher;
import com.fr.event.Listener;
import com.fr.event.Null;
import com.fr.intelli.metrics.Compute;
import com.fr.intelli.record.Focus;
import com.fr.intelli.record.PerformancePoint;
import com.fr.jvm.assist.FineAssist;
import com.fr.module.Activator;
import com.fr.module.extension.Prepare;
import com.fr.record.analyzer.AnalyzerConfiguration;
import com.fr.record.analyzer.AnalyzerKey;
import com.fr.record.analyzer.Assistant;
import com.fr.record.analyzer.DBMetrics;
import com.fr.record.analyzer.FineAnalyzer;
import com.fr.record.analyzer.advice.AnalyzerAdviceKey;
import com.fr.record.analyzer.advice.FineAdviceAssistant;
import com.fr.record.analyzer.configuration.AnalyzerAssemblyFactory;
import com.fr.record.analyzer.configuration.FineAnalyzerAssemblyFactory;
import com.fr.stable.collections.CollectionUtils;
import com.fr.third.net.bytebuddy.description.type.TypeDescription;
import com.fr.third.net.bytebuddy.dynamic.DynamicType;
import com.fr.third.net.bytebuddy.implementation.MethodDelegation;
import com.fr.third.net.bytebuddy.matcher.ElementMatchers;
import com.fr.third.net.bytebuddy.utility.JavaModule;
import com.fr.tolerance.FaultTolerance;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.concurrent.ExecutorService;
/**
* created by Harrison on 2022/03/04
**/
public class DesignerAnalyzerActivator extends Activator implements Prepare {
@Override
public void start() {
OptimizeUtil.open(OptimizeUtil.Module.ANALYZER,() -> {
AnalyzerAssemblyFactory basicFactory = createBasicFactory();
// 兼容逻辑
List<AnalyzerConfiguration> backwardsConfigurations = findMutableBackwards(AnalyzerKey.KEY);
if (!CollectionUtils.isEmpty(backwardsConfigurations)) {
// 直接初始化,不添加默认值,防止和下面的冲突
FineAnalyzer.initDirectly(FineAssist.findInstrumentation(), basicFactory, backwardsConfigurations.toArray(new AnalyzerConfiguration[0]));
}
// 等页面完全打开后,再进行 retransform, 别影响了启动速度
EventDispatcher.listen(DesignerLaunchStatus.STARTUP_COMPLETE, new Listener<Null>() {
@Override
public void on(Event event, Null param) {
ExecutorService es = newSingleThreadExecutor(new NamedThreadFactory("designer-analyzer", true));
try {
// 加入 retransform 部分的逻辑
List<FineAdviceAssistant> adviceConfigurations = findMutable(AnalyzerAdviceKey.KEY);
if (!CollectionUtils.isEmpty(adviceConfigurations)) {
AnalyzerConfiguration[] configurations = convertConfigurations(adviceConfigurations);
es.submit(() -> {
DesignerAnalyzer.init(basicFactory, configurations);
});
}
} finally {
es.shutdown();
}
}
});
});
}
@NotNull
private AnalyzerConfiguration[] convertConfigurations(List<FineAdviceAssistant> list) {
return list.stream()
.map(AnalyzerConfiguration::create)
.toArray(AnalyzerConfiguration[]::new);
}
@Override
public void stop() {
}
@Override
public void prepare() {
addMutable(AnalyzerAdviceKey.KEY, FineAdviceAssistant.create(
ElementMatchers.isAnnotatedWith(Focus.class),
FocusAdvice.class
));
addMutable(AnalyzerAdviceKey.KEY, FineAdviceAssistant.create(
ElementMatchers.isAnnotatedWith(Compute.class),
MonitorAdvice.class
));
addMutable(AnalyzerAdviceKey.KEY, FineAdviceAssistant.create(
ElementMatchers.isAnnotatedWith(DBMetrics.class),
DBMonitorAdvice.class
));
addMutable(AnalyzerAdviceKey.KEY, FineAdviceAssistant.create(
ElementMatchers.isAnnotatedWith(PerformancePoint.class),
PerformancePointAdvice.class
));
addMutable(AnalyzerAdviceKey.KEY, FineAdviceAssistant.create(
ElementMatchers.isAnnotatedWith(FaultTolerance.class),
FaultToleranceAdvice.class
));
// 保持M1 可用
addMutable(AnalyzerKey.KEY, AnalyzerConfiguration.create(new Assistant() {
@Override
public DynamicType.Builder<?> supply(DynamicType.Builder<?> builder, TypeDescription typeDescription, ClassLoader classLoader, JavaModule module) {
return builder
.method(ElementMatchers.isAnnotatedWith(Collect.class))
.intercept(MethodDelegation.to(CollectInterceptor.class));
}
}));
addMutable(AnalyzerAdviceKey.KEY, FineAdviceAssistant.create(
ElementMatchers.isAnnotatedWith(Collect.class),
CollectAdvice.class
));
}
private AnalyzerAssemblyFactory createBasicFactory() {
AnalyzerAssemblyFactory factory = findSingleton(AnalyzerAssemblyFactory.class);
FineAnalyzerAssemblyFactory basicFactory = new FineAnalyzerAssemblyFactory();
basicFactory.prepare(factory);
return basicFactory;
}
}

27
designer-base/src/main/java/com/fr/env/EnvPrepare.java vendored

@ -1,27 +0,0 @@
package com.fr.env;
import com.fr.env.detect.EnvDetectorCenter;
import com.fr.module.Activator;
/**
* 设计器环境准备
* 更多的是一些钩子需要在环境启动切换时进行处理
* 使用监听 {@link com.fr.workspace.WorkspaceEvent} 只能满足
* before -> stop -> start -> after
* 现在支持 =>
* before -> stop -> prepare -> start -> after
*
* created by Harrison on 2022/05/29
**/
public class EnvPrepare extends Activator {
@Override
public void start() {
EnvDetectorCenter.getInstance().init();
}
@Override
public void stop() {
EnvDetectorCenter.getInstance().destroy();
}
}

156
designer-base/src/main/java/com/fr/start/server/FineEmbedServerActivator.java

@ -1,156 +0,0 @@
package com.fr.start.server;
import com.fr.cbb.websocket.core.WebSocketEndpoint;
import com.fr.design.DesignerEnvManager;
import com.fr.log.FineLoggerFactory;
import com.fr.module.Activator;
import com.fr.module.ModuleRole;
import com.fr.stable.EncodeConstants;
import com.fanruan.product.ProductConstants;
import com.fr.stable.StringUtils;
import com.fr.third.springframework.web.SpringServletContainerInitializer;
import com.fr.third.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import com.fr.workspace.WorkContext;
import org.apache.catalina.Context;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.loader.WebappLoader;
import org.apache.catalina.startup.Tomcat;
import org.apache.catalina.webresources.StandardRoot;
import org.apache.tomcat.websocket.server.WsSci;
import java.io.File;
import java.util.HashSet;
import java.util.Set;
/**
* Created by juhaoyu on 2018/6/5.
*/
@Deprecated
public class FineEmbedServerActivator extends Activator {
private static final String TOMCAT_MAX_HEADER_SIZE = "tomcat-maxHttpHeaderSize";
private Tomcat tomcat;
@Override
public synchronized void start() {
try {
FineEmbedServerMonitor.getInstance().reset();
//初始化tomcat
initTomcat();
tomcat.start();
} catch (LifecycleException e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
} finally {
FineEmbedServerMonitor.getInstance().setComplete();
}
}
@Override
public synchronized void stop() {
try {
stopSpring();
stopServerActivator();
stopTomcat();
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
private void initTomcat() {
tomcat = new Tomcat();
tomcat.setPort(DesignerEnvManager.getEnvManager().getEmbedServerPort());
// 设置解码uri使用的字符编码
tomcat.getConnector().setURIEncoding(EncodeConstants.ENCODING_UTF_8);
// 参考 https://jira.atlassian.com/browse/CONFSERVER-57582
// https://tomcat.apache.org/tomcat-8.5-doc/config/http.html
// 8.5.x 请求参数带特殊字符被tomcat拒绝 []|{}^\`"<>
tomcat.getConnector().setProperty("relaxedQueryChars", "[]|{}^&#x5c;&#x60;&quot;&lt;&gt;");
setMaxPostSize();
setMaxHttpHeaderSize();
String docBase = new File(WorkContext.getCurrent().getPath()).getParent();
//内置的上下文使用工程目录比如webroot
String contextPath = "/" + ProductConstants.getAppFolderName();
final Context context = tomcat.addContext(contextPath, docBase);
context.setResources(new StandardRoot(context));
Tomcat.initWebappDefaults(context);
//覆盖tomcat的WebAppClassLoader
context.setLoader(new FRTomcatLoader());
//直接指定initializer,tomcat就不用再扫描一遍了
SpringServletContainerInitializer initializer = new SpringServletContainerInitializer();
Set<Class<?>> classes = new HashSet<Class<?>>();
/// 该Initializer已去除
//classes.add(FineWebApplicationInitializer.class);
context.addServletContainerInitializer(initializer, classes);
// 后面本地设计的内置服务器考虑用XST
// context.addServletContainerInitializer(new WsSci(), Sets.newHashSet(WebSocketEndpoint.class));
}
// tomcat的maxPostSize会影响到post参数获取,默认2M
private void setMaxPostSize() {
if (System.getProperty("tomcat-maxPostSize") != null) {
try {
tomcat.getConnector().setMaxPostSize(Integer.parseInt(System.getProperty("tomcat-maxPostSize")));
} catch (Exception e) {
FineLoggerFactory.getLogger().error("maxPostSize error: " + e.getMessage(), e);
}
}
}
private void setMaxHttpHeaderSize() {
String value = System.getProperty(TOMCAT_MAX_HEADER_SIZE);
if (StringUtils.isNotEmpty(value)) {
try {
tomcat.getConnector().setProperty("maxHttpHeaderSize", value);
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
}
private void stopServerActivator() {
ModuleRole.ServerRoot.stop();
}
private void stopSpring() {
AnnotationConfigWebApplicationContext context = ModuleRole.ServerRoot.findSingleton(AnnotationConfigWebApplicationContext.class);
if (context != null) {
context.stop();
context.destroy();
}
}
private void stopTomcat() throws LifecycleException {
tomcat.stop();
tomcat.destroy();
}
/**
* Created by juhaoyu on 2018/6/5.
* 自定义的tomcat loader主要用于防止内置服务器再加载一遍class
*/
private static class FRTomcatLoader extends WebappLoader {
@Override
public ClassLoader getClassLoader() {
return this.getClass().getClassLoader();
}
}
}

591
designer-realize/src/main/java/com/fr/start/module/DesignerActivator.java

@ -1,591 +0,0 @@
package com.fr.start.module;
import com.fanruan.carina.Carina;
import com.fanruan.config.bbs.FineBBSConfigProvider;
import com.fine.theme.icon.LazyIcon;
import com.fr.base.BaseFormula;
import com.fr.base.Formula;
import com.fr.base.MultiFieldParameter;
import com.fr.base.OptimizeUtil;
import com.fr.base.password.FinePassportListenerAdapter;
import com.fr.base.password.FinePassportManager;
import com.fr.base.process.ProcessOperator;
import com.fr.base.theme.migrator.FormThemeConfigMigrator;
import com.fr.base.theme.migrator.ReportThemeConfigMigrator;
import com.fr.chart.chartattr.ChartCollection;
import com.fr.config.ServerPreferenceConfig;
import com.fr.decision.update.backup.RecoverManager;
import com.fr.decision.webservice.v10.plugin.helper.category.impl.PluginResourceLoader;
import com.fr.decision.webservice.v10.plugin.helper.category.impl.UpmResourceLoader;
import com.fr.design.DesignerEnvManager;
import com.fr.design.ExtraDesignClassManager;
import com.fr.design.RPCConnectHandlerCenter;
import com.fr.design.actions.NewFormAction;
import com.fr.design.actions.UpdateAction;
import com.fr.design.actions.core.ActionFactory;
import com.fr.design.actions.insert.cell.BiasCellAction;
import com.fr.design.actions.insert.cell.ChartCellAction;
import com.fr.design.actions.insert.cell.DSColumnCellAction;
import com.fr.design.actions.insert.cell.FormulaCellAction;
import com.fr.design.actions.insert.cell.GeneralCellAction;
import com.fr.design.actions.insert.cell.ImageCellAction;
import com.fr.design.actions.insert.cell.RichTextCellAction;
import com.fr.design.actions.insert.cell.SubReportCellAction;
import com.fr.design.actions.insert.flot.ChartFloatAction;
import com.fr.design.actions.insert.flot.FormulaFloatAction;
import com.fr.design.actions.insert.flot.ImageFloatAction;
import com.fr.design.actions.insert.flot.TextBoxFloatAction;
import com.fr.design.actions.replace.ITReplaceAction;
import com.fr.design.actions.replace.utils.ReplaceOperator;
import com.fr.design.bridge.DesignToolbarProvider;
import com.fr.design.constants.DesignerLaunchStatus;
import com.fr.design.env.DesignerWorkspaceLoader;
import com.fr.design.fit.NewJForm;
import com.fr.design.fit.common.TemplateTool;
import com.fr.design.form.parameter.FormParaDesigner;
import com.fr.design.fun.ElementUIProvider;
import com.fr.design.gui.controlpane.NameObjectCreator;
import com.fr.design.gui.controlpane.NameableCreator;
import com.fr.design.gui.frpane.HyperlinkGroupPaneActionProvider;
import com.fr.design.hyperlink.ReportletHyperlinkPane;
import com.fr.design.hyperlink.WebHyperlinkPane;
import com.fr.design.hyperlink.popup.MobilePopupPane;
import com.fr.design.i18n.DesignI18nImpl;
import com.fr.design.javascript.EmailPane;
import com.fr.design.javascript.JavaScriptImplPane;
import com.fr.design.javascript.ParameterJavaScriptPane;
import com.fr.design.javascript.ProcessTransitionAdapter;
import com.fr.design.lock.TemplateLockInfoReSave;
import com.fr.design.login.DesignerLoginType;
import com.fr.design.login.guide.DesignerGuideHelper;
import com.fr.design.login.message.DesignerMessageHelper;
import com.fr.design.login.socketio.LoginAuthServer;
import com.fr.design.mainframe.BaseJForm;
import com.fr.design.mainframe.FormHierarchyTreePane;
import com.fr.design.mainframe.HyperlinkGroupPaneActionImpl;
import com.fr.design.mainframe.InformationCollector;
import com.fr.design.mainframe.JTemplateEvent;
import com.fr.design.mainframe.WidgetPropertyPane;
import com.fr.design.mainframe.WidgetToolBarPane;
import com.fr.design.mainframe.alphafine.AlphaFineHelper;
import com.fr.design.mainframe.alphafine.question.QuestionWindow;
import com.fr.design.mainframe.alphafine.search.manager.impl.ProductNewsSearchManager;
import com.fr.design.mainframe.bbs.BBSGuestPane;
import com.fr.design.mainframe.bbs.UserInfoPane;
import com.fr.design.mainframe.form.FormECCompositeProvider;
import com.fr.design.mainframe.form.FormECDesignerProvider;
import com.fr.design.mainframe.form.FormElementCaseDesigner;
import com.fr.design.mainframe.form.FormReportComponentComposite;
import com.fr.design.mainframe.guide.GuideRegister;
import com.fr.design.mainframe.loghandler.DesignerLogAppender;
import com.fr.design.mainframe.share.constants.ShareEntryKey;
import com.fr.design.mainframe.socketio.DesignerSocketIO;
import com.fr.design.mod.ContentReplacerCenter;
import com.fr.design.module.DesignModuleFactory;
import com.fr.design.os.impl.SupportOSImpl;
import com.fr.design.parameter.FormParameterReader;
import com.fr.design.parameter.ParameterPropertyPane;
import com.fr.design.parameter.WorkBookParameterReader;
import com.fr.design.share.SharableManager;
import com.fr.design.share.ui.config.ShareConfigPane;
import com.fr.design.share.ui.generate.ShareGeneratePane;
import com.fr.design.update.actions.RecoverForDesigner;
import com.fr.design.update.push.DesignerPushUpdateManager;
import com.fr.design.widget.ui.btn.FormSubmitButtonDetailPane;
import com.fr.event.Event;
import com.fr.event.EventDispatcher;
import com.fr.event.Listener;
import com.fr.event.Null;
import com.fr.general.GeneralContext;
import com.fr.general.xml.GeneralXMLTools;
import com.fr.js.EmailJavaScript;
import com.fr.js.JavaScriptImpl;
import com.fr.js.MobilePopupHyperlink;
import com.fr.js.ParameterJavaScript;
import com.fr.js.ReportletHyperlink;
import com.fr.js.WebHyperlink;
import com.fr.locale.InterMutableKey;
import com.fr.locale.LocaleMarker;
import com.fr.locale.LocaleScope;
import com.fr.log.FineLoggerFactory;
import com.fr.log.LogHandler;
import com.fr.module.Activator;
import com.fr.module.extension.Prepare;
import com.fr.plugin.beforeload.embed.DefaultPluginEmbedInfo;
import com.fr.plugin.beforeload.embed.PluginEmbedInfo;
import com.fr.plugin.context.PluginContext;
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.quickeditor.cellquick.CellBiasTextPainterEditor;
import com.fr.quickeditor.cellquick.CellDSColumnEditor;
import com.fr.quickeditor.cellquick.CellFormulaQuickEditor;
import com.fr.quickeditor.cellquick.CellImageQuickEditor;
import com.fr.quickeditor.cellquick.CellRichTextEditor;
import com.fr.quickeditor.cellquick.CellStringQuickEditor;
import com.fr.quickeditor.cellquick.CellSubReportEditor;
import com.fr.quickeditor.chartquick.BasicChartQuickEditor;
import com.fr.quickeditor.chartquick.FloatChartQuickEditor;
import com.fr.quickeditor.floatquick.FloatImageQuickEditor;
import com.fr.quickeditor.floatquick.FloatStringQuickEditor;
import com.fr.report.cell.CellElementValueConverter;
import com.fr.report.cell.cellattr.core.RichText;
import com.fr.report.cell.cellattr.core.SubReport;
import com.fr.report.cell.cellattr.core.group.DSColumn;
import com.fr.report.cell.painter.BiasTextPainter;
import com.fr.report.cell.painter.CellImagePainter;
import com.fr.stable.ParameterProvider;
import com.fr.stable.bridge.StableFactory;
import com.fr.stable.os.support.OSBasedAction;
import com.fr.stable.os.support.OSSupportCenter;
import com.fr.stable.plugin.ExtraDesignClassManagerProvider;
import com.fr.stable.script.CalculatorProviderContext;
import com.fr.stable.script.ValueConverter;
import com.fr.stable.xml.ObjectTokenizer;
import com.fr.stable.xml.ObjectXMLWriterFinder;
import com.fr.start.BBSGuestPaneProvider;
import com.fr.start.common.DesignerStartupExecutor;
import com.fr.start.common.DesignerStartupPool;
import com.fr.strongest.WidgetThemeListenerStarter;
import com.fr.task.Once;
import com.fr.workspace.WorkContext;
import com.fr.xml.ReportXMLUtils;
import javax.swing.SwingWorker;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
/**
* Created by juhaoyu on 2018/1/31.
* 触发原来的DesignerModule的启动
* 之后慢慢将DesignerModule拆成Activator
*/
public class DesignerActivator extends Activator implements Prepare {
private LogHandler<DesignerLogAppender> logHandler = null;
private static final String PLUGIN_EXPORT_IMAGE_SETTING = "com.fr.plugin.exportimagesettings.v11";
private final Once pushUpdateTask = new Once(new Runnable() {
@Override
public void run() {
DesignerPushUpdateManager.getInstance().preparePushUpdate();
DesignerGuideHelper.prepareShowGuideDialog();
DesignerMessageHelper.getInstance().prepareShowMessage();
}
});
private boolean hasUpdated = false;
@Override
public void start() {
List<LocaleMarker> markers = findMutable(InterMutableKey.Path);
for (LocaleMarker marker : markers) {
if (marker.match(LocaleScope.DESIGN)) {
DesignI18nImpl.getInstance().addResource(marker.getPath());
}
}
CompletableFuture<Void> themeConfigPrepare = CompletableFuture.runAsync(() -> {
if (WorkContext.getCurrent().isLocal()) {
FormThemeConfigMigrator.getInstance().upgrade();
ReportThemeConfigMigrator.getInstance().upgrade();
}
}, DesignerStartupPool.common());
CompletableFuture<Void> mainDesignerPrepare = CompletableFuture.runAsync(this::designerModuleStart, DesignerStartupPool.common());
CompletableFuture<Void> extendDesignerPrepare = CompletableFuture.runAsync(this::designerExtendStart, DesignerStartupPool.common());
CompletableFuture<Void> otherFeaturesPrepare = CompletableFuture.runAsync(() -> {
startBBSLoginAuthServer();
migrateBBSInfoFromFineDB();
OSSupportCenter.buildAction(new OSBasedAction() {
@Override
public void execute(Object... objects) {
UserInfoPane.getInstance().updateBBSUserInfo();
}
}, SupportOSImpl.BBS_USER_LOGIN_PANE);
loadLogAppender();
//DesignerSocketIO.update();
DesignerWorkspaceLoader.init();
storePassport();
AlphaFineHelper.switchConfig4Locale();
RecoverManager.register(new RecoverForDesigner());
WidgetThemeListenerStarter.start();
TemplateLockInfoReSave.startListener();
RPCConnectHandlerCenter.startListener();
}, DesignerStartupPool.common());
CompletableFuture<Void> resourcePrepare = CompletableFuture.runAsync(() -> {
pushUpdateTask.run();
if (WorkContext.getCurrent().isLocal()) {
PluginResourceLoader.INSTANCE.checkOldShopFile();
UpmResourceLoader.INSTANCE.checkOldShopFile();
}
}, DesignerStartupPool.common());
CompletableFuture
.allOf(mainDesignerPrepare, extendDesignerPrepare, themeConfigPrepare, otherFeaturesPrepare, resourcePrepare)
.join();
}
@Override
public void afterAllStart() {
DesignerStartupExecutor.getInstance().execute(() -> DesignerLaunchStatus.setStatus(DesignerLaunchStatus.DESIGNER_INIT_COMPLETE));
//生成BasicChartQuickEditor对象,需要用到ChartDesignerActivator的注册信息(DesignModuleFactory.registerChartPropertyPaneClass(ChartPropertyPane.class);)
//所以不能在registerCellEditor函数中进行注册
ActionFactory.registerCellEditor(ChartCollection.class, new BasicChartQuickEditor());
if (DesignerEnvManager.getEnvManager().isUseOptimizedUPM4Adapter() && WorkContext.getCurrent().isLocal()) {
ServerPreferenceConfig.getInstance().setUseOptimizedUPM(DesignerEnvManager.getEnvManager().isUseOptimizedUPM4Adapter());
}
}
private void loadLogAppender() {
logHandler = new LogHandler<DesignerLogAppender>() {
final DesignerLogAppender logAppender = DesignerLogAppender.createDesignerLogAppender();
@Override
public DesignerLogAppender getHandler() {
return logAppender;
}
};
logHandler.getHandler().start();
FineLoggerFactory.getLogger().addLogAppender(logHandler);
}
private void unloadLogAppender() {
if (logHandler != null) {
logHandler.getHandler().stop();
FineLoggerFactory.getLogger().removeLogAppender(logHandler);
}
}
private void designerModuleStart() {
StableFactory.registerMarkedClass(ExtraDesignClassManagerProvider.XML_TAG, ExtraDesignClassManager.class);
ActionFactory.registerCellInsertActionClass(actionsForInsertCellElement());
ActionFactory.registerFloatInsertActionClass(actionsForInsertFloatElement());
DesignModuleFactory.registerCreators4Hyperlink(hyperlinkTypes());
createPluginListener();
justStartModules4Designer();
CalculatorProviderContext.setValueConverter(valueConverter());
GeneralXMLTools.Object_Tokenizer = startXMLReadObjectTokenizer();
GeneralXMLTools.Object_XML_Writer_Finder = startObjectXMLWriterFinder();
addAdapterForPlate();
designerRegister();
}
private void designerExtendStart() {
SharableManager.start();
InformationCollector.getInstance().collectStartTime();
GuideRegister.register();
}
private void createPluginListener() {
GeneralContext.listenPluginRunningChanged(new PluginEventListener() {
@Override
public void on(PluginEvent event) {
ActionFactory.referCellInsertActionClass(actionsForInsertCellElement());
ActionFactory.referFloatInsertActionClass(actionsForInsertFloatElement());
}
}, new PluginFilter() {
@Override
public boolean accept(PluginContext context) {
return context.contain(PluginModule.ExtraDesign, ElementUIProvider.MARK_STRING);
}
});
}
private static Class<? extends UpdateAction>[] actionsForInsertCellElement() {
List<Class<?>> classes = new ArrayList<>();
classes.add(DSColumnCellAction.class);
classes.add(GeneralCellAction.class);
classes.add(RichTextCellAction.class);
classes.add(FormulaCellAction.class);
classes.add(ChartCellAction.class);
classes.add(ImageCellAction.class);
classes.add(BiasCellAction.class);
classes.add(SubReportCellAction.class);
Set<ElementUIProvider> providers = ExtraDesignClassManager.getInstance().getArray(ElementUIProvider.MARK_STRING);
for (ElementUIProvider provider : providers) {
classes.add(provider.actionForInsertCellElement());
}
return classes.toArray(new Class[0]);
}
private static Class<? extends UpdateAction>[] actionsForInsertFloatElement() {
List<Class<? extends UpdateAction>> classes = new ArrayList<>();
classes.add(TextBoxFloatAction.class);
classes.add(FormulaFloatAction.class);
classes.add(ChartFloatAction.class);
classes.add(ImageFloatAction.class);
Set<ElementUIProvider> providers = ExtraDesignClassManager.getInstance().getArray(ElementUIProvider.MARK_STRING);
for (ElementUIProvider provider : providers) {
classes.add(provider.actionForInsertFloatElement());
}
return classes.toArray(new Class[0]);
}
private static NameableCreator[] hyperlinkTypes() {
return new NameableCreator[]{
new NameObjectCreator(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Hyperlink_Reportlet"), ReportletHyperlink.class, ReportletHyperlinkPane.ChartNoRename.class),
new NameObjectCreator(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Email"), EmailJavaScript.class, EmailPane.class),
new NameObjectCreator(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Hyperlink_Web_Link"), WebHyperlink.class, WebHyperlinkPane.ChartNoRename.class),
new NameObjectCreator(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_JavaScript_Dynamic_Parameters"), ParameterJavaScript.class, ParameterJavaScriptPane.ChartNoRename.class),
new NameObjectCreator(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_JavaScript"), JavaScriptImpl.class, JavaScriptImplPane.ChartNoRename.class),
new NameObjectCreator(com.fr.design.i18n.Toolkit.i18nText("FR-Plugin-Designer_Mobile_Popup"), MobilePopupHyperlink.class, MobilePopupPane.class),
};
}
private static void justStartModules4Designer() {
formDesignerRegister();
}
/**
* CellElementValueConverter用来处理设计器格子里的值将公式/数组/其他元素转换成对应的值
*
* @return 返回处理格子值的转换器
*/
private static ValueConverter valueConverter() {
return new CellElementValueConverter();
}
/*
* 针对不同的对象在读取Object对象的xml的时候需要使用不同的对象生成器
* @return 返回对象生成器
*/
private static ObjectTokenizer startXMLReadObjectTokenizer() {
return new ReportXMLUtils.ReportObjectTokenizer();
}
/**
* 针对不同的对象在写对象的XML时需要使用不同的XML生成器
*
* @return 返回xml生成器
*/
private static ObjectXMLWriterFinder startObjectXMLWriterFinder() {
return new ReportXMLUtils.ReportObjectXMLWriterFinder();
}
//wei:fs的模块中可能有需要设计器界面做设置的地方,在这边添加
private static void addAdapterForPlate() {
ProcessTransitionAdapter.setProcessTransitionAdapter(new ProcessTransitionAdapter() {
@Override
protected String[] getTransitionNamesByBook(String book) {
return StableFactory.getMarkedObject(ProcessOperator.MARK_STRING, ProcessOperator.class, ProcessOperator.EMPTY).getTransitionNamesByBook(book);
}
@Override
protected String[] getParaNames(String book) {
return StableFactory.getMarkedObject(ProcessOperator.MARK_STRING, ProcessOperator.class, ProcessOperator.EMPTY).getParaNames(book);
}
@Override
protected ParameterProvider[] getParas(String book) {
return StableFactory.getMarkedObject(ProcessOperator.MARK_STRING, ProcessOperator.class, ProcessOperator.EMPTY).getParas(book);
}
@Override
protected MultiFieldParameter[] getAllMultiFieldParas(String book) {
return StableFactory.getMarkedObject(ProcessOperator.MARK_STRING, ProcessOperator.class, ProcessOperator.EMPTY).getAllMultiFieldParas(book);
}
});
}
private static void designerRegister() {
registerCellEditor();
registerFloatEditor();
registerData4Form();
registerOtherPane();
}
private static void registerOtherPane() {
StableFactory.registerMarkedClass(BBSGuestPaneProvider.XML_TAG, BBSGuestPane.class);
StableFactory.registerMarkedObject(HyperlinkGroupPaneActionProvider.XML_TAG, HyperlinkGroupPaneActionImpl.getInstance());
}
/**
* kunsnat:注册单元格选中Editor
*/
private static void registerCellEditor() {
ActionFactory.registerAsyncInitCellEditorClass(String.class, CellStringQuickEditor.class);
ActionFactory.registerAsyncInitCellEditorClass(Number.class, CellStringQuickEditor.class);
ActionFactory.registerAsyncInitCellEditorClass(BaseFormula.class, CellFormulaQuickEditor.class);
ActionFactory.registerAsyncInitCellEditorClass(SubReport.class, CellSubReportEditor.class);
ActionFactory.registerAsyncInitCellEditorClass(RichText.class, CellRichTextEditor.class);
ActionFactory.registerAsyncInitCellEditorClass(DSColumn.class, CellDSColumnEditor.class);
ActionFactory.registerAsyncInitCellEditorClass(Image.class, CellImageQuickEditor.class);
ActionFactory.registerAsyncInitCellEditorClass(BiasTextPainter.class, CellBiasTextPainterEditor.class);
ActionFactory.registerAsyncInitCellEditorClass(BufferedImage.class, CellImageQuickEditor.class);
ActionFactory.registerAsyncInitCellEditorClass(CellImagePainter.class, CellImageQuickEditor.class);
Set<ElementUIProvider> providers = ExtraDesignClassManager.getInstance().getArray(ElementUIProvider.MARK_STRING);
for (ElementUIProvider provider : providers) {
try {
if (provider.quickEditor() == null) {
continue;
}
ActionFactory.registerAsyncInitCellEditorClass(provider.targetObjectClass(), provider.quickEditor());
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
}
/**
* kunnat: 注册悬浮选中Editor
*/
private static void registerFloatEditor() {
ActionFactory.registerFloatEditor(String.class, new FloatStringQuickEditor());
ActionFactory.registerFloatEditor(Formula.class, new FloatStringQuickEditor());
ActionFactory.registerFloatEditor(Image.class, new FloatImageQuickEditor());
ActionFactory.registerFloatEditor(BufferedImage.class, new FloatImageQuickEditor());
ActionFactory.registerFloatEditor(CellImagePainter.class, new FloatImageQuickEditor());
//todo 图表编辑器populate没能实现刷新面板显示
ActionFactory.registerFloatEditorClass(ChartCollection.class, FloatChartQuickEditor.class);
}
private static void registerData4Form() {
StableFactory.registerMarkedClass(FormECDesignerProvider.XML_TAG, FormElementCaseDesigner.class);
StableFactory.registerMarkedClass(FormECCompositeProvider.XML_TAG, FormReportComponentComposite.class);
StableFactory.registerMarkedClass(ShareEntryKey.SHARE_GENERATE, ShareGeneratePane.class);
StableFactory.registerMarkedClass(ShareEntryKey.SHARE_CONFIG, ShareConfigPane.class);
DesignModuleFactory.registerParameterReader(new WorkBookParameterReader());
}
private static void formDesignerRegister() {
StableFactory.registerMarkedObject(DesignToolbarProvider.STRING_MARKED, WidgetToolBarPane.getInstance());
DesignModuleFactory.registerNewFormActionClass(NewFormAction.class);
DesignModuleFactory.registerReplaceActionClass(ITReplaceAction.class);
DesignModuleFactory.registerFormParaDesignerClass(FormParaDesigner.class);
DesignModuleFactory.registerParaPropertyPaneClass(ParameterPropertyPane.class);
DesignModuleFactory.registerFormHierarchyPaneClass(FormHierarchyTreePane.class);
DesignModuleFactory.registerWidgetPropertyPaneClass(WidgetPropertyPane.class);
DesignModuleFactory.registerButtonDetailPaneClass(FormSubmitButtonDetailPane.class);
DesignModuleFactory.registerReplace(new ReplaceOperator());
DesignModuleFactory.registerParameterReader(new FormParameterReader());
StableFactory.registerMarkedClass(BaseJForm.XML_TAG, NewJForm.class);
registerJTemplateEvent();
}
private static void registerJTemplateEvent(){
EventDispatcher.listen(JTemplateEvent.BEFORE_TEMPLATE_INIT, TemplateTool.getSwitchListener());
EventDispatcher.listen(JTemplateEvent.BEFORE_TEMPLATE_ACTIVE, TemplateTool.getSwitchListener());
}
private static void storePassport() {
FinePassportManager.getInstance().storePassport(DesignerEnvManager.getEnvManager().getDesignerLoginUsername(), DesignerEnvManager.getEnvManager().getActivationKey());
FinePassportManager.getInstance().addPassportListener(new FinePassportListenerAdapter() {
@Override
public void onLoginSuccess() {
FinePassportManager.getInstance().storePassport(DesignerEnvManager.getEnvManager().getDesignerLoginUsername(), DesignerEnvManager.getEnvManager().getActivationKey());
}
});
}
private void migrateBBSInfoFromFineDB() {
if (!WorkContext.getCurrent().isLocal()) {
return;
}
DesignerEnvManager manager = DesignerEnvManager.getEnvManager();
if (manager.isCurrentVersionFirstLaunch()) {
int newUid = manager.getDesignerLoginUid();
if (newUid > 0) {
return;
}
int oldUid = Carina.config(FineBBSConfigProvider.class).getBbsUid();
if (oldUid > 0) {
manager.setDesignerLoginUid(oldUid);
manager.setDesignerLoginUsername(Carina.config(FineBBSConfigProvider.class).getBbsUsername());
manager.setDesignerLoginAppId(Carina.config(FineBBSConfigProvider.class).getBbsAppId());
manager.setDesignerLoginRefreshToken(Carina.config(FineBBSConfigProvider.class).getBbsRefreshToken());
manager.setDesignerLastLoginTime(System.currentTimeMillis());
manager.setLastLoginType(DesignerLoginType.NORMAL_LOGIN);
manager.setLastLoginAccount(Carina.config(FineBBSConfigProvider.class).getBbsUsername());
manager.setCurrentVersionFirstLaunch(false);
DesignerEnvManager.getEnvManager().saveXMLFile();
}
}
}
@Override
public void stop() {
unloadLogAppender();
DesignerSocketIO.close();
TemplateLockInfoReSave.stopListener();
RPCConnectHandlerCenter.stopListener();
}
@Override
public void prepare() {
if (!OptimizeUtil.isOpen()) {
LoginAuthServer.getInstance().compatibleStart();
}
ContentReplacerCenter.getInstance().register();
EventDispatcher.listen(DesignerLaunchStatus.STARTUP_COMPLETE, new Listener<Null>() {
@Override
public void on(Event event, Null param) {
new SwingWorker<Void, Void>() {
@Override
protected Void doInBackground() throws Exception {
// 触发下cid 搜索
ProductNewsSearchManager.getInstance().getProductNewsList();
return null;
}
@Override
protected void done() {
QuestionWindow.getInstance().setVisible(true);
}
}.execute();
}
});
prepareDefaultEmbedPluginInfo();
}
private void prepareDefaultEmbedPluginInfo() {
Carina.getApplicationContext().group(PluginEmbedInfo.class).add(DefaultPluginEmbedInfo.create(PLUGIN_EXPORT_IMAGE_SETTING));
}
private void startBBSLoginAuthServer() {
OptimizeUtil.open(() -> {
// 设计器启动后启动
EventDispatcher.listen(DesignerLaunchStatus.STARTUP_COMPLETE, new Listener<Null>() {
@Override
public void on(Event event, Null param) {
LoginAuthServer.getInstance().start();
}
});
});
}
}

26
designer-realize/src/main/java/com/fr/start/module/DesignerESDActivator.java

@ -1,26 +0,0 @@
package com.fr.start.module;
import com.fr.esd.cache.manager.RecommendManager;
import com.fr.esd.core.strategy.config.service.StrategyConfigService;
import com.fr.esd.core.strategy.recomend.EnabledTemplateService;
import com.fr.esd.core.strategy.recomend.EnabledTemplateServiceProvider;
import com.fr.esd.impl.strategy.config.service.DefaultStrategyConfigServiceProvider;
import com.fr.module.Activator;
/**
* @author rinoux
* @version 10.0
* Created by rinoux on 2021/8/3
*/
public class DesignerESDActivator extends Activator {
@Override
public void start() {
StrategyConfigService.setService(new DefaultStrategyConfigServiceProvider());
EnabledTemplateService.getInstance().registerService(path -> RecommendManager.getInstance().findByPath(path) != null);
}
@Override
public void stop() {
//ignore
}
}

38
designer-realize/src/main/java/com/fr/start/module/DesignerInitActivator.java

@ -1,38 +0,0 @@
package com.fr.start.module;
import com.fanruan.boot.key.StartupArgsShell;
import com.fanruan.carina.Carina;
import com.fr.design.PluginClassRefreshManager;
import com.fanruan.boot.env.function.app.DesignerAppUtils;
import com.fr.io.repository.base.fs.FileSystemRepository;
import com.fr.io.utils.ResourceIOUtils;
import com.fr.module.Activator;
import com.fr.module.extension.Prepare;
import com.fr.start.DesignerInitial;
/**
* 设计器界面初始化
*
* @author vito
* @since 10.0
* Created on 2019/9/25
*/
public class DesignerInitActivator extends Activator implements Prepare {
@Override
public void prepare() {
ResourceIOUtils.setUnderlying(FileSystemRepository.getSingleton());
}
@Override
public void start() {
PluginClassRefreshManager.getInstance().load();
DesignerAppUtils.initPluginAllActiveListener();
DesignerInitial.init(Carina.getApplicationContext().singleton(StartupArgsShell.class).get().get());
}
@Override
public void stop() {
// void
}
}

24
designer-realize/src/main/java/com/fr/start/module/DesignerShowActivator.java

@ -1,24 +0,0 @@
package com.fr.start.module;
import com.fr.design.i18n.Toolkit;
import com.fr.event.EventDispatcher;
import com.fr.module.Activator;
import com.fr.start.DesignerInitial;
/**
* Created by juhaoyu on 2019-06-14.
*/
public class DesignerShowActivator extends Activator {
@Override
public void start() {
/// 后续换成其他进度方式
//EventDispatcher.asyncFire(ModuleEvent.MajorModuleStarting, Toolkit.i18nText("Fine-Design_Module_Name_Designer"));
DesignerInitial.prepare();
}
@Override
public void stop() {
// void
}
}

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

@ -1,200 +0,0 @@
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<StartupArgs> startupArgsValue = new NotNullLazyValue<StartupArgs>() {
@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<Null>(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(() -> {
try {
FineEmbedServer.start();
} catch (Exception e) {
throw new RuntimeException(e);
}
});
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
}
}

123
designer-realize/src/main/java/com/fr/start/module/DesignerWorkspaceActivator.java

@ -1,123 +0,0 @@
package com.fr.start.module;
import com.fr.concurrent.NamedThreadFactory;
import com.fr.design.PluginClassRefreshManager;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.event.Event;
import com.fr.event.Listener;
import com.fr.module.Activator;
import com.fr.module.ModuleContext;
import com.fr.module.engine.FineModule;
import com.fr.start.server.FineEmbedServer;
import com.fr.workspace.WorkContext;
import com.fr.workspace.Workspace;
import com.fr.workspace.WorkspaceEvent;
import com.fr.workspace.WorkspaceSwitchProcess;
import java.util.Optional;
import java.util.concurrent.ExecutorService;
/**
* Created by juhaoyu on 2019-06-14.
*/
public class DesignerWorkspaceActivator extends Activator {
private final Listener<Workspace> stopModuleAction = new Listener<Workspace>(Integer.MIN_VALUE) {
@Override
public void on(Event event, Workspace current) {
stopSub(EnvBasedModule.class);
recordModuleStop();
}
private void recordModuleStop() {
WorkspaceSwitchProcess process = WorkContext.getSwitcher().getProcess();
Optional.ofNullable(process)
.ifPresent((e) -> e.recordModuleStopUsed(() -> {
FineModule module = (FineModule) ModuleContext.getModule(EnvBasedModule.class);
return module.profileStop();
}));
}
};
private final Listener<Workspace> startModuleAction = new Listener<Workspace>(Integer.MAX_VALUE) {
@Override
public void on(Event event, Workspace current) {
startSub(EnvBasedModule.class);
recordModuleStart();
}
private void recordModuleStart() {
WorkspaceSwitchProcess process = WorkContext.getSwitcher().getProcess();
Optional.ofNullable(process)
.ifPresent((e) -> e.recordModuleStartUsed(() -> {
FineModule module = (FineModule) ModuleContext.getModule(EnvBasedModule.class);
return module.profile();
}));
}
};
@Override
public void start() {
registerEnvListener();
}
/**
* 注册切换环境前后事件监听
*/
private void registerEnvListener() {
/*切换环境前,关闭所有相关模块,最后执行*/
listenEvent(WorkspaceEvent.BeforeSwitch, stopModuleAction);
/*切换环境后,重新启动所有相关模块,最先执行*/
listenEvent(WorkspaceEvent.AfterSwitch, startModuleAction);
/*切换环境前,存储一下打开的所有文件对象,要先于 关闭相关模块部分 被触发*/
listenEvent(WorkspaceEvent.BeforeSwitch, new Listener<Workspace>(Integer.MAX_VALUE) {
@Override
public void on(Event event, Workspace workspace) {
PluginClassRefreshManager.getInstance().removePluginListener();
HistoryTemplateListCache.getInstance().stash();
PluginClassRefreshManager.getInstance().fireTabChange();
}
});
/*切换环境后,装载一下打开的所有文件对象,优先级低于默认优先级,要后于 启动相关模块部分 被触发*/
listenEvent(WorkspaceEvent.AfterSwitch, new Listener<Workspace>(Integer.MIN_VALUE) {
@Override
public void on(Event event, Workspace workspace) {
HistoryTemplateListCache.getInstance().load();
PluginClassRefreshManager.getInstance().addPluginListener();
}
});
}
private void startServer(Workspace current) {
// 切换后的环境是本地环境才启动内置服务器
if (current.isLocal()) {
ExecutorService service = newSingleThreadExecutor(
new NamedThreadFactory("DesignerWorkspaceActivator"));
service.submit(() -> {
try {
FineEmbedServer.start();
} catch (Exception e) {
throw new RuntimeException(e);
}
});
service.shutdown();
}
}
@Override
public void stop() {
}
}

99
designer-realize/src/main/java/com/fr/start/module/DesignerWorkspaceProvider.java

@ -1,99 +0,0 @@
package com.fr.start.module;
import com.fanruan.boot.key.StartupArgsShell;
import com.fanruan.carina.Carina;
import com.fr.design.DesignerEnvManager;
import com.fr.design.EnvChangeEntrance;
import com.fr.design.constants.DesignerLaunchStatus;
import com.fr.design.editlock.ConnectionLockChangeChecker;
import com.fr.design.editlock.ServerTableDataLockChangeChecker;
import com.fr.design.env.DesignerWorkspaceGenerator;
import com.fr.design.env.DesignerWorkspaceInfo;
import com.fr.design.plugin.remind.PluginErrorDesignReminder;
import com.fr.env.utils.WorkspaceUtils;
import com.fr.event.Event;
import com.fr.event.EventDispatcher;
import com.fr.event.Listener;
import com.fr.event.Null;
import com.fr.module.Activator;
import com.fr.design.backup.DesignContext;
import com.fr.value.NotNullLazyValue;
import com.fr.workspace.WorkContext;
import com.fr.workspace.Workspace;
import org.jetbrains.annotations.NotNull;
/**
* Created by juhaoyu on 2018/1/8.
* 设计器启动时的环境相关模块activator
*/
public class DesignerWorkspaceProvider extends Activator {
private NotNullLazyValue<StartupArgs> startupArgs = new NotNullLazyValue<StartupArgs>() {
@NotNull
@Override
protected StartupArgs compute() {
return Carina.getApplicationContext().singleton(StartupArgsShell.class).get();
}
};
@Override
public void start() {
//检查环境
DesignerEnvManager.checkNameEnvMap();
if (startupArgs.getValue().isDemo()) {
DesignerEnvManager.getEnvManager().setCurrentEnv2Default();
} else {
DesignerWorkspaceInfo workspaceInfo = null;
try {
String current = DesignerEnvManager.getEnvManager().getCurEnvName();
workspaceInfo = WorkspaceUtils.getWorkspaceInfo();
((DesignContext)Carina.getApplicationContext()).setDesignWebInfPath(workspaceInfo.getPath());
Workspace workspace = DesignerWorkspaceGenerator.generate(workspaceInfo);
boolean checkValid = workspace != null && workspaceInfo.checkValid();
if (!checkValid) {
EnvChangeEntrance.getInstance().dealEvnExceptionWhenStartDesigner(null, workspaceInfo);
} else {
WorkContext.switchTo(workspace);
}
} catch (Throwable e) {
EnvChangeEntrance.getInstance().dealEvnExceptionWhenStartDesigner(e, workspaceInfo);
}
}
pluginErrorRemind();
editLockCheckerStart();
}
private void editLockCheckerStart() {
ConnectionLockChangeChecker.getInstance().start();
ServerTableDataLockChangeChecker.getInstance().start();
}
private void pluginErrorRemind() {
EventDispatcher.listen(DesignerLaunchStatus.STARTUP_COMPLETE, new Listener<Null>() {
@Override
public void on(Event event, Null aNull) {
PluginErrorDesignReminder.getInstance().remindStartFailedPlugins();
PluginErrorDesignReminder.getInstance().remindInvalidatePlugins();
}
});
}
@Override
public void stop() {
// void
editLockCheckerStop();
}
private void editLockCheckerStop() {
ConnectionLockChangeChecker.getInstance().stop();
ServerTableDataLockChangeChecker.getInstance().stop();
}
@Override
public void afterAllStart() {
DesignerLaunchStatus.setStatus(DesignerLaunchStatus.WORKSPACE_INIT_COMPLETE);
}
}

21
designer-realize/src/main/java/com/fr/start/module/EnvBasedModule.java

@ -1,21 +0,0 @@
package com.fr.start.module;
import com.fr.module.Activator;
import com.fr.start.server.FineEmbedServer;
/**
* Created by juhaoyu on 2018/6/6.
* 基于env的模块启动关闭
*/
public class EnvBasedModule extends Activator {
@Override
public void start() {
}
@Override
public void stop() {
//先关闭tomcat(如果已经启动了的话)
FineEmbedServer.stop();
}
}

59
designer-realize/src/main/java/com/fr/start/module/PreStartActivator.java

@ -1,59 +0,0 @@
package com.fr.start.module;
import com.fr.design.DesignerEnvManager;
import com.fr.design.RestartHelper;
import com.fr.design.constants.DesignerLaunchStatus;
import com.fr.design.file.TemplateResourceManager;
import com.fr.design.utils.DesignUtils;
import com.fr.event.Event;
import com.fr.event.EventDispatcher;
import com.fr.event.Listener;
import com.fr.event.Null;
import com.fr.file.TmpFileUtils;
import com.fr.general.CloudCenter;
import com.fr.general.GeneralContext;
import com.fr.module.Activator;
import com.fr.start.common.DesignerStartupPool;
/**
* Created by juhaoyu on 2018/1/8.
*/
public class PreStartActivator extends Activator {
@Override
public void start() {
//清空临时文件
Runtime.getRuntime().addShutdownHook(new Thread(TmpFileUtils::cleanUpInnerTmpFiles));
RestartHelper.deleteRecordFilesWhenStart();
//初始化起始画面放到 SplashContext 里面
//EventDispatcher.fire(ModuleEvent.MajorModuleStarting, Toolkit.i18nText("Fine-Design_Basic_Initializing"));
// 完成初始化
//noinspection ResultOfMethodCallIgnored
CloudCenter.getInstance();
// 创建监听服务
DesignUtils.createListeningServer(DesignUtils.getPort(), startFileSuffix());
// 在插件引擎模块起来前 初始化下插件接口监听
TemplateResourceManager.getResource();
initLanguage();
}
@Override
public void stop() {
// void
}
private void initLanguage() {
//这两句的位置不能随便调换,因为会影响语言切换的问题
GeneralContext.setLocale(DesignerEnvManager.getEnvManager(false).getLanguage());
}
private String[] startFileSuffix() {
return new String[]{".cpt", ".xls", ".xlsx", ".frm", ".form", ".cht", ".chart", ".fvs"};
}
}

36
designer-realize/src/main/java/com/fr/start/module/optimized/BaseDBActivator4Designer.java

@ -1,36 +0,0 @@
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.stable.lifecycle.FineLifecycleFatalError;
import com.fr.start.LifecycleFatalErrorHandler;
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<Null>(Integer.MAX_VALUE) {
@Override
public void on(Event event, Null param) {
try {
BaseDBActivator4Designer.super.start();
} catch (FineLifecycleFatalError error) {
LifecycleFatalErrorHandler.getInstance().handle(error);
}
}
});
} else {
super.start();
}
}
}

23
designer-realize/src/main/java/com/fr/start/module/optimized/ConfigurationActivator4Designer.java

@ -1,23 +0,0 @@
package com.fr.start.module.optimized;
import com.fr.config.activator.ConfigurationActivator;
import com.fr.config.dao.DaoSelectorFactory;
import com.fr.transaction.PropertiesTransactor;
import com.fr.transaction.TransactorFactory;
/**
* @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()) {
TransactorFactory.setTransactor(new PropertiesTransactor());
} else {
super.initLocalDao();
}
}
}

25
designer-realize/src/main/java/com/fr/start/module/optimized/DesignUpdateActivator.java

@ -1,25 +0,0 @@
package com.fr.start.module.optimized;
import com.fr.start.common.DesignerStartupContext;
import com.fr.update.activator.BasicUpdateActivator;
import com.fr.update.base.FineUpdateUnit;
/**
* created by Harrison on 2022/08/11
**/
public class DesignUpdateActivator extends BasicUpdateActivator {
@Override
public void start() {
if (DesignerStartupContext.getInstance().onWarmup()) {
try {
prepare4Start();
FineUpdateUnit.makeNew();
} catch (Throwable ignore) {
}
} else {
super.start();
}
}
}

35
designer-realize/src/main/java/com/fr/start/module/optimized/DesignerPluginActivator.java

@ -1,35 +0,0 @@
package com.fr.start.module.optimized;
import com.fr.module.Activator;
import com.fr.module.ModuleContext;
import com.fr.plugin.manage.PluginManager;
import com.fr.start.common.DesignerStartupExecutor;
import com.fr.workspace.WorkContext;
import com.fr.workspace.WorkspaceSwitchHelper;
import com.fr.workspace.WorkspaceSwitchProcess;
/**
* created by Harrison on 2022/06/22
**/
public class DesignerPluginActivator extends Activator {
@Override
public void start() {
//WorkspaceSwitchProcess process = WorkContext.getSwitcher().getProcess();
//if (WorkspaceSwitchHelper.supportHotSwitch(process)) {
// PluginManager.getHotModule().start();
//} else {
// DesignerStartupExecutor.getInstance().execute(() -> ModuleContext.getModule(PluginActivator.class).start());
//}
}
@Override
public void stop() {
//WorkspaceSwitchProcess process = WorkContext.getSwitcher().getProcess();
//if (WorkspaceSwitchHelper.supportHotSwitch(process)) {
// PluginManager.getHotModule().stop();
//} else {
// ModuleContext.getModule(PluginActivator.class).stop();
//}
}
}

221
designer-realize/src/main/java/com/fr/start/module/optimized/DesignerStartupPageActivator.java

@ -1,221 +0,0 @@
package com.fr.start.module.optimized;
import com.fanruan.boot.key.ActivatorContextGroup;
import com.fanruan.boot.key.StartupArgsShell;
import com.fanruan.carina.Carina;
import com.fr.design.DesignerEnvManager;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.messagecollect.StartErrorMessageCollector;
import com.fr.design.ui.util.UIUtil;
import com.fr.log.FineLoggerFactory;
import com.fr.module.Activator;
import com.fr.module.engine.base.ActivatorContext;
import com.fr.start.SplashContext;
import com.fr.start.common.DesignerStartupContext;
import com.fr.start.module.StartupArgs;
import com.fr.start.preload.PreLoadService;
import com.fr.start.util.DesignerStartupPageUtil;
import com.fr.startup.metric.DesignerMetrics;
import com.fr.startup.metric.DesignerStartupModel;
import com.fr.startup.ui.StartupPageModel;
import com.fr.startup.ui.StartupPageWindow;
import com.fr.startup.ui.StartupWorkspaceBean;
import com.fr.third.org.apache.commons.lang3.time.StopWatch;
import com.fr.value.NotNullLazyValue;
import org.jetbrains.annotations.NotNull;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
/**
* 设计器起始页启动器
* <a href="https://kms.fineres.com/pages/viewpage.action?pageId=416850313">设计文档</a>
*
* created by Harrison on 2022/07/03
**/
public class DesignerStartupPageActivator extends Activator {
private final NotNullLazyValue<StartupArgs> startupArgsValue = new NotNullLazyValue<StartupArgs>() {
@NotNull
@Override
protected StartupArgs compute() {
return Carina.getApplicationContext().singleton(StartupArgsShell.class).get();
}
};
/**
* 上下文
*/
private final ActivatorContext activatorContext = new ActivatorContext();
private final CountDownLatch LATCH = new CountDownLatch(1);
@Override
public void start() {
DesignerStartupContext context = DesignerStartupContext.getInstance();
context.setStartupArgs(startupArgsValue.getValue());
if (context.isShowStartupPage()) {
showDesignerStartupPage(context);
} else {
startNonStartupPage();
}
}
private void startNonStartupPage() {
StopWatch recorder = DesignerStartupContext.getRecorder();
try {
DesignerStartupPageUtil.enterWorkspace();
} catch (Exception e) {
throw new RuntimeException(e);
}
recordStartupEnd(recorder);
}
private void showDesignerStartupPage(DesignerStartupContext context) {
// 启动页关闭
SplashContext.getInstance().hide();
// 即时暂停
suspendRecorder(context);
Carina.getApplicationContext().group(ActivatorContextGroup.class).add(activatorContext);
PreLoadService.getInstance().waitForUI();
UIUtil.invokeLaterIfNeeded(() -> {
StartupPageModel model = StartupPageModel.create();
context.setStartupPageModel(model);
StopWatch suspendWatch = new StopWatch();
final Runnable recordSuspend = () -> {
long suspendTime = suspendWatch.getTime(TimeUnit.MILLISECONDS);
activatorContext.setSuspendTime(suspendTime);
};
// selectAndOpenLast
model.setOpenLastTemplateRunnable(() -> {
recordSuspend.run();
context.setOpenLastFile(true);
handleModel(model);
launchAfterWarmup();
});
// selectAndOpenEmpty
model.setOpenEmptyTemplateRunnable(() -> {
recordSuspend.run();
context.setOpenEmpty(true);
handleModel(model);
launchAfterWarmup();
});
// selectAndCreateNew
model.setCreateNewTemplateRunnable(() -> {
recordSuspend.run();
context.setCreateNew(true);
handleModel(model);
launchAfterWarmup();
});
StartupPageWindow window = new StartupPageWindow(model);
window.setVisible(true);
context.setOnWaiting(true);
suspendWatch.start();
});
waitSubTask();
}
private void suspendRecorder(DesignerStartupContext context) {
DesignerMetrics designerMetrics = context.getDesignerMetrics();
DesignerStartupModel designerStartupModel = designerMetrics.getModel();
StopWatch recorder = DesignerStartupContext.getRecorder();
recorder.suspend();
long time = recorder.getTime(TimeUnit.MILLISECONDS);
designerStartupModel.setLandingTime(time);
}
private void handleModel(StartupPageModel model) {
// 将选中的环境设置为当前环境
StartupWorkspaceBean selectWorkspaceInfo = model.getSelectWorkspaceInfo();
DesignerEnvManager.getEnvManager().setCurEnvName(selectWorkspaceInfo.getName());
UIUtil.invokeLaterIfNeeded(() -> {
DesignerContext.getDesignerFrame().setTitle();
});
}
private void launchAfterWarmup() {
StopWatch stopWatch = StopWatch.createStarted();
try {
StopWatch recorder = DesignerStartupContext.getRecorder();
if (recorder.isSuspended()) {
recorder.resume();
}
// 等待中切换
DesignerStartupContext.getInstance().setOnWaiting(false);
DesignerStartupContext.getInstance().setOnStartup(true);
try {
DesignerStartupPageUtil.enterWorkspace();
} catch (Exception e) {
throw new RuntimeException(e);
}
} finally {
UIUtil.invokeLaterIfNeeded(() -> {
// 换到 awt 线程中关闭,不然异步会出现问题。
DesignerStartupContext.getInstance().setOnStartup(false);
StartErrorMessageCollector.getInstance().setExtraJudgeStart(true);
recordStartupEnd(stopWatch);
});
markComplete();
}
}
private void recordStartupEnd(StopWatch stopWatch) {
DesignerStartupContext context = DesignerStartupContext.getInstance();
DesignerMetrics designerMetrics = context.getDesignerMetrics();
DesignerStartupModel model = designerMetrics.getModel();
model.setStartingTime(stopWatch.getTime(TimeUnit.MILLISECONDS));
model.fill();
}
/**
* 阻塞住当前的方法
* 只有 UI 交互开始执行的时候才会停止阻塞
*/
private void waitSubTask() {
try {
LATCH.await();
} catch (InterruptedException e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
private void markComplete() {
try {
LATCH.countDown();
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
@Override
public void stop() {
}
}

32
designer-realize/src/main/java/com/fr/start/module/optimized/ReportBaseActivator4Designer.java

@ -1,32 +0,0 @@
package com.fr.start.module.optimized;
import com.fr.config.dao.DaoSelectorFactory;
import com.fr.event.Event;
import com.fr.event.Listener;
import com.fr.event.Null;
import com.fr.report.module.ReportBaseActivator;
import com.fr.start.event.LazyStartupEvent;
/**
* @author hades
* @version 11.0
* Created by hades on 2022/3/16
*/
public class ReportBaseActivator4Designer extends ReportBaseActivator {
@Override
protected void vcsInit() {
if (DaoSelectorFactory.getDaoSelector().useCacheDao()) {
listenEvent(LazyStartupEvent.INSTANCE, new Listener<Null>() {
@Override
public void on(Event event, Null param) {
ReportBaseActivator4Designer.super.vcsInit();
}
});
} else {
super.vcsInit();
}
}
}

1
designer-realize/src/test/java/com/fr/design/mainframe/app/DesignerAppUtilsTest.java

@ -1,5 +1,6 @@
package com.fr.design.mainframe.app;
import com.fanruan.boot.env.function.app.DesignerAppUtils;
import com.fr.invoke.Reflect;
import com.fr.plugin.context.PluginMarker;
import com.fr.plugin.context.PluginMarkerAdapter;

50
designer-realize/src/test/java/com/fr/start/module/DesignerWorkspaceProviderTest.java

@ -1,50 +0,0 @@
package com.fr.start.module;
import com.fr.design.constants.DesignerLaunchStatus;
import com.fr.event.EventDispatcher;
import com.fr.invoke.Reflect;
import com.fr.workspace.WorkContext;
import com.fr.workspace.Workspace;
import org.easymock.EasyMock;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.easymock.PowerMock;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
/**
* @author Lucian.Chen
* @version 10.0
* Created by Lucian.Chen on 2021/1/7
*/
@RunWith(PowerMockRunner.class)
@PrepareForTest({WorkContext.class})
public class DesignerWorkspaceProviderTest {
@Test
public void testPluginErrorRemind() {
try {
Workspace workspace = EasyMock.mock(Workspace.class);
EasyMock.expect(workspace.isLocal()).andReturn(false).once();
PowerMock.mockStatic(WorkContext.class);
EasyMock.expect(WorkContext.getCurrent()).andReturn(workspace).anyTimes();
EasyMock.replay(workspace);
PowerMock.replayAll();
DesignerWorkspaceProvider provider = new DesignerWorkspaceProvider();
Reflect.on(provider).call("pluginErrorRemind");
EventDispatcher.fire(DesignerLaunchStatus.STARTUP_COMPLETE);
EasyMock.verify(workspace);
PowerMock.verifyAll();
} catch (Exception e) {
Assert.fail(e.getMessage());
}
}
}
Loading…
Cancel
Save