Browse Source

Pull request #9160: REPORT-70565 设计器环境监测(jar包异常、finedb、杀毒软件)

Merge in DESIGN/design from ~HARRISON/design:feature/x to feature/x

* commit 'f6cf059be1768012a407c0b40f051b711bcd5af2':
  无 JIRA 任务,补充注释
  REPORT-73403【设计器环境监测】jar异常弹窗,%FR_HOME%\lib和\WEB-INF\lib下的jar需要区分显示 处理相关的魔术值
  REPORT-73403【设计器环境监测】jar异常弹窗,%FR_HOME%\lib和\WEB-INF\lib下的jar需要区分显示 抽象一个常量
  无 JIRA 任务,补充注释
  REPORT-73403【设计器环境监测】jar异常弹窗,%FR_HOME%\lib和\WEB-INF\lib下的jar需要区分显示 适配交互的样式
  REPORT-73318【设计器环境监测】服务器finedb有脏数据,设计器远程切换,过程很慢且没有自动监测弹窗 处理切换远程时不生效的逻辑
  REPORT-73396【设计器环境监测】删除fine-decision-11.0,触发的是重置finedb 当遇到 finedb 异常却是缺少 JAR 导致的时候,交互补充处理
  REPORT-73312 【设计器环境监测】远程切换时,fine-report-designer-11.0一定会触发版本不一致的检测  过滤掉 designer
  REPORT-73391【设计器环境监测】缺少fine-activator-11.0,预期外启动的弹窗没有捕获 守护线程的检测逻辑处理。
  REPORT-73331【设计器环境监测】远程环境缺少jar,没有检测到异常 修复远程时,缺少 JAR 的逻辑
  REPORT-73292【设计器环境监测】缺少的jar在版本不一致中也会被检测到 处理不一致的逻辑,之前忘了判空
  REPORT-73335【设计器环境监测】手动检测完成后,交互文字提示丢失 和产品沟通,修复交互逻辑
  REPORT-73262【设计器环境监测】右下角弹窗文字显示不全 测试右下角弹窗文字的展示问题
feature/x
Harrison 3 years ago
parent
commit
6f970323a8
  1. 59
      designer-base/src/main/java/com/fr/design/components/notification/NotificationDialog.java
  2. 18
      designer-base/src/main/java/com/fr/env/detect/EnvDetectorCenter.java
  3. 7
      designer-base/src/main/java/com/fr/env/detect/base/DetectorConstants.java
  4. 42
      designer-base/src/main/java/com/fr/env/detect/base/DetectorUtil.java
  5. 11
      designer-base/src/main/java/com/fr/env/detect/impl/JarInconsistentDetector.java
  6. 84
      designer-base/src/main/java/com/fr/env/detect/impl/JarLackDetector.java
  7. 22
      designer-base/src/main/java/com/fr/env/detect/impl/converter/ClassConflictConvertor.java
  8. 62
      designer-base/src/main/java/com/fr/env/detect/ui/EnvDetectorDialog.java
  9. 2
      designer-base/src/test/java/com/fr/design/components/notification/NotificationDialogTest.java
  10. 18
      designer-realize/src/main/java/com/fr/start/FineDesigner.java
  11. 62
      designer-realize/src/main/java/com/fr/start/LifecycleFatalErrorHandler.java

59
designer-base/src/main/java/com/fr/design/components/notification/NotificationDialog.java

