Browse Source

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

1-补充设定,针对某一项的某一个异常进行检测
2-所有的日志,在检测后,统一输出,避免遗忘
3-优化一下代码质量
4-补充 UI 部分 - 异常展示
5-补充 UI 部分 - 检测 model
feature/x
Harrison 3 years ago
parent
commit
0b02d73eb8
  1. 172
      designer-base/src/main/java/com/fr/env/detect/EnvDetectorCenter.java
  2. 2
      designer-base/src/main/java/com/fr/env/detect/base/CatchExceptionDetector.java
  3. 27
      designer-base/src/main/java/com/fr/env/detect/base/DetectorBridge.java
  4. 4
      designer-base/src/main/java/com/fr/env/detect/base/DetectorManager.java
  5. 83
      designer-base/src/main/java/com/fr/env/detect/base/DetectorUtil.java
  6. 23
      designer-base/src/main/java/com/fr/env/detect/base/ExceptionDetectorConfig.java
  7. 4
      designer-base/src/main/java/com/fr/env/detect/bean/DetectorResult.java
  8. 5
      designer-base/src/main/java/com/fr/env/detect/bean/ExceptionSolution.java
  9. 5
      designer-base/src/main/java/com/fr/env/detect/bean/ExceptionTips.java
  10. 26
      designer-base/src/main/java/com/fr/env/detect/exception/DetectorException.java
  11. 4
      designer-base/src/main/java/com/fr/env/detect/exception/intelli/package-info.java
  12. 4
      designer-base/src/main/java/com/fr/env/detect/impl/JarConflictDetector.java
  13. 75
      designer-base/src/main/java/com/fr/env/detect/impl/JarInconsistentDetector.java
  14. 8
      designer-base/src/main/java/com/fr/env/detect/impl/JarLackDetector.java
  15. 30
      designer-base/src/main/java/com/fr/env/detect/impl/converter/ClassConflictConvertor.java
  16. 27
      designer-base/src/main/java/com/fr/env/detect/impl/converter/FineDbDirtyConverter.java
  17. 2
      designer-base/src/main/java/com/fr/env/detect/impl/converter/FineDbLockedConverter.java
  18. 3
      designer-base/src/main/java/com/fr/env/detect/impl/converter/FineDbPermissionConverter.java
  19. 135
      designer-base/src/main/java/com/fr/env/detect/ui/DetectorErrorDialog.java
  20. 235
      designer-base/src/main/java/com/fr/env/detect/ui/EnvDetectorDialog.java
  21. 38
      designer-base/src/main/java/com/fr/env/detect/ui/EnvDetectorItem.java
  22. 59
      designer-base/src/main/java/com/fr/env/detect/ui/EnvDetectorModel.java

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

@ -0,0 +1,172 @@
package com.fr.env.detect;
import com.fr.design.components.notification.NotificationDialog;
import com.fr.design.components.notification.NotificationDialogProperties;
import com.fr.design.components.notification.NotificationModel;
import com.fr.design.constants.DesignerLaunchStatus;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.ui.util.UIUtil;
import com.fr.env.detect.base.DetectorBridge;
import com.fr.env.detect.base.DetectorUtil;
import com.fr.env.detect.bean.DetectorResult;
import com.fr.env.detect.bean.DetectorStatus;
import com.fr.event.Event;
import com.fr.event.EventDispatcher;
import com.fr.event.Listener;
import com.fr.event.Null;
import com.fr.start.server.EmbedServerEvent;
import com.fr.update.delay.DelayHelper;
import com.fr.workspace.Workspace;
import com.fr.workspace.WorkspaceEvent;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* created by Harrison on 2022/05/27
**/
public class EnvDetectorCenter {
public static EnvDetectorCenter getInstance() {
return EnvDetectorCenterHolder.INSTANCE;
}
private static class EnvDetectorCenterHolder {
private static final EnvDetectorCenter INSTANCE = new EnvDetectorCenter();
}
private final AtomicReference<DetectorProcess> PROCESS = new AtomicReference<>();
public void init() {
// 默认是启动
PROCESS.set(DetectorProcess.DESIGN_LAUNCH);
start();
// 添加启动完成监听
EventDispatcher.listen(DesignerLaunchStatus.STARTUP_COMPLETE, new Listener<Null>() {
@Override
public void on(Event event, Null param) {
if (isSameProcess(DetectorProcess.DESIGN_LAUNCH)) {
stop();
}
}
});
// 切换工作目录
EventDispatcher.listen(WorkspaceEvent.BeforeSwitch, new Listener<Workspace>() {
@Override
public void on(Event event, Workspace param) {
PROCESS.set(DetectorProcess.ENV_SWITCH);
start();
}
});
EventDispatcher.listen(WorkspaceEvent.AfterSwitch, new Listener<Workspace>() {
@Override
public void on(Event event, Workspace param) {
if (isSameProcess(DetectorProcess.ENV_SWITCH)) {
stop();
}
}
});
// 打开内置服务器
EventDispatcher.listen(EmbedServerEvent.BeforeStart, new Listener<Null>() {
@Override
public void on(Event event, Null param) {
PROCESS.set(DetectorProcess.SERVER_LAUNCH);
start();
}
});
EventDispatcher.listen(EmbedServerEvent.AfterStart, new Listener<Null>() {
@Override
public void on(Event event, Null param) {
if (isSameProcess(DetectorProcess.SERVER_LAUNCH)) {
stop();
}
}
});
}
/**
* 当前的流程符合预期
* 什么情况下不符合
* design.start -> server.start -> design.end -> server.end
* 这个时候 design.end 就不会触发等待服务器启动后才触发
*
* @param process 检测流程
* @return /
*/
private boolean isSameProcess(DetectorProcess process) {
return PROCESS.compareAndSet(process, null);
}
public void start() {
DetectorBridge.getInstance().start();
}
public void stop() {
Stream<DetectorResult> resultStream = DetectorBridge.getInstance().detect();
// 展示效果
NotificationDialogProperties properties = new NotificationDialogProperties(DesignerContext.getDesignerFrame(), Toolkit.i18nText("Fine-Design_Basic_Detect_Notification_Title"));
List<NotificationModel> notificationModels = resultStream
.filter(Objects::nonNull)
.filter((e) -> e.getStatus() == DetectorStatus.EXCEPTION)
.map(DetectorUtil::convert2Notification)
.collect(Collectors.toList());
// 一分钟后执行
DelayHelper.delayCall(EnvDetectorCenter.class.getName(), () -> {
UIUtil.invokeLaterIfNeeded(() -> {
NotificationDialog dialog = new NotificationDialog(properties, notificationModels);
dialog.open();
});
}, 1, TimeUnit.MINUTES);
// 结束
DetectorBridge.getInstance().stop();
}
/**
* 使用预期外的错误进行展示
*
* @param throwable 异常
* @return
*/
public List<DetectorResult> terminate(Throwable throwable) {
Stream<DetectorResult> resultStream = DetectorBridge.getInstance().detect(throwable);
List<DetectorResult> results = resultStream
.filter((e) -> e.getStatus() == DetectorStatus.EXCEPTION)
.collect(Collectors.toList());
return results;
}
private enum DetectorProcess {
/**
* 设计器启动
*/
DESIGN_LAUNCH,
/**
* 服务器启动
*/
SERVER_LAUNCH,
/**
* 环境切换
*/
ENV_SWITCH
}
}

