From 540480bf660f7d91d0ec689833d9a2707da89651 Mon Sep 17 00:00:00 2001 From: Harrison Date: Thu, 26 May 2022 09:51:02 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20REPORT-70565=20=E8=AE=BE=E8=AE=A1?= =?UTF-8?q?=E5=99=A8=E7=8E=AF=E5=A2=83=E7=9B=91=E6=B5=8B=EF=BC=88jar?= =?UTF-8?q?=E5=8C=85=E5=BC=82=E5=B8=B8=E3=80=81finedb=E3=80=81=E6=9D=80?= =?UTF-8?q?=E6=AF=92=E8=BD=AF=E4=BB=B6=EF=BC=89=20=E5=9F=BA=E6=9C=AC?= =?UTF-8?q?=E5=AE=8C=E6=88=90=E6=89=80=E6=9C=89=E7=9A=84=E4=B8=9A=E5=8A=A1?= =?UTF-8?q?=E9=80=BB=E8=BE=91=E3=80=82=E5=87=86=E5=A4=87=E5=A4=84=E7=90=86?= =?UTF-8?q?=20UI=20=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../base/AbstractExceptionDetector.java | 8 +- .../fr/env/detect/base/DetectorBridge.java | 45 +++-- .../fr/env/detect/base/DetectorConstants.java | 11 ++ .../com/fr/env/detect/base/DetectorUtil.java | 16 ++ .../fr/env/detect/base/ExceptionDetector.java | 4 +- .../fr/env/detect/bean/DetectorResult.java | 40 ++--- .../fr/env/detect/bean/DetectorStatus.java | 22 --- .../com/fr/env/detect/bean/DetectorType.java | 57 +++++- .../fr/env/detect/bean/ExceptionSolution.java | 7 +- .../exception/intelli/package-info.java | 4 + .../fr/env/detect/impl/HsqlDirtyDetector.java | 6 +- .../detect/impl/JarInconsistentDetector.java | 60 +++++-- .../fr/env/detect/impl/JarLackDetector.java | 130 ++++++++++++-- .../impl/converter/ClassConfictConvertor.java | 165 ++++++++++++++++++ .../converter/ClassThrowableConvertor.java | 53 ------ .../impl/converter/FineDbDirtyConverter.java | 70 +++++++- .../impl/converter/FineDbLockedConverter.java | 22 ++- .../converter/FineDbPermissionConverter.java | 22 ++- .../converter/ClassConfictConvertorTest.java | 23 +++ 19 files changed, 605 insertions(+), 160 deletions(-) create mode 100644 designer-base/src/main/java/com/fr/env/detect/base/DetectorConstants.java create mode 100644 designer-base/src/main/java/com/fr/env/detect/base/DetectorUtil.java delete mode 100644 designer-base/src/main/java/com/fr/env/detect/bean/DetectorStatus.java create mode 100644 designer-base/src/main/java/com/fr/env/detect/exception/intelli/package-info.java create mode 100644 designer-base/src/main/java/com/fr/env/detect/impl/converter/ClassConfictConvertor.java delete mode 100644 designer-base/src/main/java/com/fr/env/detect/impl/converter/ClassThrowableConvertor.java create mode 100644 designer-base/src/test/java/com/fr/env/detect/impl/converter/ClassConfictConvertorTest.java diff --git a/designer-base/src/main/java/com/fr/env/detect/base/AbstractExceptionDetector.java b/designer-base/src/main/java/com/fr/env/detect/base/AbstractExceptionDetector.java index 32d54a1d7..5414ba648 100644 --- a/designer-base/src/main/java/com/fr/env/detect/base/AbstractExceptionDetector.java +++ b/designer-base/src/main/java/com/fr/env/detect/base/AbstractExceptionDetector.java @@ -7,13 +7,13 @@ import com.fr.env.detect.bean.DetectorType; **/ public abstract class AbstractExceptionDetector implements ExceptionDetector { - private DetectorType key; + private DetectorType type; - public AbstractExceptionDetector(DetectorType key) { - this.key = key; + public AbstractExceptionDetector(DetectorType type) { + this.type = type; } public DetectorType type() { - return key; + return type; } } diff --git a/designer-base/src/main/java/com/fr/env/detect/base/DetectorBridge.java b/designer-base/src/main/java/com/fr/env/detect/base/DetectorBridge.java index 78b501784..8cbef25ab 100644 --- a/designer-base/src/main/java/com/fr/env/detect/base/DetectorBridge.java +++ b/designer-base/src/main/java/com/fr/env/detect/base/DetectorBridge.java @@ -2,6 +2,13 @@ package com.fr.env.detect.base; import com.fr.env.detect.bean.DetectorResult; import com.fr.env.detect.bean.DetectorType; +import com.fr.env.detect.impl.HsqlDirtyDetector; +import com.fr.env.detect.impl.JarInconsistentDetector; +import com.fr.env.detect.impl.JarLackDetector; +import com.fr.env.detect.impl.converter.ClassConfictConvertor; +import com.fr.env.detect.impl.converter.FineDbDirtyConverter; +import com.fr.env.detect.impl.converter.FineDbLockedConverter; +import com.fr.env.detect.impl.converter.FineDbPermissionConverter; import com.fr.env.detect.thowable.ThrowableLogAppender; import com.fr.value.NotNullLazyValue; import org.jetbrains.annotations.NotNull; @@ -28,8 +35,13 @@ public class DetectorBridge { private final NotNullLazyValue throwableBridge = new NotNullLazyValue() { @Override protected @NotNull ThrowableBridge compute() { - - return new ThrowableBridge(); + + ThrowableBridge bridge = new ThrowableBridge(); + bridge.register(new ClassConfictConvertor()); + bridge.register(new FineDbDirtyConverter()); + bridge.register(new FineDbLockedConverter()); + bridge.register(new FineDbPermissionConverter()); + return bridge; } }; @@ -37,8 +49,12 @@ public class DetectorBridge { @Override protected @NotNull DetectorManager compute() { - - return new DetectorManager(); + + DetectorManager manager = new DetectorManager(); + manager.register(new HsqlDirtyDetector()); + manager.register(new JarInconsistentDetector()); + manager.register(new JarLackDetector()); + return manager; } }; @@ -62,24 +78,25 @@ public class DetectorBridge { } /** - * 执行-检测异常 + * 针对某一项进行检测 + * 主要用于手动检测时 * - * @return 能够检测出的异常情况 + * @param type 检测类型 + * @return 检测结果 */ - public Stream detect() { - - return detectorManager.getValue().detect(); + public Optional detect(DetectorType type) { + + return detectorManager.getValue().detect(type); } /** - * 针对某一项进行检测 + * 执行-检测异常 * - * @param type 检测类型 - * @return 检测结果 + * @return 能够检测出的异常情况 */ - public Optional detect(DetectorType type) { + public Stream detect() { - return detectorManager.getValue().detect(type); + return detectorManager.getValue().detect(); } /** diff --git a/designer-base/src/main/java/com/fr/env/detect/base/DetectorConstants.java b/designer-base/src/main/java/com/fr/env/detect/base/DetectorConstants.java new file mode 100644 index 000000000..fce9d5a88 --- /dev/null +++ b/designer-base/src/main/java/com/fr/env/detect/base/DetectorConstants.java @@ -0,0 +1,11 @@ +package com.fr.env.detect.base; + +/** + * created by Harrison on 2022/05/25 + **/ +public class DetectorConstants { + + public static final String JAR_HELP_LINK = ""; + + public static final String FINE_DB_HELP_LINK = ""; +} diff --git a/designer-base/src/main/java/com/fr/env/detect/base/DetectorUtil.java b/designer-base/src/main/java/com/fr/env/detect/base/DetectorUtil.java new file mode 100644 index 000000000..33aa0e98f --- /dev/null +++ b/designer-base/src/main/java/com/fr/env/detect/base/DetectorUtil.java @@ -0,0 +1,16 @@ +package com.fr.env.detect.base; + +import com.fr.general.build.BuildInfo; +import com.fr.stable.StringUtils; + +/** + * created by Harrison on 2022/05/25 + **/ +public class DetectorUtil { + + public static boolean isDesignerJar(BuildInfo info) { + + return StringUtils.contains(info.getJar(), "fine-report-designer"); + } + +} diff --git a/designer-base/src/main/java/com/fr/env/detect/base/ExceptionDetector.java b/designer-base/src/main/java/com/fr/env/detect/base/ExceptionDetector.java index 3d6d8bc4e..c874b1979 100644 --- a/designer-base/src/main/java/com/fr/env/detect/base/ExceptionDetector.java +++ b/designer-base/src/main/java/com/fr/env/detect/base/ExceptionDetector.java @@ -1,7 +1,8 @@ package com.fr.env.detect.base; -import com.fr.env.detect.bean.DetectorType; import com.fr.env.detect.bean.DetectorResult; +import com.fr.env.detect.bean.DetectorType; +import org.jetbrains.annotations.Nullable; /** * created by Harrison on 2022/05/13 @@ -20,6 +21,7 @@ public interface ExceptionDetector { * * @return 结果 */ + @Nullable DetectorResult detect(); } diff --git a/designer-base/src/main/java/com/fr/env/detect/bean/DetectorResult.java b/designer-base/src/main/java/com/fr/env/detect/bean/DetectorResult.java index 09850055d..86d6c0e0c 100644 --- a/designer-base/src/main/java/com/fr/env/detect/bean/DetectorResult.java +++ b/designer-base/src/main/java/com/fr/env/detect/bean/DetectorResult.java @@ -11,29 +11,20 @@ public class DetectorResult { private DetectorType type; - private DetectorStatus status; - private ExceptionTips tips; private ExceptionSolution solution; - private ExceptionLog exceptionLog; - - public DetectorResult(DetectorType type, ExceptionTips tips, ExceptionSolution solution, ExceptionLog exceptionLog) { + public DetectorResult(DetectorType type, ExceptionTips tips, ExceptionSolution solution) { this.type = type; this.tips = tips; this.solution = solution; - this.exceptionLog = exceptionLog; } public DetectorType getType() { return type; } - public DetectorStatus getStatus() { - return status; - } - @Nullable public ExceptionTips getTips() { return tips; @@ -44,11 +35,6 @@ public class DetectorResult { return solution; } - @Nullable - public ExceptionLog getExceptionLog() { - return exceptionLog; - } - public static DetectorResultBuilder builder() { return new DetectorResultBuilder(); @@ -58,11 +44,9 @@ public class DetectorResult { public static final class DetectorResultBuilder { private DetectorType type; - private DetectorStatus status; private ExceptionTips tips; private ExceptionSolution solution; - private ExceptionLog exceptionLog; private DetectorResultBuilder() { } @@ -72,8 +56,10 @@ public class DetectorResult { return this; } - public DetectorResultBuilder withStatus(DetectorStatus status) { - this.status = status; + public DetectorResultBuilder withTips(String message) { + + Message.Simple simple = new Message.Simple(message); + this.tips = new ExceptionTips(simple); return this; } @@ -82,21 +68,21 @@ public class DetectorResult { return this; } - public DetectorResultBuilder withSolution(ExceptionSolution solution) { - this.solution = solution; + public DetectorResultBuilder withSolution(String content, String link) { + + Message.Link message = new Message.Link(content, link); + this.solution = new ExceptionSolution(message, null); return this; } - public DetectorResultBuilder withExceptionLog(ExceptionLog exceptionLog) { - this.exceptionLog = exceptionLog; + public DetectorResultBuilder withSolution(ExceptionSolution solution) { + this.solution = solution; return this; } public DetectorResult build() { - - DetectorResult detectorResult = new DetectorResult(type, tips, solution, exceptionLog); - detectorResult.status = this.status; - return detectorResult; + + return new DetectorResult(type, tips, solution); } } } diff --git a/designer-base/src/main/java/com/fr/env/detect/bean/DetectorStatus.java b/designer-base/src/main/java/com/fr/env/detect/bean/DetectorStatus.java deleted file mode 100644 index d75a82e56..000000000 --- a/designer-base/src/main/java/com/fr/env/detect/bean/DetectorStatus.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.fr.env.detect.bean; - -/** - * created by Harrison on 2022/05/25 - **/ -public enum DetectorStatus { - - /** - * 成功 - */ - SUCCESS, - - /** - * 失败 - */ - FAILED, - - /** - * 异常 - */ - UNKNOWN -} diff --git a/designer-base/src/main/java/com/fr/env/detect/bean/DetectorType.java b/designer-base/src/main/java/com/fr/env/detect/bean/DetectorType.java index 2bc71e58a..979b35501 100644 --- a/designer-base/src/main/java/com/fr/env/detect/bean/DetectorType.java +++ b/designer-base/src/main/java/com/fr/env/detect/bean/DetectorType.java @@ -2,6 +2,8 @@ package com.fr.env.detect.bean; /** * 检测的原生数据 + * 其实这里可以继续拆分到不同的逻辑下面的, 比如实际生成 DetectorResult 的地方 {@link com.fr.env.detect.base.ExceptionDetector}。 + * 不过目前没有必要。先这样处理。 * * created by Harrison on 2022/05/13 **/ @@ -10,43 +12,70 @@ public enum DetectorType { /** * 缺少 JAR */ - LACK_OF_JAR(Kind.JAR, WorkType.LOCAL), + LACK_OF_JAR(Kind.JAR, WorkType.LOCAL, + "Fine_Design_Basic_Jar_Lack", + "Fine_Design_Basic_Jar_Solution", + "Fine_Design_Basic_Log_Jar_Lack"), + /** * JAR 包版本不一致 */ - JAR_IN_CONSISTENCE(Kind.JAR, WorkType.SIMPLE), + JAR_IN_CONSISTENCE(Kind.JAR, WorkType.SIMPLE, + "Fine_Design_Basic_Jar_InConsistent", + "Fine_Design_Basic_Jar_Solution", + "Fine_Design_Basic_Log_Jar_InConsistent"), /** * JAR 包冲突 */ - JAR_CONFLICT(Kind.JAR, WorkType.REMOTE), - + JAR_CONFLICT(Kind.JAR, WorkType.REMOTE, + "Fine_Design_Basic_Jar_Problem", + "Fine_Design_Basic_Jar_Solution", + "Fine_Design_Basic_Log_Jar_Problem"), /** * FineDB 权限问题 */ - FINE_DB_PERMISSION(Kind.FINE_DB, WorkType.LOCAL), + FINE_DB_PERMISSION(Kind.FINE_DB, WorkType.LOCAL, + "Fine_Design_Basic_FineDB_Permission_Occupied", + "Fine_Design_Basic_FineDB_Solution", + "Fine_Design_Basic_Log_FineDB_Permission_Occupied"), /** * FineDB 锁 */ - FINE_DB_LOCKED(Kind.FINE_DB, WorkType.LOCAL), + FINE_DB_LOCKED(Kind.FINE_DB, WorkType.LOCAL, + "Fine_Design_Basic_FineDB_Locked", + "Fine_Design_Basic_FineDB_Solution", + "Fine_Design_Basic_Log_FineDB_Locked"), /** * FineDB 脏数据 */ - FINE_DB_DIRTY(Kind.FINE_DB, WorkType.SIMPLE) + FINE_DB_DIRTY(Kind.FINE_DB, WorkType.SIMPLE, + "Fine_Design_Basic_FineDB_Dirty_Data", + "Fine_Design_Basic_FineDB_Dirty_Solution", + "Fine_Design_Basic_Log_FineDB_Dirty_Data") ; private final Kind kind; private final WorkType workType; - DetectorType(Kind kind, WorkType workType) { + private final String tipsLocale; + + private final String solutionLocale; + + private final String logLocale; + + DetectorType(Kind kind, WorkType workType, String tipsLocale, String solutionLocale, String logLocale) { this.kind = kind; this.workType = workType; + this.tipsLocale = tipsLocale; + this.solutionLocale = solutionLocale; + this.logLocale = logLocale; } public Kind getKind() { @@ -57,6 +86,18 @@ public enum DetectorType { return workType; } + public String getTipsLocale() { + return tipsLocale; + } + + public String getSolutionLocale() { + return solutionLocale; + } + + public String getLogLocale() { + return logLocale; + } + public enum Kind { /** diff --git a/designer-base/src/main/java/com/fr/env/detect/bean/ExceptionSolution.java b/designer-base/src/main/java/com/fr/env/detect/bean/ExceptionSolution.java index a6748e26c..796d78c8d 100644 --- a/designer-base/src/main/java/com/fr/env/detect/bean/ExceptionSolution.java +++ b/designer-base/src/main/java/com/fr/env/detect/bean/ExceptionSolution.java @@ -1,5 +1,7 @@ package com.fr.env.detect.bean; +import org.jetbrains.annotations.Nullable; + /** * created by Harrison on 2022/05/13 **/ @@ -7,9 +9,10 @@ public class ExceptionSolution { private Message message; + @Nullable private SolutionAction action; - public ExceptionSolution(Message message, SolutionAction action) { + public ExceptionSolution(Message message, @Nullable SolutionAction action) { this.message = message; this.action = action; } @@ -18,7 +21,7 @@ public class ExceptionSolution { return message; } - public SolutionAction getAction() { + public @Nullable SolutionAction getAction() { return action; } } diff --git a/designer-base/src/main/java/com/fr/env/detect/exception/intelli/package-info.java b/designer-base/src/main/java/com/fr/env/detect/exception/intelli/package-info.java new file mode 100644 index 000000000..f11ad3f7e --- /dev/null +++ b/designer-base/src/main/java/com/fr/env/detect/exception/intelli/package-info.java @@ -0,0 +1,4 @@ +/** + * 国际化相关的异常 + */ +package com.fr.env.detect.exception.intelli; \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/env/detect/impl/HsqlDirtyDetector.java b/designer-base/src/main/java/com/fr/env/detect/impl/HsqlDirtyDetector.java index 6afc41a66..4d3645858 100644 --- a/designer-base/src/main/java/com/fr/env/detect/impl/HsqlDirtyDetector.java +++ b/designer-base/src/main/java/com/fr/env/detect/impl/HsqlDirtyDetector.java @@ -2,14 +2,18 @@ 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.thowable.ThrowableStore; import com.fr.env.detect.impl.converter.FineDbDirtyConverter; +import com.fr.env.detect.thowable.ThrowableStore; /** * created by Harrison on 2022/05/25 **/ public class HsqlDirtyDetector extends CatchExceptionDetector { + public HsqlDirtyDetector() { + this(ThrowableStore.getInstance()); + } + public HsqlDirtyDetector(ThrowableStore throwableStore) { super(DetectorType.FINE_DB_DIRTY, throwableStore, new FineDbDirtyConverter()); diff --git a/designer-base/src/main/java/com/fr/env/detect/impl/JarInconsistentDetector.java b/designer-base/src/main/java/com/fr/env/detect/impl/JarInconsistentDetector.java index 0967697f6..4a3e4aafa 100644 --- a/designer-base/src/main/java/com/fr/env/detect/impl/JarInconsistentDetector.java +++ b/designer-base/src/main/java/com/fr/env/detect/impl/JarInconsistentDetector.java @@ -1,20 +1,30 @@ package com.fr.env.detect.impl; +import com.fr.common.util.Collections; +import com.fr.design.i18n.Toolkit; import com.fr.env.detect.base.AbstractExceptionDetector; +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.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.exception.DetectorException; import com.fr.general.build.BuildInfo; -import com.fr.general.build.BuildInfoOperator; import com.fr.general.build.BuildInfoManager; -import com.fr.stable.StringUtils; +import com.fr.general.build.BuildInfoOperator; +import com.fr.general.build.impl.BuildInfoOperatorImpl; +import com.fr.log.FineLoggerFactory; 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 java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.stream.Collectors; /** @@ -31,14 +41,15 @@ public class JarInconsistentDetector extends AbstractExceptionDetector { public DetectorResult detect() { DetectorResult.DetectorResultBuilder builder = DetectorResult.builder(); - // 检测有哪些 JAR 包, 当前是否缺少对应的 JAR 包 - BuildInfoOperator buildInfoOperator = WorkContext.getCurrent().get(BuildInfoOperator.class); - List buildInfos = buildInfoOperator.getBuildInfos(); if (WorkContext.getCurrent().isLocal()) { + // 本地的获取方式 + BuildInfoOperator operator = new BuildInfoOperatorImpl(); + List buildInfos = operator.getBuildInfos(); + String designerBuild = buildInfos.stream() - .filter(this::isDesignerJar) + .filter(DetectorUtil::isDesignerJar) .map(BuildInfo::getGroupBuild) .filter(StringUtils::isNotEmpty) .findFirst() @@ -48,8 +59,27 @@ public class JarInconsistentDetector extends AbstractExceptionDetector { .filter((e) -> !StringUtils.equals(designerBuild, e.getGroupBuild())) .collect(Collectors.toList()); + if (Collections.isEmpty(inConsistentInfos)) { + return null; + } + + List inConsistentJars = inConsistentInfos.stream() + .map(BuildInfo::getJar) + .collect(Collectors.toList()); + String message = StringUtils.join(",", inConsistentJars); + + String tipsMessage = Toolkit.i18nText("Fine_Design_Basic_Detect_Local") + Toolkit.i18nText(type().getTipsLocale()) + "\n" + message; + builder.withTips(new ExceptionTips(new Message.Simple(tipsMessage))) + .withSolution(new ExceptionSolution(new Message.Link(Toolkit.i18nText(type().getSolutionLocale()), DetectorConstants.JAR_HELP_LINK), null)); + + FineLoggerFactory.getLogger().error(type().getLogLocale() + message); + } else { + // 检测有哪些 JAR 包, 当前是否缺少对应的 JAR 包 + BuildInfoOperator buildInfoOperator = WorkContext.getCurrent().get(BuildInfoOperator.class); + List buildInfos = buildInfoOperator.getBuildInfos(); + // 远程情况 List localInfos = BuildInfoManager.getInstance().getInfos(); Map localMap = groupBy(localInfos); @@ -58,19 +88,25 @@ public class JarInconsistentDetector extends AbstractExceptionDetector { Map remoteMap = groupBy(remoteInfos); MapDifference difference = Maps.difference(localMap, remoteMap); - // 两边都有的 JAR 的不同之处 Map diffInCommon = difference.entriesInCommon(); + + if (diffInCommon.isEmpty()) { + return null; + } + + Set 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); + builder.withTips(new ExceptionTips(tipsMessage)) + .withSolution(new ExceptionSolution(new Message.Link(Toolkit.i18nText(type().getSolutionLocale()), DetectorConstants.JAR_HELP_LINK), null)); + } return builder.build(); } - private boolean isDesignerJar(BuildInfo info) { - - return StringUtils.contains(info.getJar(), "fine-report-designer"); - } - private Map groupBy(List localInfos) { Map localMap = new HashMap<>(); diff --git a/designer-base/src/main/java/com/fr/env/detect/impl/JarLackDetector.java b/designer-base/src/main/java/com/fr/env/detect/impl/JarLackDetector.java index 86f589f30..ecad03e12 100644 --- a/designer-base/src/main/java/com/fr/env/detect/impl/JarLackDetector.java +++ b/designer-base/src/main/java/com/fr/env/detect/impl/JarLackDetector.java @@ -1,14 +1,32 @@ package com.fr.env.detect.impl; +import com.fr.common.util.Collections; +import com.fr.common.util.Strings; import com.fr.env.detect.base.AbstractExceptionDetector; +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.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.general.build.BuildInfo; import com.fr.general.build.BuildInfoOperator; -import com.fr.stable.StringUtils; +import com.fr.general.build.impl.BuildInfoOperatorImpl; +import com.fr.locale.InterProviderFactory; +import com.fr.log.FineLoggerFactory; +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; +import java.util.stream.Collectors; /** * created by Harrison on 2022/05/24 @@ -16,28 +34,120 @@ import java.util.List; public class JarLackDetector extends AbstractExceptionDetector { public JarLackDetector() { + super(DetectorType.LACK_OF_JAR); } @Override public DetectorResult detect() { + // 不支持远程 + if (!WorkContext.getCurrent().isLocal()) { + return null; + } + DetectorResult.DetectorResultBuilder builder = DetectorResult.builder(); // 检测有哪些 JAR 包, 当前是否缺少对应的 JAR 包 - BuildInfoOperator buildInfoOperator = WorkContext.getCurrent().get(BuildInfoOperator.class); + BuildInfoOperator buildInfoOperator = new BuildInfoOperatorImpl(); List buildInfos = buildInfoOperator.getBuildInfos(); - for (BuildInfo buildInfo : buildInfos) { - String jar = buildInfo.getJar(); - String buildContent = buildInfo.getGroupBuild(); - boolean isLack = StringUtils.isEmpty(buildContent); - if (isLack) { - // 处理信息 - - } + List lackInfos = buildInfos.stream() + .filter(this::isLackInfo) + .collect(Collectors.toList()); + + if (Collections.isEmpty(lackInfos)) { + return null; } + Message message = tipsMessage(lackInfos); + builder.withTips(new ExceptionTips(message)) + .withSolution( + new ExceptionSolution( + new Message.Link(InterProviderFactory.getProvider().getLocText(type().getSolutionLocale()), DetectorConstants.JAR_HELP_LINK), + null)); + + logException(lackInfos); + return builder.build(); + } + + private void logException(List lackInfos) { + + List jarInfos = lackInfos.stream() + .map(BuildInfo::getJar) + .collect(Collectors.toList()); + String message = StringUtils.join(",", jarInfos); + FineLoggerFactory.getLogger().error(type().getLogLocale() + message); + } + + private boolean isLackInfo(BuildInfo e) { + return StringUtils.isNotEmpty(e.getGroupBuild()); + } + + private Message tipsMessage(List 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); + + Map> libMap = groupByPath(infos, homeLibPath, webLibPath); + + StringBuilder sb = new StringBuilder(); + + List homeLibs = libMap.get(homeLibPath); + if (!Collections.isEmpty(homeLibs)) { + sb.append(homeLibPath).append(":"); + sb.append(StringUtils.join("、", homeLibs)); + } + + List webLibs = libMap.get(webLibPath); + if (!Collections.isEmpty(webLibs)) { + if (sb.length() != 0) { + sb.append("\n"); + } + sb.append(Strings.join("、", webLibs)); + } + + String mainContent = sb.toString(); + + DetectorType type = this.type(); + String header = InterProviderFactory.getProvider().getLocText(type.getTipsLocale()); + return new Message.Simple(header + "\n" + mainContent); + } + + @NotNull + private Map> groupByPath(List infos, String homeLibPath, String webLibPath) { + Map> libMap = new HashMap<>(); + for (BuildInfo info : infos) { + String key; + if (inHomeLib(info)) { + key = homeLibPath; + } else { + key = webLibPath; + } + libMap.compute(key, (keyA, value) -> { + if (Collections.isEmpty(value)) { + value = Lists.newArrayList(info.getJar()); + } else { + value.add(info.getJar()); + } + return value; + }); + } + return libMap; } + + /** + * 在 %FR_HOME%\lib + * 否则都是在 %FR_HOME%\webapps\webroot\WEB-INF\lib + * + * @param info JAR 信息 + * @return 是否位于 HOME\LIB + */ + private boolean inHomeLib(BuildInfo info) { + + return DetectorUtil.isDesignerJar(info); + } + } diff --git a/designer-base/src/main/java/com/fr/env/detect/impl/converter/ClassConfictConvertor.java b/designer-base/src/main/java/com/fr/env/detect/impl/converter/ClassConfictConvertor.java new file mode 100644 index 000000000..dd26dc50f --- /dev/null +++ b/designer-base/src/main/java/com/fr/env/detect/impl/converter/ClassConfictConvertor.java @@ -0,0 +1,165 @@ +package com.fr.env.detect.impl.converter; + +import com.fr.env.detect.bean.DetectorResult; +import com.fr.env.detect.thowable.ThrowableConverter; +import com.fr.stable.resource.ResourceLoader; + +import javax.el.MethodNotFoundException; +import java.io.IOException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * 类抛出异常的转换 + * 原则:可以找不到,但不要误报 + * + * created by Harrison on 2022/05/24 + **/ +public class ClassConfictConvertor implements ThrowableConverter { + + private Map, ClassNameConverter> throwableMap = new HashMap<>(); + + private static final Pattern JAR_PATTERN = Pattern.compile("([\\w+-\\.]*\\.jar)"); + + public ClassConfictConvertor() { + + // 类异常 + this.throwableMap.put(ClassNotFoundException.class, Converter.CLASS); + this.throwableMap.put(NoClassDefFoundError.class, Converter.CLASS); + this.throwableMap.put(ClassCastException.class, Converter.CLASS); + this.throwableMap.put(IncompatibleClassChangeError.class, Converter.CLASS); + + // 方法异常 + this.throwableMap.put(MethodNotFoundException.class, Converter.METHOD); + this.throwableMap.put(NoSuchMethodException.class, Converter.METHOD); + this.throwableMap.put(NoSuchMethodError.class, Converter.METHOD); + } + + @Override + public boolean accept(Throwable throwable) { + + Throwable sign = throwable; + while (sign != null) { + if (throwableMap.containsKey(sign.getClass())) { + return true; + } + sign = sign.getCause(); + } + return false; + } + + @Override + public DetectorResult convert(Throwable throwable) { + + Iterable classNames = Collections.emptyList(); + Throwable sign = throwable; + while (sign != null) { + if (throwableMap.containsKey(sign.getClass())) { + classNames = throwableMap.get(sign.getClass()) + .converter(throwable); + } + sign = sign.getCause(); + } + + for (String className : classNames) { + String classFile = "/" + className.replaceAll("\\.", "/") + ".class"; + try { + Enumeration urls = ResourceLoader.getResources(classFile, this.getClass()); + List urlList = new ArrayList<>(); + while (urls.hasMoreElements()) { + URL url = urls.nextElement(); + urlList.add(url); + } + Set allPath = new HashSet<>(); + for (URL url : urlList) { + String file = url.getFile(); + Matcher matcher = JAR_PATTERN.matcher(url.getFile()); + if (matcher.find()) { + String jar = matcher.group(); + allPath.add(jar); + } else { + boolean containsClasses = file.contains("classes"); + if (containsClasses) { + allPath.add("classes"); + } + } + } + } catch (IOException ignore) { + } + } + return null; + } + + private interface ClassNameConverter { + + /** + * 将异常解析为类名,可能有多个 + * + * @param throwable 异常 + * @return 类名 + */ + Iterable converter(Throwable throwable); + } + + public enum Converter implements ClassNameConverter { + + /** + * 类匹配 + */ + CLASS { + + /** + * 匹配 111.222.333 + * 至少有一个 111. + * 至少有一个 333 + */ + private final Pattern CLASS_PATTERN = Pattern.compile("((\\w+\\.)+(\\w+))"); + + @Override + public Iterable converter(Throwable throwable) { + + String message = throwable.getMessage(); + Matcher matcher = CLASS_PATTERN.matcher(message); + List names = new ArrayList<>(); + while (matcher.find()) { + String className = matcher.group(); + names.add(className); + } + return names; + } + }, + + /** + * 方法匹配 + */ + METHOD { + + /** + * 后面有 .method()xxxx + */ + private final Pattern METHOD_PATTERN = Pattern.compile("((\\w+\\.)+(\\w+))(\\.\\w+\\(\\))"); + + @Override + public Iterable converter(Throwable throwable) { + + String message = throwable.getMessage(); + Matcher matcher = METHOD_PATTERN.matcher(message); + List names = new ArrayList<>(); + while (matcher.find()) { + String className = matcher.group(); + names.add(className); + } + return names; + } + } + } +} diff --git a/designer-base/src/main/java/com/fr/env/detect/impl/converter/ClassThrowableConvertor.java b/designer-base/src/main/java/com/fr/env/detect/impl/converter/ClassThrowableConvertor.java deleted file mode 100644 index 7fdd8bbe3..000000000 --- a/designer-base/src/main/java/com/fr/env/detect/impl/converter/ClassThrowableConvertor.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.fr.env.detect.impl.converter; - -import com.fr.env.detect.bean.DetectorResult; -import com.fr.env.detect.thowable.ThrowableConverter; - -import javax.el.MethodNotFoundException; -import java.util.HashSet; -import java.util.Set; - -/** - * 类抛出异常的转换 - * created by Harrison on 2022/05/24 - **/ -public class ClassThrowableConvertor implements ThrowableConverter { - - private Set> throwableClassSet = new HashSet<>(); - - private Set> throwableMethodSet = new HashSet<>(); - - public ClassThrowableConvertor() { - - // 类异常 - this.throwableClassSet.add(ClassNotFoundException.class); - this.throwableClassSet.add(NoClassDefFoundError.class); - this.throwableClassSet.add(ClassCastException.class); - this.throwableClassSet.add(IncompatibleClassChangeError.class); - - // 方法异常 - this.throwableMethodSet.add(MethodNotFoundException.class); - this.throwableMethodSet.add(NoSuchMethodException.class); - this.throwableMethodSet.add(NoSuchMethodError.class); - } - - @Override - public boolean accept(Throwable throwable) { - - Throwable sign = throwable; - while (sign != null) { - if (throwableClassSet.contains(sign.getClass()) || throwableMethodSet.contains(sign.getClass())) { - return true; - } - sign = sign.getCause(); - } - return false; - } - - @Override - public DetectorResult convert(Throwable throwable) { - - // todo - return null; - } -} diff --git a/designer-base/src/main/java/com/fr/env/detect/impl/converter/FineDbDirtyConverter.java b/designer-base/src/main/java/com/fr/env/detect/impl/converter/FineDbDirtyConverter.java index d23aa9915..962768eb4 100644 --- a/designer-base/src/main/java/com/fr/env/detect/impl/converter/FineDbDirtyConverter.java +++ b/designer-base/src/main/java/com/fr/env/detect/impl/converter/FineDbDirtyConverter.java @@ -1,10 +1,23 @@ package com.fr.env.detect.impl.converter; +import com.fr.config.ConfigContext; +import com.fr.config.Configuration; +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.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.log.FineLoggerFactory; import com.fr.third.org.hibernate.exception.GenericJDBCException; import org.jetbrains.annotations.Nullable; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + /** * created by Harrison on 2022/05/25 **/ @@ -15,7 +28,7 @@ public class FineDbDirtyConverter implements ThrowableConverter { Throwable sign = throwable; while (sign != null) { - if (sign instanceof GenericJDBCException) { + if (sign.getClass() == GenericJDBCException.class) { return true; } sign = sign.getCause(); @@ -27,7 +40,60 @@ public class FineDbDirtyConverter implements ThrowableConverter { public @Nullable DetectorResult convert(Throwable throwable) { // 检测 Config - // todo + Throwable sign = throwable; + while (sign.getClass() != GenericJDBCException.class) { + sign = sign.getCause(); + } + + Map configMap = getAllConfigurationClassName(); + StackTraceElement[] stackTrace = sign.getStackTrace(); + for (StackTraceElement stackTraceElement : stackTrace) { + String className = stackTraceElement.getClassName(); + if (configMap.containsKey(className)) { + + DetectorType detectorType = DetectorType.FINE_DB_DIRTY; + DetectorResult.DetectorResultBuilder builder = DetectorResult.builder() + .withType(detectorType); + + String tableName = configMap.get(className); + 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() { + @Override + public String name() { + // todo + return null; + } + + @Override + public void run() { + + } + }); + builder.withTips(tipsLocale) + .withSolution(exceptionSolution); + + String errorMsg = Toolkit.i18nText(detectorType.getLogLocale(), tableName); + FineLoggerFactory.getLogger().error(errorMsg); + return builder.build(); + } + } + return null; } + + private Map getAllConfigurationClassName() { + + Map configMap = new HashMap<>(); + Iterator tableNames = ConfigContext.getConfigNames(); + while (tableNames.hasNext()) { + String tableName = tableNames.next(); + Class configClass = ConfigContext.getConfigClass(tableName); + String className = configClass.getName(); + configMap.put(className, tableName); + } + return configMap; + + } } diff --git a/designer-base/src/main/java/com/fr/env/detect/impl/converter/FineDbLockedConverter.java b/designer-base/src/main/java/com/fr/env/detect/impl/converter/FineDbLockedConverter.java index 8924d688a..509cb30f3 100644 --- a/designer-base/src/main/java/com/fr/env/detect/impl/converter/FineDbLockedConverter.java +++ b/designer-base/src/main/java/com/fr/env/detect/impl/converter/FineDbLockedConverter.java @@ -1,6 +1,9 @@ package com.fr.env.detect.impl.converter; +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.thowable.ThrowableConverter; import com.fr.third.org.hsqldb.HsqlException; @@ -14,7 +17,7 @@ public class FineDbLockedConverter implements ThrowableConverter { Throwable sign = throwable; while (sign != null) { - if (sign instanceof HsqlException) { + if (sign.getClass() == HsqlException.class) { return true; } sign = sign.getCause(); @@ -25,7 +28,22 @@ public class FineDbLockedConverter implements ThrowableConverter { @Override public DetectorResult convert(Throwable throwable) { - // todo + Throwable sign = throwable; + while (sign.getClass() != HsqlException.class) { + sign = sign.getCause(); + } + + String message = sign.getMessage(); + if (message.contains("lock")) { + DetectorType type = DetectorType.FINE_DB_LOCKED; + String tipsLocale = type.getTipsLocale(); + + return DetectorResult.builder() + .withType(type) + .withTips(Toolkit.i18nText(tipsLocale)) + .withSolution(Toolkit.i18nText(type.getSolutionLocale()), DetectorConstants.FINE_DB_HELP_LINK) + .build(); + } return null; } } diff --git a/designer-base/src/main/java/com/fr/env/detect/impl/converter/FineDbPermissionConverter.java b/designer-base/src/main/java/com/fr/env/detect/impl/converter/FineDbPermissionConverter.java index 21722ebb4..7a7407ea9 100644 --- a/designer-base/src/main/java/com/fr/env/detect/impl/converter/FineDbPermissionConverter.java +++ b/designer-base/src/main/java/com/fr/env/detect/impl/converter/FineDbPermissionConverter.java @@ -1,6 +1,9 @@ package com.fr.env.detect.impl.converter; +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.thowable.ThrowableConverter; import com.fr.third.org.hsqldb.HsqlException; @@ -16,7 +19,7 @@ public class FineDbPermissionConverter implements ThrowableConverter { Throwable sign = throwable; while (sign != null) { - if (sign instanceof HsqlException) { + if (sign.getClass() == HsqlException.class) { return true; } sign = sign.getCause(); @@ -27,7 +30,22 @@ public class FineDbPermissionConverter implements ThrowableConverter { @Override public DetectorResult convert(Throwable throwable) { - // todo + Throwable sign = throwable; + while (sign.getClass() != HsqlException.class) { + sign = sign.getCause(); + } + + String message = sign.getMessage(); + if (message.contains("permission")) { + DetectorType type = DetectorType.FINE_DB_PERMISSION; + String tipsLocale = type.getTipsLocale(); + + return DetectorResult.builder() + .withType(type) + .withTips(Toolkit.i18nText(tipsLocale)) + .withSolution(Toolkit.i18nText(type.getSolutionLocale()), DetectorConstants.FINE_DB_HELP_LINK) + .build(); + } return null; } } diff --git a/designer-base/src/test/java/com/fr/env/detect/impl/converter/ClassConfictConvertorTest.java b/designer-base/src/test/java/com/fr/env/detect/impl/converter/ClassConfictConvertorTest.java new file mode 100644 index 000000000..bf43c5560 --- /dev/null +++ b/designer-base/src/test/java/com/fr/env/detect/impl/converter/ClassConfictConvertorTest.java @@ -0,0 +1,23 @@ +package com.fr.env.detect.impl.converter; + +import org.junit.Test; + +public class ClassConfictConvertorTest { + + @Test + public void testInnerFinder() { + + ClassNotFoundException ex1 = new ClassNotFoundException("Class 111.222.333 not found"); + Iterable names = ClassConfictConvertor.Converter.CLASS.converter(ex1); + + System.out.println(); + } + + @Test + public void testConverter() { + + ClassNotFoundException ex1 = new ClassNotFoundException("com.zaxxer.hikari.HikariConfig"); + ClassConfictConvertor convertor = new ClassConfictConvertor(); + convertor.convert(ex1); + } +} \ No newline at end of file