@ -32,6 +32,7 @@ import java.awt.event.MouseEvent;
import java.net.URI; import java.net.URI;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.function.Function;
import java.util.function.Supplier; import java.util.function.Supplier;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -43,8 +44,31 @@ import java.util.stream.Collectors;
**/ **/
public class NotificationDialog extends JDialog { public class NotificationDialog extends JDialog {
private Dimension contentSize = new Dimension(300, 100); /**
private Dimension buttonDimension = new Dimension(68, 20); * 通知框的内部高度
*/
private static final int CONTENT_INNER_HEIGHT = 60;
/**
* 通知框如果出现滚动条后的内部宽度
*/
private static final int CONTENT_SCROLL_WIDTH = 280;
private static final int CONTENT_WIDTH = 300;
private static final int CONTENT_HEIGHT = 100;
/**
* 通知框的外部宽高
*/
private static final Dimension CONTENT_SIZE = new Dimension(CONTENT_WIDTH, CONTENT_HEIGHT);
private static final Dimension BUTTON_DIMENSION = new Dimension(68, 20);
/**
* 标记 LABEL 没有作用
*/
private static final UILabel SIGN_LABEL = new UILabel("#");
/**
* 确认一个 LABEL 的宽高
*/
private static final Dimension SIGN_LABEL_DIMENSION = SIGN_LABEL.getPreferredSize();
private NotificationDialogProperties properties; private NotificationDialogProperties properties;
@ -151,15 +175,30 @@ public class NotificationDialog extends JDialog {
} }
return new UILabel(LinkStrUtils.generateHtmlTag(messageModel.format())); return new UILabel(LinkStrUtils.generateHtmlTag(messageModel.format()));
}) })
.collect(Collectors.toList());
// 当高度 大于 60 时,就会出现滚动条。
// 当出现滚动条时,需要将内部的宽度限制为 280, 否则会展示不出来
Function<Double, Integer> calStandardWidth = height -> height > CONTENT_INNER_HEIGHT ? CONTENT_SCROLL_WIDTH : CONTENT_WIDTH;
int widthUnit = messageComponents.stream()
.map((component) -> {
Dimension preferredSize = component.getPreferredSize();
return preferredSize.getHeight();
})
.reduce(Double::sum)
.map(calStandardWidth)
.orElse(CONTENT_WIDTH);
messageComponents = messageComponents.stream()
.peek((component) -> { .peek((component) -> {
Dimension preferredSize = component.getPreferredSize(); Dimension preferredSize = component.getPreferredSize();
double componentWidth = preferredSize.getWidth(); double componentWidth = preferredSize.getWidth();
double componentHeight = preferredSize.getHeight(); double componentHeight = preferredSize.getHeight();
double widthFactor = Math.ceil(componentWidth / 300); double heightFactor = Math.ceil(componentHeight / SIGN_LABEL_DIMENSION.getHeight());
double heightFactor = Math.ceil(componentHeight / 15); double widthFactor = Math.ceil(componentWidth / widthUnit);
int realHeight = (int) (heightFactor + widthFactor - 1) * 15; int realHeight = (int)Math.ceil(heightFactor + widthFactor - 1) * (int)(Math.ceil(SIGN_LABEL_DIMENSION.getHeight()));
component.setPreferredSize(new Dimension(300, realHeight)); component.setPreferredSize(new Dimension(widthUnit, realHeight));
}) })
.collect(Collectors.toList()); .collect(Collectors.toList());
@ -171,7 +210,7 @@ public class NotificationDialog extends JDialog {
jScrollPane.setBorder(BorderFactory.createEmptyBorder()); jScrollPane.setBorder(BorderFactory.createEmptyBorder());
centerPanel.add(jScrollPane, BorderLayout.CENTER); centerPanel.add(jScrollPane, BorderLayout.CENTER);
centerPanel.setPreferredSize(contentSize); centerPanel.setPreferredSize(CONTENT_SIZE);
contentPanel.add(centerPanel, BorderLayout.CENTER); contentPanel.add(centerPanel, BorderLayout.CENTER);
@ -240,7 +279,7 @@ public class NotificationDialog extends JDialog {
NotificationAction action = currentModel.getAction(); NotificationAction action = currentModel.getAction();
if (action != null) { if (action != null) {
UIButton actionButton = new UIButton(action.name()); UIButton actionButton = new UIButton(action.name());
actionButton.setPreferredSize(buttonDimension); actionButton.setPreferredSize(BUTTON_DIMENSION);
actionButton.addActionListener(new ActionListener() { actionButton.addActionListener(new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
@ -251,7 +290,7 @@ public class NotificationDialog extends JDialog {
} }
UIButton knowButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Know")); UIButton knowButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Know"));
knowButton.setPreferredSize(buttonDimension); knowButton.setPreferredSize(BUTTON_DIMENSION);
knowButton.addActionListener(new ActionListener() { knowButton.addActionListener(new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {

18
designer-base/src/main/java/com/fr/env/detect/EnvDetectorCenter.java vendored

@ -18,6 +18,7 @@ import com.fr.event.EventDispatcher;
import com.fr.event.Listener; import com.fr.event.Listener;
import com.fr.event.Null; import com.fr.event.Null;
import com.fr.start.server.EmbedServerEvent; import com.fr.start.server.EmbedServerEvent;
import com.fr.task.Once;
import com.fr.update.delay.DelayHelper; import com.fr.update.delay.DelayHelper;
import com.fr.workspace.Workspace; import com.fr.workspace.Workspace;
import com.fr.workspace.WorkspaceEvent; import com.fr.workspace.WorkspaceEvent;
@ -72,6 +73,14 @@ public class EnvDetectorCenter {
} }
}; };
private final Once launchOnce = new Once(() -> {
// 添加启动完成监听
EventDispatcher.listen(DesignerLaunchStatus.STARTUP_COMPLETE, START_UP_COMPLETE_LISTENER);
// 切换完成后的监听
EventDispatcher.listen(WorkspaceEvent.AfterSwitch, AFTER_SWITCH_LISTENER);
});
private final AtomicReference<DetectorProcess> PROCESS = new AtomicReference<>(); private final AtomicReference<DetectorProcess> PROCESS = new AtomicReference<>();
public static EnvDetectorCenter getInstance() { public static EnvDetectorCenter getInstance() {
@ -96,6 +105,7 @@ public class EnvDetectorCenter {
// 默认是启动 // 默认是启动
PROCESS.set(DetectorProcess.DESIGN_LAUNCH); PROCESS.set(DetectorProcess.DESIGN_LAUNCH);
launchOnce.run();
listen(); listen();
} }
@ -189,12 +199,6 @@ public class EnvDetectorCenter {
private void listen() { private void listen() {
// 添加启动完成监听
EventDispatcher.listen(DesignerLaunchStatus.STARTUP_COMPLETE, START_UP_COMPLETE_LISTENER);
// 切换完成后的监听
EventDispatcher.listen(WorkspaceEvent.AfterSwitch, AFTER_SWITCH_LISTENER);
// 内置服务器监听 // 内置服务器监听
EventDispatcher.listen(EmbedServerEvent.BeforeStart, BEFORE_START_LISTENER); EventDispatcher.listen(EmbedServerEvent.BeforeStart, BEFORE_START_LISTENER);
EventDispatcher.listen(EmbedServerEvent.AfterStart, AFTER_START_LISTENER); EventDispatcher.listen(EmbedServerEvent.AfterStart, AFTER_START_LISTENER);
@ -202,8 +206,6 @@ public class EnvDetectorCenter {
private void stopListen() { private void stopListen() {
EventDispatcher.stopListen(START_UP_COMPLETE_LISTENER);
EventDispatcher.stopListen(AFTER_SWITCH_LISTENER);
EventDispatcher.stopListen(BEFORE_START_LISTENER); EventDispatcher.stopListen(BEFORE_START_LISTENER);
EventDispatcher.stopListen(AFTER_START_LISTENER); EventDispatcher.stopListen(AFTER_START_LISTENER);
} }

7
designer-base/src/main/java/com/fr/env/detect/base/DetectorConstants.java vendored

@ -8,4 +8,11 @@ public class DetectorConstants {
public static final String JAR_HELP_LINK = "https://help.fanruan.com/finereport/doc-view-4700.html?source=3"; public static final String JAR_HELP_LINK = "https://help.fanruan.com/finereport/doc-view-4700.html?source=3";
public static final String FINE_DB_HELP_LINK = "https://help.fanruan.com/finereport/doc-view-4701.html?source=3"; public static final String FINE_DB_HELP_LINK = "https://help.fanruan.com/finereport/doc-view-4701.html?source=3";
public static final String SEPARATOR = "、";
public static final String BR_TAG = "<br/>";
public static final String WEB_LIB_PATH = "%FR_HOME%\\webapps\\webroot\\WEB-INF\\lib:";
public static final String FR_HOME_LIB = "%FR_HOME%\\lib:";
} }

42
designer-base/src/main/java/com/fr/env/detect/base/DetectorUtil.java vendored

@ -1,6 +1,7 @@
package com.fr.env.detect.base; package com.fr.env.detect.base;
import com.fr.base.function.ThrowableRunnable; import com.fr.base.function.ThrowableRunnable;
import com.fr.common.util.Collections;
import com.fr.design.components.notification.NotificationAction; import com.fr.design.components.notification.NotificationAction;
import com.fr.design.components.notification.NotificationMessage; import com.fr.design.components.notification.NotificationMessage;
import com.fr.design.components.notification.NotificationModel; import com.fr.design.components.notification.NotificationModel;
@ -14,7 +15,7 @@ import com.fr.env.detect.bean.ExceptionTips;
import com.fr.env.detect.bean.Message; import com.fr.env.detect.bean.Message;
import com.fr.env.detect.bean.SolutionAction; import com.fr.env.detect.bean.SolutionAction;
import com.fr.general.build.BuildInfo; import com.fr.general.build.BuildInfo;
import com.fr.stable.StringUtils; import com.fr.third.org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import javax.swing.JComponent; import javax.swing.JComponent;
@ -22,9 +23,15 @@ import java.awt.Desktop;
import java.net.URI; import java.net.URI;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.function.Function; import java.util.function.Function;
import static com.fr.env.detect.base.DetectorConstants.BR_TAG;
import static com.fr.env.detect.base.DetectorConstants.FR_HOME_LIB;
import static com.fr.env.detect.base.DetectorConstants.SEPARATOR;
import static com.fr.env.detect.base.DetectorConstants.WEB_LIB_PATH;
/** /**
* created by Harrison on 2022/05/25 * created by Harrison on 2022/05/25
**/ **/
@ -124,4 +131,37 @@ public class DetectorUtil {
} }
return new UILabel(LinkStrUtils.generateHtmlTag(message.get())); return new UILabel(LinkStrUtils.generateHtmlTag(message.get()));
} }
/**
* lib 转化成合适的格式
* %FR_HOME%/lib
* %FR_HOME%/webapps/webroot/WEB-INF/lib
*
* @param libMap jar 路径, key为前缀
* @return 信息
*/
public static String concatLibFormatMsg(Map<String, List<String>> libMap) {
String webLibPath = WEB_LIB_PATH;
String homeLibPath = FR_HOME_LIB;
StringBuilder sb = new StringBuilder();
List<String> homeLibs = libMap.get(homeLibPath);
if (!Collections.isEmpty(homeLibs)) {
sb.append(homeLibPath);
sb.append(StringUtils.join(homeLibs, SEPARATOR));
}
List<String> webLibs = libMap.get(webLibPath);
if (!Collections.isEmpty(webLibs)) {
if (sb.length() != 0) {
sb.append(BR_TAG);
}
sb.append(webLibPath);
sb.append(StringUtils.join(webLibs, SEPARATOR));
}
return sb.toString();
}
} }

11
designer-base/src/main/java/com/fr/env/detect/impl/JarInconsistentDetector.java vendored

@ -114,7 +114,11 @@ public class JarInconsistentDetector extends AbstractExceptionDetector {
// 获取所有的不一致的 build // 获取所有的不一致的 build
List<BuildInfo> inConsistentInfos = buildInfos.stream() List<BuildInfo> inConsistentInfos = buildInfos.stream()
.filter((e) -> !StringUtils.equals(designerBuild.get(), e.getGroupBuild())) .filter((e) -> {
// 不为空,且不相等
return StringUtils.isNotEmpty(e.getGroupBuild())
&& !StringUtils.equals(designerBuild.get(), e.getGroupBuild());
})
.collect(Collectors.toList()); .collect(Collectors.toList());
// 没有直接返回 // 没有直接返回
@ -141,7 +145,10 @@ public class JarInconsistentDetector extends AbstractExceptionDetector {
for (BuildInfo localInfo : localInfos) { for (BuildInfo localInfo : localInfos) {
String jar = localInfo.getJar(); String jar = localInfo.getJar();
String groupContent = localInfo.getGroupBuild(); String groupContent = localInfo.getGroupBuild();
localMap.put(jar, groupContent); // 不一致的 JAR 检测,忽视缺少的情况
if (StringUtils.isNotEmpty(groupContent)) {
localMap.put(jar, groupContent);
}
} }
return localMap; return localMap;
} }

84
designer-base/src/main/java/com/fr/env/detect/impl/JarLackDetector.java vendored

@ -12,6 +12,7 @@ import com.fr.env.detect.bean.ExceptionSolution;
import com.fr.env.detect.bean.ExceptionTips; import com.fr.env.detect.bean.ExceptionTips;
import com.fr.env.detect.bean.Message; import com.fr.env.detect.bean.Message;
import com.fr.general.build.BuildInfo; import com.fr.general.build.BuildInfo;
import com.fr.general.build.BuildInfoManager;
import com.fr.general.build.BuildInfoOperator; import com.fr.general.build.BuildInfoOperator;
import com.fr.general.build.impl.BuildInfoOperatorImpl; import com.fr.general.build.impl.BuildInfoOperatorImpl;
import com.fr.third.guava.collect.Lists; import com.fr.third.guava.collect.Lists;
@ -22,18 +23,18 @@ import org.jetbrains.annotations.NotNull;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static com.fr.env.detect.base.DetectorConstants.FR_HOME_LIB;
import static com.fr.env.detect.base.DetectorConstants.WEB_LIB_PATH;
/** /**
* created by Harrison on 2022/05/24 * created by Harrison on 2022/05/24
**/ **/
public class JarLackDetector extends AbstractExceptionDetector { public class JarLackDetector extends AbstractExceptionDetector {
public static final String SEPARATOR = "、";
public static final String BR_TAG = "<br/>";
public static final String WEB_LIB_PATH = "%FR_HOME%\\webapps\\webroot\\WEB-INF\\lib:";
public static final String FR_HOME_LIB = "%FR_HOME%\\lib:";
public JarLackDetector() { public JarLackDetector() {
super(DetectorType.LACK_OF_JAR); super(DetectorType.LACK_OF_JAR);
@ -42,18 +43,41 @@ public class JarLackDetector extends AbstractExceptionDetector {
@Override @Override
public DetectorResult detect() { public DetectorResult detect() {
// 不支持远程 List<BuildInfo> lackInfos;
// 远程
if (!WorkContext.getCurrent().isLocal()) { if (!WorkContext.getCurrent().isLocal()) {
return DetectorResult.normal(type()); // 检测有哪些 JAR 包, 当前是否缺少对应的 JAR 包
BuildInfoOperator buildInfoOperator = WorkContext.getCurrent().get(BuildInfoOperator.class);
// 远程情况
List<BuildInfo> remoteInfos = buildInfoOperator.getBuildInfos();
// 本地情况
List<BuildInfo> localInfos = BuildInfoManager.getInstance().getInfos();
Set<String> remoteSet = remoteInfos.stream()
.filter(this::isExistInfo)
.map(BuildInfo::getJar)
.collect(Collectors.toSet());
Predicate<BuildInfo> remoteNotContains = (e) -> !remoteSet.contains(e.getJar());
lackInfos = localInfos.stream()
.filter(this::isExistInfo)
// 不是设计器的 JAR
.filter((e) -> !DetectorUtil.isDesignerJar(e))
.filter(remoteNotContains)
.collect(Collectors.toList());
} else {
// 本地
// 检测有哪些 JAR 包, 当前是否缺少对应的 JAR 包
BuildInfoOperator buildInfoOperator = new BuildInfoOperatorImpl();
List<BuildInfo> buildInfos = buildInfoOperator.getBuildInfos();
lackInfos = buildInfos.stream()
.filter(this::isLackInfo)
.collect(Collectors.toList());
} }
// 检测有哪些 JAR 包, 当前是否缺少对应的 JAR 包
BuildInfoOperator buildInfoOperator = new BuildInfoOperatorImpl();
List<BuildInfo> buildInfos = buildInfoOperator.getBuildInfos();
List<BuildInfo> lackInfos = buildInfos.stream()
.filter(this::isLackInfo)
.collect(Collectors.toList());
if (Collections.isEmpty(lackInfos)) { if (Collections.isEmpty(lackInfos)) {
return DetectorResult.normal(type()); return DetectorResult.normal(type());
} }
@ -77,6 +101,11 @@ public class JarLackDetector extends AbstractExceptionDetector {
return ExceptionLog.create(Toolkit.i18nText(type().getLogLocale()) + message); return ExceptionLog.create(Toolkit.i18nText(type().getLogLocale()) + message);
} }
private boolean isExistInfo(BuildInfo e) {
return !isLackInfo(e);
}
private boolean isLackInfo(BuildInfo e) { private boolean isLackInfo(BuildInfo e) {
return StringUtils.isEmpty(e.getGroupBuild()); return StringUtils.isEmpty(e.getGroupBuild());
@ -84,33 +113,12 @@ public class JarLackDetector extends AbstractExceptionDetector {
private Message tipsMessage(List<BuildInfo> infos) { private Message tipsMessage(List<BuildInfo> infos) {
String webLibPath = WEB_LIB_PATH; Map<String, List<String>> libMap = groupByPath(infos, FR_HOME_LIB, WEB_LIB_PATH);
String homeLibPath = FR_HOME_LIB;
Map<String, List<String>> libMap = groupByPath(infos, homeLibPath, webLibPath);
StringBuilder sb = new StringBuilder();
List<String> homeLibs = libMap.get(homeLibPath);
if (!Collections.isEmpty(homeLibs)) {
sb.append(homeLibPath);
sb.append(StringUtils.join(homeLibs, SEPARATOR));
}
List<String> webLibs = libMap.get(webLibPath);
if (!Collections.isEmpty(webLibs)) {
if (sb.length() != 0) {
sb.append(BR_TAG);
}
sb.append(webLibPath);
sb.append(StringUtils.join(webLibs, SEPARATOR));
}
String mainContent = sb.toString();
String content = DetectorUtil.concatLibFormatMsg(libMap);
DetectorType type = this.type(); DetectorType type = this.type();
String header = Toolkit.i18nText(type.getTipsLocale()); String header = Toolkit.i18nText(type.getTipsLocale());
return new Message.Simple(header + mainContent); return new Message.Simple(header + content);
} }
@NotNull @NotNull

22
designer-base/src/main/java/com/fr/env/detect/impl/converter/ClassConflictConvertor.java vendored

@ -2,6 +2,7 @@ package com.fr.env.detect.impl.converter;
import com.fr.design.i18n.Toolkit; import com.fr.design.i18n.Toolkit;
import com.fr.env.detect.base.DetectorConstants; import com.fr.env.detect.base.DetectorConstants;
import com.fr.env.detect.base.DetectorUtil;
import com.fr.env.detect.bean.DetectorResult; import com.fr.env.detect.bean.DetectorResult;
import com.fr.env.detect.bean.DetectorType; import com.fr.env.detect.bean.DetectorType;
import com.fr.env.detect.bean.ExceptionLog; import com.fr.env.detect.bean.ExceptionLog;
@ -9,7 +10,6 @@ import com.fr.env.detect.bean.ExceptionSolution;
import com.fr.env.detect.bean.ExceptionTips; import com.fr.env.detect.bean.ExceptionTips;
import com.fr.env.detect.thowable.ThrowableConverter; import com.fr.env.detect.thowable.ThrowableConverter;
import com.fr.stable.resource.ResourceLoader; import com.fr.stable.resource.ResourceLoader;
import com.fr.third.org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import javax.el.MethodNotFoundException; import javax.el.MethodNotFoundException;
@ -41,6 +41,8 @@ public class ClassConflictConvertor implements ThrowableConverter {
*/ */
private static final Pattern JAR_NAME_PATTERN = Pattern.compile("([\\w+-\\.]*\\.jar)"); private static final Pattern JAR_NAME_PATTERN = Pattern.compile("([\\w+-\\.]*\\.jar)");
private static final String WEB_INF_STRING = "WEB-INF";
private final Map<Class<?>, ClassNameConverter> throwableMap = new HashMap<>(); private final Map<Class<?>, ClassNameConverter> throwableMap = new HashMap<>();
public ClassConflictConvertor() { public ClassConflictConvertor() {
@ -83,6 +85,10 @@ public class ClassConflictConvertor implements ThrowableConverter {
sign = sign.getCause(); sign = sign.getCause();
} }
Map<String, List<String>> libMap = new HashMap<>();
libMap.put(DetectorConstants.FR_HOME_LIB, new ArrayList<>());
libMap.put(DetectorConstants.WEB_LIB_PATH, new ArrayList<>());
Set<String> allPath = new HashSet<>(); Set<String> allPath = new HashSet<>();
for (String className : classNames) { for (String className : classNames) {
String classFile = convertClass2Path(className); String classFile = convertClass2Path(className);
@ -98,12 +104,14 @@ public class ClassConflictConvertor implements ThrowableConverter {
Matcher matcher = JAR_NAME_PATTERN.matcher(url.getFile()); Matcher matcher = JAR_NAME_PATTERN.matcher(url.getFile());
if (matcher.find()) { if (matcher.find()) {
String jar = matcher.group(); String jar = matcher.group();
allPath.add(jar); List<String> libPath = null;
} else { if (file.contains(WEB_INF_STRING)) {
boolean containsClasses = file.contains(CLASSES); libPath = libMap.get(DetectorConstants.WEB_LIB_PATH);
if (containsClasses) { } else {
allPath.add(CLASSES); libPath = libMap.get(DetectorConstants.FR_HOME_LIB);
} }
libPath.add(jar);
allPath.add(jar);
} }
} }
} catch (IOException ignore) { } catch (IOException ignore) {
@ -115,7 +123,7 @@ public class ClassConflictConvertor implements ThrowableConverter {
return null; return null;
} }
String msg = StringUtils.join(allPath, SEPARATOR); String msg = DetectorUtil.concatLibFormatMsg(libMap);
DetectorType type = DetectorType.JAR_CONFLICT; DetectorType type = DetectorType.JAR_CONFLICT;
return DetectorResult.exception(type, return DetectorResult.exception(type,

62
designer-base/src/main/java/com/fr/env/detect/ui/EnvDetectorDialog.java vendored

@ -54,9 +54,11 @@ public class EnvDetectorDialog extends JDialog {
private static final ImageIcon LOADING_ICON = getLoadingIcon(); private static final ImageIcon LOADING_ICON = getLoadingIcon();
public static final int TIMEOUT = 1000; public static final int TIMEOUT = 1000;
private JPanel body; private final JPanel body;
private final JPanel headerPanel; private final JPanel headerPanel;
private UIButton detectButton;
private JPanel resultSummaryPane;
private final TablePanel tablePanel; private final TablePanel tablePanel;
@ -128,7 +130,7 @@ public class EnvDetectorDialog extends JDialog {
JPanel headerPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); JPanel headerPanel = FRGUIPaneFactory.createBorderLayout_S_Pane();
headerPanel.setBorder(BorderFactory.createEmptyBorder(5, 0, 12, 0)); headerPanel.setBorder(BorderFactory.createEmptyBorder(5, 0, 12, 0));
UIButton detectButton = new UIButton(buttonStatus.getDesc()) { this.detectButton = new UIButton(buttonStatus.getDesc()) {
@Override @Override
public ButtonUI getUI() { public ButtonUI getUI() {
@ -152,7 +154,7 @@ public class EnvDetectorDialog extends JDialog {
detectButton.setForeground(Color.WHITE); detectButton.setForeground(Color.WHITE);
detectButton.addActionListener(event -> { detectButton.addActionListener(event -> {
if (buttonStatus.isNotExecuting()) { if (buttonStatus.isNotExecuting()) {
startDetecting(detectButton); startDetecting();
} else { } else {
stopDetecting(detectButton); stopDetecting(detectButton);
} }
@ -165,7 +167,7 @@ public class EnvDetectorDialog extends JDialog {
return headerPanel; return headerPanel;
} }
private void startDetecting(UIButton detectButton) { private void startDetecting() {
// 重新检测的时候需要处理一些逻辑 // 重新检测的时候需要处理一些逻辑
if (buttonStatus == EnvDetectorButtonStatus.A_NEW) { if (buttonStatus == EnvDetectorButtonStatus.A_NEW) {
@ -173,7 +175,7 @@ public class EnvDetectorDialog extends JDialog {
} }
// 执行前 // 执行前
buttonStatus = buttonStatus.next(); buttonStatus = buttonStatus.next();
UIUtil.invokeLaterIfNeeded(() -> detectButton.setText(buttonStatus.getDesc())); UIUtil.invokeLaterIfNeeded(EnvDetectorDialog.this::refreshHeaderPanel);
detectWorker = new SwingWorker<Void, Void>() { detectWorker = new SwingWorker<Void, Void>() {
@Override @Override
@ -218,7 +220,7 @@ public class EnvDetectorDialog extends JDialog {
if (buttonStatus.isExecuting()) { if (buttonStatus.isExecuting()) {
// 执行结束 // 执行结束
buttonStatus = EnvDetectorButtonStatus.A_NEW; buttonStatus = EnvDetectorButtonStatus.A_NEW;
UIUtil.invokeLaterIfNeeded(() -> detectButton.setText(buttonStatus.getDesc())); UIUtil.invokeLaterIfNeeded(EnvDetectorDialog.this::refreshHeaderPanel);
} }
} }
}; };
@ -251,6 +253,42 @@ public class EnvDetectorDialog extends JDialog {
}); });
} }
private void updateHeaderPanel() {
// 刷新按钮
detectButton.setText(buttonStatus.getDesc());
if (buttonStatus == EnvDetectorButtonStatus.A_NEW) {
this.resultSummaryPane = new JPanel();
this.resultSummaryPane.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 0));
this.resultSummaryPane.setLayout(new BorderLayout(5, 0));
Boolean success = model.getResults()
.map((e) -> {
if (e.getStatus() == DetectorStatus.NORMAL) {
return Boolean.TRUE;
}
return Boolean.FALSE;
}).reduce((a, b) -> a && b)
.orElse(Boolean.FALSE);
if (success) {
resultSummaryPane.add(new UILabel(Toolkit.i18nText("Fine-Design_Basic_Detect_Result_Label")), BorderLayout.WEST);
UILabel successLabel = new UILabel(Toolkit.i18nText("Fine-Design_Basic_Detect_Result_Success"));
successLabel.setForeground(Color.GREEN);
resultSummaryPane.add(successLabel, BorderLayout.CENTER);
} else {
resultSummaryPane.add(new UILabel(Toolkit.i18nText("Fine-Design_Basic_Exception")), BorderLayout.WEST);
UILabel resultLabel = new UILabel(Toolkit.i18nText("Fine-Design_Basic_Detect_Result_Error"));
resultLabel.setForeground(Color.RED);
resultSummaryPane.add(resultLabel, BorderLayout.CENTER);
}
this.headerPanel.add(BorderLayout.CENTER, resultSummaryPane);
} else {
if (resultSummaryPane != null) {
this.headerPanel.remove(resultSummaryPane);
}
}
}
/* table */ /* table */
@ -394,6 +432,13 @@ public class EnvDetectorDialog extends JDialog {
return tailPanel; return tailPanel;
} }
private void refreshHeaderPanel() {
updateHeaderPanel();
pack();
repaint();
}
private void refresh() { private void refresh() {
updateTable(this.tablePanel); updateTable(this.tablePanel);
@ -504,4 +549,9 @@ public class EnvDetectorDialog extends JDialog {
public abstract EnvDetectorButtonStatus next(); public abstract EnvDetectorButtonStatus next();
} }
private class EnvDetectorHeaderPanel extends JPanel {
}
} }

2
designer-base/src/test/java/com/fr/design/components/notification/NotificationDialogTest.java

@ -31,7 +31,7 @@ public class NotificationDialogTest {
public void run(Object... args) { public void run(Object... args) {
System.out.println("1111"); System.out.println("1111");
} }
}, new NotificationMessage.LinkMessage("1111 2222 33333333 4444 555 6666 66555 888 999 333 <br/> 3333", ""),new NotificationMessage.LinkMessage("display <a href='#'>model2</a> test", "abc")); }, new NotificationMessage.LinkMessage("1111 2222 33333333 4444 555 6666 66555 888 999 333 <br/> 3333 <br /> 444 <br/> 555 <br/>", ""),new NotificationMessage.LinkMessage("display <a href='#'>model2</a> test", "abc"));
NotificationDialogProperties properties = new NotificationDialogProperties(frame, "test"); NotificationDialogProperties properties = new NotificationDialogProperties(frame, "test");
NotificationDialog dialog = new NotificationDialog(properties, Lists.newArrayList(model1, model2)); NotificationDialog dialog = new NotificationDialog(properties, Lists.newArrayList(model1, model2));

18
designer-realize/src/main/java/com/fr/start/FineDesigner.java

@ -1,5 +1,7 @@
package com.fr.start; package com.fr.start;
import com.fr.exit.DesignerExiter;
import com.fr.process.engine.FineProcessUtils;
import com.fr.process.engine.core.FineProcessEntry; import com.fr.process.engine.core.FineProcessEntry;
/** /**
@ -11,4 +13,20 @@ import com.fr.process.engine.core.FineProcessEntry;
*/ */
public class FineDesigner extends FineProcessEntry { public class FineDesigner extends FineProcessEntry {
public static void main(String[] args) {
FineDesigner fineDesigner = new FineDesigner();
FineProcessUtils.run(fineDesigner, args);
}
@Override
public void run(String[] args) {
try {
super.run(args);
} catch (Throwable throwable) {
// 守护进程启动时,需要捕获异常。并且退出。
DesignerExiter.getInstance().exit(throwable);
}
}
} }

62
designer-realize/src/main/java/com/fr/start/LifecycleFatalErrorHandler.java

@ -1,15 +1,19 @@
package com.fr.start; package com.fr.start;
import com.fr.common.report.ReportState; import com.fr.common.report.ReportState;
import com.fr.common.util.Collections;
import com.fr.design.RestartHelper; import com.fr.design.RestartHelper;
import com.fr.design.dialog.FineJOptionPane; import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.i18n.Toolkit; import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.DesignerFrame;
import com.fr.design.mainframe.messagecollect.StartErrorMessageCollector; import com.fr.design.mainframe.messagecollect.StartErrorMessageCollector;
import com.fr.design.mainframe.messagecollect.entity.DesignerErrorMessage; import com.fr.design.mainframe.messagecollect.entity.DesignerErrorMessage;
import com.fr.env.detect.base.DetectorBridge; import com.fr.env.detect.base.DetectorBridge;
import com.fr.env.detect.bean.DetectorResult; import com.fr.env.detect.bean.DetectorResult;
import com.fr.env.detect.bean.DetectorStatus; import com.fr.env.detect.bean.DetectorStatus;
import com.fr.env.detect.bean.DetectorType; import com.fr.env.detect.bean.DetectorType;
import com.fr.env.detect.ui.DetectorErrorDialog;
import com.fr.exit.DesignerExiter; import com.fr.exit.DesignerExiter;
import com.fr.general.IOUtils; import com.fr.general.IOUtils;
import com.fr.io.utils.ResourceIOUtils; import com.fr.io.utils.ResourceIOUtils;
@ -17,14 +21,19 @@ import com.fr.log.FineLoggerFactory;
import com.fr.process.engine.core.CarryMessageEvent; import com.fr.process.engine.core.CarryMessageEvent;
import com.fr.process.engine.core.FineProcessContext; import com.fr.process.engine.core.FineProcessContext;
import com.fr.stable.StableUtils; import com.fr.stable.StableUtils;
import com.fr.stable.StringUtils;
import com.fr.stable.lifecycle.ErrorType; import com.fr.stable.lifecycle.ErrorType;
import com.fr.stable.lifecycle.ErrorTypeHelper; import com.fr.stable.lifecycle.ErrorTypeHelper;
import com.fr.stable.lifecycle.FineLifecycleFatalError; import com.fr.stable.lifecycle.FineLifecycleFatalError;
import com.fr.stable.project.ProjectConstants; import com.fr.stable.project.ProjectConstants;
import javax.swing.JOptionPane; import javax.swing.JOptionPane;
import java.util.EnumMap;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/** /**
* @author hades * @author hades
@ -68,10 +77,30 @@ public class LifecycleFatalErrorHandler {
* 自检测 * 自检测
*/ */
SELF { SELF {
final EnumMap<DetectorType, String> solutionMap = new EnumMap<>(DetectorType.class);
{
solutionMap.put(DetectorType.FINE_DB_LOCKED, "Fine-Design_Error_Finedb_Dirty_Backup_Reset");
solutionMap.put(DetectorType.FINE_DB_PERMISSION, "Fine-Design_Error_Finedb_Permission_Backup_Reset");
solutionMap.put(DetectorType.FINE_DB_DIRTY, "Fine-Design_Error_Finedb_Dirty_Backup_Reset");
}
@Override @Override
public void handle(FineLifecycleFatalError fatal) { public void handle(FineLifecycleFatalError fatal) {
String showText = generateShowText(fatal); Stream<DetectorResult> resultStream = DetectorBridge.getInstance().detect(fatal);
List<DetectorResult> results = resultStream
.filter((e) -> e.getStatus() == DetectorStatus.EXCEPTION)
.collect(Collectors.toList());
String showText = generateShowText(results);
// 如果还是异常,说明并不是 DB 的异常,抛出预期外的错误
if (StringUtils.isEmpty(showText)) {
DesignerFrame designerFrame = DesignerContext.getDesignerFrame();
DetectorErrorDialog errorDialog = new DetectorErrorDialog(designerFrame, results);
errorDialog.setVisible(true);
return;
}
StartErrorMessageCollector.getInstance().record(DesignerErrorMessage.FINEDB_PROBLEM.getId(), StartErrorMessageCollector.getInstance().record(DesignerErrorMessage.FINEDB_PROBLEM.getId(),
DesignerErrorMessage.FINEDB_PROBLEM.getMessage(), DesignerErrorMessage.FINEDB_PROBLEM.getMessage(),
@ -107,26 +136,23 @@ public class LifecycleFatalErrorHandler {
/** /**
* 生成展示信息 * 生成展示信息
*
* @param fatal 异常
* @return 文本
*/ */
private String generateShowText(FineLifecycleFatalError fatal) { private String generateShowText(List<DetectorResult> results) {
// todo 其实这里的交互还是有问题, 为什么在锁住和没权限的场景下,要重置 FineDB 呢。 String showText = StringUtils.EMPTY;
DetectorResult detectorResult = DetectorBridge.getInstance().detect(DetectorType.FINE_DB_LOCKED, fatal); if (Collections.isEmpty(results)) {
if (detectorResult.getStatus() == DetectorStatus.EXCEPTION) { showText = Toolkit.i18nText("Fine-Design_Error_Finedb_Backup_Reset");
return Toolkit.i18nText("Fine-Design_Error_Finedb_Locked_Backup_Reset"); } else {
} for (DetectorResult result : results) {
detectorResult = DetectorBridge.getInstance().detect(DetectorType.FINE_DB_PERMISSION, fatal); DetectorType type = result.getType();
if (detectorResult.getStatus() == DetectorStatus.EXCEPTION) { String solutionLocale = solutionMap.get(type);
return Toolkit.i18nText("Fine-Design_Error_Finedb_Permission_Backup_Reset"); if (StringUtils.isNotEmpty(solutionLocale)) {
} showText = Toolkit.i18nText(solutionLocale);
detectorResult = DetectorBridge.getInstance().detect(DetectorType.FINE_DB_DIRTY, fatal); break;
if (detectorResult.getStatus() == DetectorStatus.EXCEPTION) { }
return Toolkit.i18nText("Fine-Design_Error_Finedb_Dirty_Backup_Reset"); }
} }
return Toolkit.i18nText("Fine-Design_Error_Finedb_Backup_Reset"); return showText;
} }
private void afterBackupFailed() { private void afterBackupFailed() {

Loading…
Cancel
Save