2
designer-base/src/main/java/com/fr/env/detect/base/CatchExceptionDetector.java vendored

@ -50,6 +50,6 @@ public abstract class CatchExceptionDetector extends AbstractExceptionDetector {
return result;
}
}
return null;
return DetectorResult.normal(type());
}
}

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

@ -13,7 +13,6 @@ import com.fr.env.detect.thowable.ThrowableStore;
import com.fr.value.NotNullLazyValue;
import org.jetbrains.annotations.NotNull;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Stream;
@ -54,7 +53,7 @@ public class DetectorBridge {
public void start() {
if (ExceptionDetectorConfig.getInstance().isOpen()) {
if (!hasStarted.get() && ExceptionDetectorConfig.getInstance().isOpen()) {
// 开始注册异常处理
ThrowableLogAppender.getInstance().enable();
hasStarted.set(true);
@ -76,11 +75,33 @@ public class DetectorBridge {
* @param type 检测类型
* @return 检测结果
*/
public Optional<DetectorResult> detect(DetectorType type) {
@NotNull
public DetectorResult detect(DetectorType type) {
return detectorManager.getValue().detect(type);
}
/**
* 针对某一项 \ 某一个异常进行检测
*
* @param type 类型
* @param throwable 异常
* @return 结果
*/
@NotNull
public DetectorResult detect(DetectorType type, Throwable throwable) {
// 先清理一下
ThrowableStore.getInstance().reset();
ThrowableStore.getInstance().add(throwable);
DetectorResult result = detect(type);
ThrowableStore.getInstance().reset();
return result;
}
/**
* 异常检测
* 对异常统一检测

4
designer-base/src/main/java/com/fr/env/detect/base/DetectorManager.java vendored

@ -34,7 +34,7 @@ class DetectorManager {
return results;
}
public Optional<DetectorResult> detect(DetectorType type) {
public DetectorResult detect(DetectorType type) {
Optional<DetectorResult> result = detectors.stream()
.filter((detector -> type == detector.type()))
@ -44,6 +44,6 @@ class DetectorManager {
// 记录日志
result.ifPresent(DetectorResult::log);
return result;
return result.orElse(DetectorResult.normal(type));
}
}

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

@ -1,7 +1,28 @@
package com.fr.env.detect.base;
import com.fr.base.function.ThrowableRunnable;
import com.fr.design.components.notification.NotificationAction;
import com.fr.design.components.notification.NotificationMessage;
import com.fr.design.components.notification.NotificationModel;
import com.fr.design.components.notification.NotificationType;
import com.fr.design.dialog.link.MessageWithLink;
import com.fr.design.gui.ilable.UILabel;
import com.fr.env.detect.bean.DetectorResult;
import com.fr.env.detect.bean.ExceptionSolution;
import com.fr.env.detect.bean.ExceptionTips;
import com.fr.env.detect.bean.Message;
import com.fr.env.detect.bean.SolutionAction;
import com.fr.general.build.BuildInfo;
import com.fr.stable.StringUtils;
import org.jetbrains.annotations.NotNull;
import javax.swing.JComponent;
import java.awt.Desktop;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.function.Function;
/**
* created by Harrison on 2022/05/25
@ -13,4 +34,66 @@ public class DetectorUtil {
return StringUtils.contains(info.getJar(), "fine-report-designer");
}
public static NotificationModel convert2Notification(DetectorResult result) {
List<NotificationMessage> messages = new ArrayList<>();
Function<Message, Optional<NotificationMessage>> convert2NotificationMsg = message -> {
NotificationMessage notificationMessage = null;
if (message != null) {
Message.Type type = message.getType();
switch (type) {
case SIMPLE:
notificationMessage = (new NotificationMessage.SimpleMessage(message.get()));
break;
case LINK:
Message.Link linkMsg = (Message.Link) message;
notificationMessage = new NotificationMessage.LinkMessage(linkMsg.getText(), linkMsg.getLink());
break;
default:
break;
}
}
return Optional.ofNullable(notificationMessage);
};
ExceptionTips tips = result.getTips();
convert2NotificationMsg
.apply(tips.getMessage())
.ifPresent(messages::add);
ExceptionSolution solution = result.getSolution();
convert2NotificationMsg.apply(solution.getMessage())
.ifPresent(messages::add);
NotificationAction notificationAction = null;
SolutionAction solutionAction = solution.getAction();
if (solutionAction != null) {
notificationAction = new NotificationAction() {
@Override
public String name() {
return solutionAction.name();
}
@Override
public void run(Object... args) {
solutionAction.run();
}
};
}
return new NotificationModel(NotificationType.WARNING, notificationAction, messages);
}
public static JComponent convert2Component(@NotNull Message message) {
if (message.getType() == Message.Type.LINK) {
Message.Link linkMsg = (Message.Link) message;
return new MessageWithLink(linkMsg.getText(), ThrowableRunnable.toRunnable(() -> {
Desktop.getDesktop().browse(URI.create(linkMsg.getLink()));
}));
}
return new UILabel(message.get());
}
}

23
designer-base/src/main/java/com/fr/env/detect/base/ExceptionDetectorConfig.java vendored

@ -1,21 +1,34 @@
package com.fr.env.detect.base;
import com.fr.config.ConfigContext;
import com.fr.config.DefaultConfiguration;
import com.fr.config.holder.Conf;
import com.fr.config.holder.factory.Holders;
/**
* created by Harrison on 2022/05/13
**/
public class ExceptionDetectorConfig {
public class ExceptionDetectorConfig extends DefaultConfiguration {
private static volatile ExceptionDetectorConfig instance = null;
public static ExceptionDetectorConfig getInstance() {
return ExceptionDetectorConfigHolder.INSTANCE;
if (instance == null) {
instance = ConfigContext.getConfigInstance(ExceptionDetectorConfig.class);
}
return instance;
}
private static class ExceptionDetectorConfigHolder {
private static final ExceptionDetectorConfig INSTANCE = new ExceptionDetectorConfig();
private final Conf<Boolean> open = Holders.simple(true);
public void setOpen(boolean open) {
this.open.set(open);
}
public boolean isOpen() {
return true;
return open.get();
}
}

4
designer-base/src/main/java/com/fr/env/detect/bean/DetectorResult.java vendored

@ -1,5 +1,7 @@
package com.fr.env.detect.bean;
import org.jetbrains.annotations.Nullable;
/**
* 检测结果
*
@ -51,10 +53,12 @@ public class DetectorResult {
return type;
}
@Nullable
public ExceptionTips getTips() {
return tips;
}
@Nullable
public ExceptionSolution getSolution() {
return solution;
}

5
designer-base/src/main/java/com/fr/env/detect/bean/ExceptionSolution.java vendored

@ -12,6 +12,11 @@ public class ExceptionSolution {
@Nullable
private SolutionAction action;
public static ExceptionSolution create(String text, String link, SolutionAction action) {
return new ExceptionSolution(new Message.Link(text, link), action);
}
public ExceptionSolution(Message message, @Nullable SolutionAction action) {
this.message = message;
this.action = action;

5
designer-base/src/main/java/com/fr/env/detect/bean/ExceptionTips.java vendored

@ -9,6 +9,11 @@ public class ExceptionTips {
private Message message;
public static ExceptionTips create(String text) {
return new ExceptionTips(new Message.Simple(text));
}
public ExceptionTips(Message message) {
this.message = message;
}

26
designer-base/src/main/java/com/fr/env/detect/exception/DetectorException.java vendored

@ -1,26 +0,0 @@
package com.fr.env.detect.exception;
/**
* created by Harrison on 2022/05/25
**/
public class DetectorException extends RuntimeException {
public DetectorException() {
}
public DetectorException(String message) {
super(message);
}
public DetectorException(String message, Throwable cause) {
super(message, cause);
}
public DetectorException(Throwable cause) {
super(cause);
}
public DetectorException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}

4
designer-base/src/main/java/com/fr/env/detect/exception/intelli/package-info.java vendored

@ -1,4 +0,0 @@
/**
* 国际化相关的异常
*/
package com.fr.env.detect.exception.intelli;

4
designer-base/src/main/java/com/fr/env/detect/impl/JarConflictDetector.java vendored

@ -2,7 +2,7 @@ package com.fr.env.detect.impl;
import com.fr.env.detect.base.CatchExceptionDetector;
import com.fr.env.detect.bean.DetectorType;
import com.fr.env.detect.impl.converter.ClassConfictConvertor;
import com.fr.env.detect.impl.converter.ClassConflictConvertor;
/**
* created by Harrison on 2022/05/26
@ -10,6 +10,6 @@ import com.fr.env.detect.impl.converter.ClassConfictConvertor;
public class JarConflictDetector extends CatchExceptionDetector {
public JarConflictDetector() {
super(DetectorType.JAR_CONFLICT, new ClassConfictConvertor());
super(DetectorType.JAR_CONFLICT, new ClassConflictConvertor());
}
}

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

@ -19,6 +19,7 @@ import com.fr.third.guava.collect.MapDifference;
import com.fr.third.guava.collect.Maps;
import com.fr.third.org.apache.commons.lang3.StringUtils;
import com.fr.workspace.WorkContext;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
import java.util.List;
@ -50,6 +51,48 @@ public class JarInconsistentDetector extends AbstractExceptionDetector {
public DetectorResult detect() {
if (WorkContext.getCurrent().isLocal()) {
return detectLocal();
} else {
return detectLocalAndRemote();
}
}
@NotNull
private DetectorResult detectLocalAndRemote() {
// 检测有哪些 JAR 包, 当前是否缺少对应的 JAR 包
BuildInfoOperator buildInfoOperator = WorkContext.getCurrent().get(BuildInfoOperator.class);
List<BuildInfo> buildInfos = buildInfoOperator.getBuildInfos();
// 远程情况
List<BuildInfo> localInfos = BuildInfoManager.getInstance().getInfos();
Map<String, String> localMap = groupBy(localInfos);
List<BuildInfo> remoteInfos = buildInfos;
Map<String, String> remoteMap = groupBy(remoteInfos);
MapDifference<String, String> difference = Maps.difference(localMap, remoteMap);
Map<String, String> diffInCommon = difference.entriesInCommon();
if (diffInCommon.isEmpty()) {
return DetectorResult.normal(type());
}
Set<String> inConsistentJars = diffInCommon.keySet();
String message = StringUtils.join(",", inConsistentJars);
Message.Simple tipsMessage = new Message.Simple(Toolkit.i18nText("Fine_Design_Basic_Detect_Server") + Toolkit.i18nText(type().getTipsLocale()) + "\n" + message);
return DetectorResult.exception(type(),
new ExceptionTips(tipsMessage),
new ExceptionSolution(new Message.Link(Toolkit.i18nText(type().getSolutionLocale(),DetectorConstants.JAR_HELP_LINK)
, DetectorConstants.JAR_HELP_LINK), null),
ExceptionLog.create(type().getLogLocale() + message));
}
@NotNull
private DetectorResult detectLocal() {
// 本地的获取方式
BuildInfoOperator operator = new BuildInfoOperatorImpl();
@ -88,38 +131,6 @@ public class JarInconsistentDetector extends AbstractExceptionDetector {
new ExceptionTips(new Message.Simple(tipsMessage)),
new ExceptionSolution(new Message.Link(Toolkit.i18nText(type().getSolutionLocale()), DetectorConstants.JAR_HELP_LINK), null),
ExceptionLog.create(type().getLogLocale() + message));
} else {
// 检测有哪些 JAR 包, 当前是否缺少对应的 JAR 包
BuildInfoOperator buildInfoOperator = WorkContext.getCurrent().get(BuildInfoOperator.class);
List<BuildInfo> buildInfos = buildInfoOperator.getBuildInfos();
// 远程情况
List<BuildInfo> localInfos = BuildInfoManager.getInstance().getInfos();
Map<String, String> localMap = groupBy(localInfos);
List<BuildInfo> remoteInfos = buildInfos;
Map<String, String> remoteMap = groupBy(remoteInfos);
MapDifference<String, String> difference = Maps.difference(localMap, remoteMap);
Map<String, String> diffInCommon = difference.entriesInCommon();
if (diffInCommon.isEmpty()) {
return DetectorResult.normal(type());
}
Set<String> inConsistentJars = diffInCommon.keySet();
String message = StringUtils.join(",", inConsistentJars);
Message.Simple tipsMessage = new Message.Simple(Toolkit.i18nText("Fine_Design_Basic_Detect_Server") + Toolkit.i18nText(type().getTipsLocale()) + "\n" + message);
return DetectorResult.exception(type(),
new ExceptionTips(tipsMessage),
new ExceptionSolution(new Message.Link(Toolkit.i18nText(type().getSolutionLocale()), DetectorConstants.JAR_HELP_LINK), null),
ExceptionLog.create(type().getLogLocale() + message));
}
}
private Map<String, String> groupBy(List<BuildInfo> localInfos) {

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

@ -15,14 +15,11 @@ import com.fr.general.build.BuildInfo;
import com.fr.general.build.BuildInfoOperator;
import com.fr.general.build.impl.BuildInfoOperatorImpl;
import com.fr.locale.InterProviderFactory;
import com.fr.stable.CommonUtils;
import com.fr.stable.StableUtils;
import com.fr.third.guava.collect.Lists;
import com.fr.third.org.apache.commons.lang3.StringUtils;
import com.fr.workspace.WorkContext;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -81,9 +78,8 @@ public class JarLackDetector extends AbstractExceptionDetector {
private Message tipsMessage(List<BuildInfo> infos) {
String installHome = StableUtils.getInstallHome();
String homeLibPath = installHome + File.pathSeparator + "lib";
String webLibPath = CommonUtils.join(new String[]{installHome, "webapps", "webroot", "WEB-INF", "lib"}, File.pathSeparator);
String webLibPath = "%FR_HOME%\\webapps\\webroot\\WEB-INF\\lib:";
String homeLibPath = "%FR_HOME%\\lib:";
Map<String, List<String>> libMap = groupByPath(infos, homeLibPath, webLibPath);

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

@ -1,6 +1,13 @@
package com.fr.env.detect.impl.converter;
import com.fr.common.util.Strings;
import com.fr.design.i18n.Toolkit;
import com.fr.env.detect.base.DetectorConstants;
import com.fr.env.detect.bean.DetectorResult;
import com.fr.env.detect.bean.DetectorType;
import com.fr.env.detect.bean.ExceptionLog;
import com.fr.env.detect.bean.ExceptionSolution;
import com.fr.env.detect.bean.ExceptionTips;
import com.fr.env.detect.thowable.ThrowableConverter;
import com.fr.stable.resource.ResourceLoader;
@ -24,13 +31,16 @@ import java.util.regex.Pattern;
*
* created by Harrison on 2022/05/24
**/
public class ClassConfictConvertor implements ThrowableConverter {
public class ClassConflictConvertor implements ThrowableConverter {
private Map<Class<?>, ClassNameConverter> throwableMap = new HashMap<>();
private static final Pattern JAR_PATTERN = Pattern.compile("([\\w+-\\.]*\\.jar)");
/**
* 获取对应的 JAR 包名称
*/
private static final Pattern JAR_NAME_PATTERN = Pattern.compile("([\\w+-\\.]*\\.jar)");
public ClassConfictConvertor() {
public ClassConflictConvertor() {
// 类异常
this.throwableMap.put(ClassNotFoundException.class, Converter.CLASS);
@ -70,6 +80,7 @@ public class ClassConfictConvertor implements ThrowableConverter {
sign = sign.getCause();
}
Set<String> allPath = new HashSet<>();
for (String className : classNames) {
String classFile = "/" + className.replaceAll("\\.", "/") + ".class";
try {
@ -79,10 +90,9 @@ public class ClassConfictConvertor implements ThrowableConverter {
URL url = urls.nextElement();
urlList.add(url);
}
Set<String> allPath = new HashSet<>();
for (URL url : urlList) {
String file = url.getFile();
Matcher matcher = JAR_PATTERN.matcher(url.getFile());
Matcher matcher = JAR_NAME_PATTERN.matcher(url.getFile());
if (matcher.find()) {
String jar = matcher.group();
allPath.add(jar);
@ -93,11 +103,17 @@ public class ClassConfictConvertor implements ThrowableConverter {
}
}
}
} catch (IOException ignore) {
}
}
return null;
String msg = Strings.join("、", allPath);
DetectorType type = DetectorType.JAR_CONFLICT;
return DetectorResult.exception(type,
ExceptionTips.create(Toolkit.i18nText(type.getTipsLocale()) + msg),
ExceptionSolution.create(Toolkit.i18nText(type.getSolutionLocale()), DetectorConstants.JAR_HELP_LINK, null),
ExceptionLog.create(Toolkit.i18nText(type.getLogLocale()), msg));
}
private interface ClassNameConverter {

27
designer-base/src/main/java/com/fr/env/detect/impl/converter/FineDbDirtyConverter.java vendored

@ -2,6 +2,7 @@ package com.fr.env.detect.impl.converter;
import com.fr.config.ConfigContext;
import com.fr.config.Configuration;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.i18n.Toolkit;
import com.fr.env.detect.base.DetectorConstants;
import com.fr.env.detect.bean.DetectorResult;
@ -10,9 +11,14 @@ import com.fr.env.detect.bean.ExceptionSolution;
import com.fr.env.detect.bean.Message;
import com.fr.env.detect.bean.SolutionAction;
import com.fr.env.detect.thowable.ThrowableConverter;
import com.fr.io.utils.ResourceIOUtils;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.StableUtils;
import com.fr.stable.project.ProjectConstants;
import com.fr.third.org.hibernate.exception.GenericJDBCException;
import org.jetbrains.annotations.Nullable;
import javax.swing.JOptionPane;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
@ -68,16 +74,29 @@ public class FineDbDirtyConverter implements ThrowableConverter {
String tipsLocale = Toolkit.i18nText(detectorType.getTipsLocale(), tableName);
String solutionLocale = detectorType.getSolutionLocale();
ExceptionSolution exceptionSolution = new ExceptionSolution(new Message.Link(solutionLocale, DetectorConstants.FINE_DB_HELP_LINK), new SolutionAction() {
ExceptionSolution exceptionSolution = new ExceptionSolution(new Message.Link(Toolkit.i18nText(solutionLocale, DetectorConstants.FINE_DB_HELP_LINK), DetectorConstants.FINE_DB_HELP_LINK), new SolutionAction() {
@Override
public String name() {
// todo
return null;
return Toolkit.i18nText("Fine-Design_Basic_Reset_Immediately");
}
@Override
public void run() {
boolean success = false;
try {
ResourceIOUtils.copy(StableUtils.pathJoin(ProjectConstants.EMBED_DB_DIRECTORY, ProjectConstants.FINE_DB_NAME),
StableUtils.pathJoin(ProjectConstants.EMBED_DB_DIRECTORY, ProjectConstants.FINE_DB_BAK_NAME));
success = ResourceIOUtils.delete(StableUtils.pathJoin(ProjectConstants.EMBED_DB_DIRECTORY, ProjectConstants.FINE_DB_NAME));
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
if (!success) {
FineJOptionPane.showMessageDialog(null,
Toolkit.i18nText("Fine-Design_Error_Finedb_Backup_Reset_Result",
ResourceIOUtils.getRealPath(StableUtils.pathJoin(ProjectConstants.EMBED_DB_DIRECTORY, ProjectConstants.FINE_DB_NAME))),
Toolkit.i18nText("Fine-Design_Basic_Error"),
JOptionPane.ERROR_MESSAGE);
}
}
});
builder.withTips(tipsLocale)

2
designer-base/src/main/java/com/fr/env/detect/impl/converter/FineDbLockedConverter.java vendored

@ -47,7 +47,7 @@ public class FineDbLockedConverter implements ThrowableConverter {
return DetectorResult.builder()
.withType(type)
.withTips(Toolkit.i18nText(type.getTipsLocale()))
.withSolution(Toolkit.i18nText(type.getSolutionLocale()), DetectorConstants.FINE_DB_HELP_LINK)
.withSolution(Toolkit.i18nText(type.getSolutionLocale(),DetectorConstants.FINE_DB_HELP_LINK), DetectorConstants.FINE_DB_HELP_LINK)
.withLog(Toolkit.i18nText(type.getLogLocale()))
.build();
}

3
designer-base/src/main/java/com/fr/env/detect/impl/converter/FineDbPermissionConverter.java vendored

@ -42,7 +42,8 @@ public class FineDbPermissionConverter implements ThrowableConverter {
return DetectorResult.builder()
.withType(type)
.withTips(Toolkit.i18nText(type.getTipsLocale()))
.withSolution(Toolkit.i18nText(type.getSolutionLocale()), DetectorConstants.FINE_DB_HELP_LINK)
.withSolution(Toolkit.i18nText(type.getSolutionLocale(), DetectorConstants.FINE_DB_HELP_LINK),
DetectorConstants.FINE_DB_HELP_LINK)
.withLog(type.getLogLocale())
.build();
}

135
designer-base/src/main/java/com/fr/env/detect/ui/DetectorErrorDialog.java vendored

@ -0,0 +1,135 @@
package com.fr.env.detect.ui;
import com.fr.design.RestartHelper;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.VerticalFlowLayout;
import com.fr.design.utils.ColorUtils;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.env.detect.base.DetectorUtil;
import com.fr.env.detect.bean.DetectorResult;
import com.fr.env.detect.bean.ExceptionSolution;
import com.fr.env.detect.bean.ExceptionTips;
import com.fr.env.detect.bean.Message;
import com.fr.exit.DesignerExiter;
import com.fr.general.FRFont;
import javax.swing.BorderFactory;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ScrollPaneConstants;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;
/**
* 未知错误框
* todo 其实这里可以将多个 error-dialog 抽象在一起的 时间不够 简单写写
*
* created by Harrison on 2022/05/29
**/
public class DetectorErrorDialog extends JDialog implements ActionListener {
private UIButton okButton;
private UIButton restartButton;
public DetectorErrorDialog(Frame parent, List<DetectorResult> results) {
super(parent, true);
JPanel northPane = FRGUIPaneFactory.createBorderLayout_L_Pane();
JPanel messagePane = FRGUIPaneFactory.createVerticalFlowLayout_S_Pane(true);
UILabel boldHeader = new UILabel(Toolkit.i18nText("Fine-Design_Error_Start_Apology_Message"));
Font font = FRFont.getInstance(boldHeader.getFont().getFontName(), Font.BOLD, 20);
boldHeader.setFont(font);
messagePane.add(boldHeader);
UILabel description = new UILabel(Toolkit.i18nText("Fine-Design_Send_Report_To_Us"));
messagePane.add(description);
northPane.add(messagePane);
JPanel centerPane = FRGUIPaneFactory.createBorderLayout_L_Pane();
UILabel detailDesc = new UILabel(Toolkit.i18nText("Fine-Design_Problem_Detail_Message"));
centerPane.add(detailDesc, BorderLayout.NORTH);
JPanel detailPanel = FRGUIPaneFactory.createVerticalFlowLayout_Pane(true, VerticalFlowLayout.TOP, 0, 10);
detailPanel.setBorder(BorderFactory.createEmptyBorder(0, 20, 10, 10));
for (DetectorResult result : results) {
ExceptionTips tips = result.getTips();
if (tips != null) {
Message tipsMsg = tips.getMessage();
detailPanel.add(DetectorUtil.convert2Component(tipsMsg));
}
ExceptionSolution solution = result.getSolution();
if (solution != null) {
Message solutionMsg = solution.getMessage();
detailPanel.add(DetectorUtil.convert2Component(solutionMsg));
}
}
JScrollPane detailPanelWrapper = new JScrollPane(detailPanel, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
ColorUtils.syncBackground(detailPanelWrapper, Color.WHITE);
centerPane.add(detailPanelWrapper, BorderLayout.CENTER);
JPanel southPane = FRGUIPaneFactory.createBorderLayout_L_Pane();
JPanel controlPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
JPanel buttonPane = new JPanel(new FlowLayout(FlowLayout.RIGHT, 10, 0));
okButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Ok"));
okButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
okEvent();
}
});
buttonPane.add(okButton);
restartButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Restart"));
restartButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
restartEvent();
}
});
buttonPane.add(restartButton);
controlPane.add(buttonPane, BorderLayout.EAST);
southPane.add(controlPane);
this.setTitle(Toolkit.i18nText("Fine-Design_Error_Start_Report"));
this.setResizable(false);
this.add(northPane, BorderLayout.NORTH);
this.add(centerPane, BorderLayout.CENTER);
this.add(southPane, BorderLayout.SOUTH);
this.setSize(new Dimension(600, 500));
GUICoreUtils.centerWindow(this);
}
@Override
public void actionPerformed(ActionEvent e) {
dispose();
}
protected void okEvent() {
dispose();
DesignerExiter.getInstance().execute();
}
protected void restartEvent() {
dispose();
RestartHelper.restart();
}
}

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

@ -1,12 +1,9 @@
package com.fr.env.detect.ui;
import com.fr.base.svg.IconUtils;
import com.fr.design.components.notification.NotificationAction;
import com.fr.design.components.notification.NotificationDialog;
import com.fr.design.components.notification.NotificationDialogProperties;
import com.fr.design.components.notification.NotificationMessage;
import com.fr.design.components.notification.NotificationModel;
import com.fr.design.components.notification.NotificationType;
import com.fr.design.components.table.TablePanel;
import com.fr.design.constants.DesignerColor;
import com.fr.design.gui.ibutton.UIButton;
@ -19,14 +16,11 @@ import com.fr.design.ui.util.UIUtil;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.design.utils.gui.GUIPaintUtils;
import com.fr.env.detect.base.DetectorBridge;
import com.fr.env.detect.base.DetectorUtil;
import com.fr.env.detect.base.ExceptionDetectorConfig;
import com.fr.env.detect.bean.DetectorResult;
import com.fr.env.detect.bean.DetectorStatus;
import com.fr.env.detect.bean.DetectorType;
import com.fr.env.detect.bean.ExceptionSolution;
import com.fr.env.detect.bean.ExceptionTips;
import com.fr.env.detect.bean.Message;
import com.fr.env.detect.bean.SolutionAction;
import com.fr.third.guava.collect.Lists;
import org.jetbrains.annotations.NotNull;
import javax.swing.BorderFactory;
@ -45,15 +39,10 @@ import java.awt.Image;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@ -63,6 +52,7 @@ import java.util.stream.Stream;
public class EnvDetectorDialog extends JDialog {
private static final ImageIcon LOADING_ICON = getLoadingIcon();
public static final int TIMEOUT = 1000;
private JPanel body;
@ -74,7 +64,7 @@ public class EnvDetectorDialog extends JDialog {
/* 数据 model */
private EnvDetectorModel model = new EnvDetectorModel();
private EnvDetectorModel model;
/* 流程 model */
@ -87,11 +77,25 @@ public class EnvDetectorDialog extends JDialog {
private SwingWorker<Void, Void> detectWorker = null;
/* config model */
private boolean detectOpen = ExceptionDetectorConfig.getInstance().isOpen();
public EnvDetectorDialog(Frame owner) {
this(owner, null);
}
public EnvDetectorDialog(Frame owner, EnvDetectorModel model) {
super(owner);
configProperties();
if (model == null) {
this.model = new EnvDetectorModel();
} else {
this.model = model;
}
this.body = FRGUIPaneFactory.createBorderLayout_L_Pane();
Color backgroundColor = new Color(240, 240, 243, 1);
this.body.setBackground( backgroundColor);
@ -117,6 +121,8 @@ public class EnvDetectorDialog extends JDialog {
GUICoreUtils.centerWindow(this);
}
/* header */
@NotNull
private JPanel createHeaderPanel() {
@ -184,12 +190,13 @@ public class EnvDetectorDialog extends JDialog {
DetectorType type = item.getType();
// 执行检测, UI-当前在检测中
Optional<DetectorResult> detect = UIUtil.waitUntil(
DetectorResult result = UIUtil.waitUntil(
() -> DetectorBridge.getInstance().detect(type),
1000, TimeUnit.MILLISECONDS);
// 获取结果,更新UI
detect.ifPresent(item::setResult);
TIMEOUT, TimeUnit.MILLISECONDS);
// 获取结果
item.setResult(result);
// 更新UI
// 只有还在运行中,才会真正的刷新面板
if (buttonStatus.isExecuting()) {
// 在刷新一下面板
@ -231,6 +238,8 @@ public class EnvDetectorDialog extends JDialog {
});
}
/* table */
@NotNull
private TablePanel createTablePanel() {
@ -285,19 +294,6 @@ public class EnvDetectorDialog extends JDialog {
}
}
private static ImageIcon getLoadingIcon() {
URL resource = EnvDetectorDialog.class.getResource("/com/fr/design/standard/loading/loading-120.gif");
if (resource == null) {
return null;
}
ImageIcon loadingIcon = new ImageIcon(resource);
int width = 16;
int height = 16;
loadingIcon.setImage(loadingIcon.getImage().getScaledInstance(width, height, Image.SCALE_DEFAULT));
return loadingIcon;
}
private Component createResultComponent(DetectorResult result) {
JPanel statusPanel = FRGUIPaneFactory.createBorderLayout_S_Pane();
@ -305,8 +301,16 @@ public class EnvDetectorDialog extends JDialog {
statusPanel.add(new UILabel(IconUtils.readIcon("/com/fr/design/standard/reminder/reminder_success.svg")), BorderLayout.WEST);
statusPanel.add(new UILabel(Toolkit.i18nText("Fine-Design_Basic_Normal")), BorderLayout.CENTER);
} else {
statusPanel.add(new UILabel(IconUtils.readIcon("/com/fr/design/standard/reminder/reminder_error.svg")), BorderLayout.WEST);
statusPanel.add(new UILabel(Toolkit.i18nText("Fine-Design_Basic_Exception")), BorderLayout.CENTER);
JPanel infoPanel = FRGUIPaneFactory.createBorderLayout_S_Pane();
{
infoPanel.add(new UILabel(IconUtils.readIcon("/com/fr/design/standard/reminder/reminder_error.svg")), BorderLayout.WEST);
infoPanel.add(new UILabel(Toolkit.i18nText("Fine-Design_Basic_Exception")), BorderLayout.CENTER);
}
statusPanel.add(infoPanel, BorderLayout.WEST);
JPanel detailPanel = FRGUIPaneFactory.createBorderLayout_S_Pane();
{
detailPanel.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 0));
UILabel detailLabel = new UILabel(Toolkit.i18nText("Fine_Designer_Look_Detail"));
detailLabel.setForeground(new Color(65, 155, 249));
detailLabel.addMouseListener(new MouseAdapter() {
@ -317,76 +321,22 @@ public class EnvDetectorDialog extends JDialog {
List<NotificationModel> notificationModels = results
.filter(Objects::nonNull)
.filter((e) -> e.getStatus() == DetectorStatus.EXCEPTION)
.map(EnvDetectorDialog.this::convertDetectorResult)
.map(DetectorUtil::convert2Notification)
.collect(Collectors.toList());
NotificationDialog dialog = new NotificationDialog(properties, notificationModels);
dialog.open();
}
});
statusPanel.add(detailLabel);
}
return statusPanel;
detailPanel.add(detailLabel, BorderLayout.CENTER);
}
private NotificationModel convertDetectorResult(DetectorResult result) {
List<NotificationMessage> messages = new ArrayList<>();
Function<Message, Optional<NotificationMessage>> convert2NotificationMsg = message -> {
NotificationMessage notificationMessage = null;
if (message != null) {
Message.Type type = message.getType();
switch (type) {
case SIMPLE:
notificationMessage = (new NotificationMessage.SimpleMessage(message.get()));
break;
case LINK:
Message.Link linkMsg = (Message.Link) message;
notificationMessage = new NotificationMessage.LinkMessage(linkMsg.getText(), linkMsg.getLink());
break;
default:
break;
}
}
return Optional.ofNullable(notificationMessage);
};
ExceptionTips tips = result.getTips();
convert2NotificationMsg
.apply(tips.getMessage())
.ifPresent(messages::add);
ExceptionSolution solution = result.getSolution();
convert2NotificationMsg.apply(solution.getMessage())
.ifPresent(messages::add);
NotificationAction notificationAction = null;
SolutionAction solutionAction = solution.getAction();
if (solutionAction != null) {
notificationAction = new NotificationAction() {
@Override
public String name() {
return solutionAction.name();
statusPanel.add(detailPanel, BorderLayout.CENTER);
}
@Override
public void run(Object... args) {
solutionAction.run();
}
};
}
return new NotificationModel(NotificationType.WARNING, notificationAction, messages);
return statusPanel;
}
private void refresh() {
updateTable(this.tablePanel);
pack();
repaint();
}
/* tail */
@NotNull
private JPanel createTailPanel() {
@ -397,6 +347,11 @@ public class EnvDetectorDialog extends JDialog {
JPanel configPanel = FRGUIPaneFactory.createBorderLayout_S_Pane();
{
UICheckBox checkBox = new UICheckBox();
checkBox.setSelected(this.detectOpen);
checkBox.addChangeListener(e -> {
UICheckBox source = (UICheckBox) e.getSource();
EnvDetectorDialog.this.detectOpen = source.isSelected();
});
configPanel.add(checkBox, BorderLayout.WEST);
UILabel description = new UILabel(Toolkit.i18nText("Fine-Design_Basic_Detect_Switch"));
configPanel.add(description, BorderLayout.EAST);
@ -411,7 +366,7 @@ public class EnvDetectorDialog extends JDialog {
setVisible(false);
dispose();
// 配置处理
// todo
ExceptionDetectorConfig.getInstance().setOpen(this.detectOpen);
});
actionsPanel.add(confirmButton, BorderLayout.WEST);
@ -426,89 +381,33 @@ public class EnvDetectorDialog extends JDialog {
return tailPanel;
}
private void configProperties() {
setTitle(Toolkit.i18nText("Fine-Design_Basic_Detect_Title"));
setModal(false);
setFocusable(false);
setAutoRequestFocus(false);
setResizable(false);
}
/**
* 数据 model
*
* kind-list_item
*/
private class EnvDetectorModel {
private Map<DetectorType.Kind, List<EnvDetectorItem>> itemMap = new LinkedHashMap<>();
public EnvDetectorModel() {
itemMap.put(DetectorType.Kind.JAR, Lists.newArrayList(new EnvDetectorItem(DetectorType.LACK_OF_JAR), new EnvDetectorItem(DetectorType.JAR_IN_CONSISTENCE), new EnvDetectorItem(DetectorType.JAR_CONFLICT)));
itemMap.put(DetectorType.Kind.FINE_DB, Lists.newArrayList(new EnvDetectorItem(DetectorType.FINE_DB_LOCKED), new EnvDetectorItem(DetectorType.FINE_DB_PERMISSION), new EnvDetectorItem(DetectorType.FINE_DB_DIRTY)));
}
public void update(DetectorType type, DetectorResult result) {
List<EnvDetectorItem> items = itemMap.get(type.getKind());
items.stream()
.filter((e) -> e.getType() == type)
.findFirst()
.ifPresent((e) -> {e.setResult(result);});
}
public Stream<DetectorResult> getResults() {
return getItems().stream()
.map(EnvDetectorItem::getResult);
}
public List<EnvDetectorItem> getItems() {
return itemMap.values().stream()
.flatMap(Collection::stream)
.collect(Collectors.toList());
}
public Map<DetectorType.Kind, List<EnvDetectorItem>> getItemMap() {
return this.itemMap;
}
}
private class EnvDetectorItem {
private DetectorType type;
private DetectorResult result;
private void refresh() {
public EnvDetectorItem(DetectorType detectorType) {
this.type = detectorType;
updateTable(this.tablePanel);
pack();
repaint();
}
public DetectorType getType() {
return type;
}
private static ImageIcon getLoadingIcon() {
public String getKind() {
return this.type.getKind().getDescription();
URL resource = EnvDetectorDialog.class.getResource("/com/fr/design/standard/loading/loading-120.gif");
if (resource == null) {
return null;
}
public String getDescription() {
return this.type.getDescription();
ImageIcon loadingIcon = new ImageIcon(resource);
int width = 16;
int height = 16;
loadingIcon.setImage(loadingIcon.getImage().getScaledInstance(width, height, Image.SCALE_DEFAULT));
return loadingIcon;
}
public DetectorResult getResult() {
return result;
}
private void configProperties() {
public void setResult(DetectorResult result) {
this.result = result;
}
setTitle(Toolkit.i18nText("Fine-Design_Basic_Detect_Title"));
setModal(false);
setFocusable(false);
setAutoRequestFocus(false);
setResizable(false);
}
/**

38
designer-base/src/main/java/com/fr/env/detect/ui/EnvDetectorItem.java vendored

@ -0,0 +1,38 @@
package com.fr.env.detect.ui;
import com.fr.env.detect.bean.DetectorResult;
import com.fr.env.detect.bean.DetectorType;
/**
* created by Harrison on 2022/05/27
**/
public class EnvDetectorItem {
private DetectorType type;
private DetectorResult result;
public EnvDetectorItem(DetectorType detectorType) {
this.type = detectorType;
}
public DetectorType getType() {
return type;
}
public String getKind() {
return this.type.getKind().getDescription();
}
public String getDescription() {
return this.type.getDescription();
}
public DetectorResult getResult() {
return result;
}
public void setResult(DetectorResult result) {
this.result = result;
}
}

59
designer-base/src/main/java/com/fr/env/detect/ui/EnvDetectorModel.java vendored

@ -0,0 +1,59 @@
package com.fr.env.detect.ui;
import com.fr.env.detect.bean.DetectorResult;
import com.fr.env.detect.bean.DetectorType;
import com.fr.third.guava.collect.Lists;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* created by Harrison on 2022/05/27
**/
public class EnvDetectorModel {
private Map<DetectorType.Kind, List<EnvDetectorItem>> itemMap = new LinkedHashMap<>();
public EnvDetectorModel() {
itemMap.put(DetectorType.Kind.JAR, Lists.newArrayList(new EnvDetectorItem(DetectorType.LACK_OF_JAR), new EnvDetectorItem(DetectorType.JAR_IN_CONSISTENCE), new EnvDetectorItem(DetectorType.JAR_CONFLICT)));
itemMap.put(DetectorType.Kind.FINE_DB, Lists.newArrayList(new EnvDetectorItem(DetectorType.FINE_DB_LOCKED), new EnvDetectorItem(DetectorType.FINE_DB_PERMISSION), new EnvDetectorItem(DetectorType.FINE_DB_DIRTY)));
}
public void update(DetectorType type, DetectorResult result) {
List<EnvDetectorItem> items = itemMap.get(type.getKind());
items.stream()
.filter((e) -> e.getType() == type)
.findFirst()
.ifPresent((e) -> {
e.setResult(result);
});
}
public Stream<DetectorResult> getResults() {
return getItems().stream()
.map(EnvDetectorItem::getResult);
}
public List<EnvDetectorItem> getItems() {
return itemMap.values().stream()
.flatMap(Collection::stream)
.collect(Collectors.toList());
}
public Map<DetectorType.Kind, List<EnvDetectorItem>> getItemMap() {
return this.itemMap;
}
}
Loading…
Cancel
Save