Harrison
3 years ago
27 changed files with 1092 additions and 0 deletions
@ -0,0 +1,19 @@ |
|||||||
|
package com.fr.env.detect.base; |
||||||
|
|
||||||
|
import com.fr.env.detect.bean.DetectorType; |
||||||
|
|
||||||
|
/** |
||||||
|
* created by Harrison on 2022/05/13 |
||||||
|
**/ |
||||||
|
public abstract class AbstractExceptionDetector implements ExceptionDetector { |
||||||
|
|
||||||
|
private DetectorType key; |
||||||
|
|
||||||
|
public AbstractExceptionDetector(DetectorType key) { |
||||||
|
this.key = key; |
||||||
|
} |
||||||
|
|
||||||
|
public DetectorType type() { |
||||||
|
return key; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,44 @@ |
|||||||
|
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.thowable.ThrowableConverter; |
||||||
|
import com.fr.env.detect.thowable.ThrowableStore; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* created by Harrison on 2022/05/13 |
||||||
|
**/ |
||||||
|
public abstract class CatchExceptionDetector extends AbstractExceptionDetector { |
||||||
|
|
||||||
|
private ThrowableStore throwableStore; |
||||||
|
|
||||||
|
private ThrowableConverter throwableConverter; |
||||||
|
|
||||||
|
public CatchExceptionDetector(DetectorType key, ThrowableStore throwableStore, ThrowableConverter throwableConverter) { |
||||||
|
super(key); |
||||||
|
this.throwableStore = throwableStore; |
||||||
|
this.throwableConverter = throwableConverter; |
||||||
|
} |
||||||
|
|
||||||
|
public ThrowableStore getThrowableStore() { |
||||||
|
return throwableStore; |
||||||
|
} |
||||||
|
|
||||||
|
public ThrowableConverter getThrowableConverter() { |
||||||
|
return throwableConverter; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public DetectorResult detect() { |
||||||
|
|
||||||
|
List<Throwable> throwableList = throwableStore.getAll(); |
||||||
|
for (Throwable throwable : throwableList) { |
||||||
|
if (throwableConverter.accept(throwable)) { |
||||||
|
return throwableConverter.convert(throwable); |
||||||
|
} |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,95 @@ |
|||||||
|
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.thowable.ThrowableLogAppender; |
||||||
|
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; |
||||||
|
|
||||||
|
/** |
||||||
|
* created by Harrison on 2022/05/13 |
||||||
|
**/ |
||||||
|
public class DetectorBridge { |
||||||
|
|
||||||
|
public static DetectorBridge getInstance() { |
||||||
|
|
||||||
|
return DetectorBridgeHolder.INSTANCE; |
||||||
|
} |
||||||
|
|
||||||
|
private static class DetectorBridgeHolder { |
||||||
|
|
||||||
|
private static final DetectorBridge INSTANCE = new DetectorBridge(); |
||||||
|
} |
||||||
|
|
||||||
|
private final NotNullLazyValue<ThrowableBridge> throwableBridge = new NotNullLazyValue<ThrowableBridge>() { |
||||||
|
@Override |
||||||
|
protected @NotNull ThrowableBridge compute() { |
||||||
|
|
||||||
|
return new ThrowableBridge(); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
private final NotNullLazyValue<DetectorManager> detectorManager = new NotNullLazyValue<DetectorManager>() { |
||||||
|
|
||||||
|
@Override |
||||||
|
protected @NotNull DetectorManager compute() { |
||||||
|
|
||||||
|
return new DetectorManager(); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
private final AtomicBoolean hasStarted = new AtomicBoolean(false); |
||||||
|
|
||||||
|
public void start() { |
||||||
|
|
||||||
|
if (ExceptionDetectorConfig.getInstance().isOpen()) { |
||||||
|
// 开始注册异常处理
|
||||||
|
ThrowableLogAppender.getInstance().enable(); |
||||||
|
hasStarted.set(true); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void stop() { |
||||||
|
|
||||||
|
if (hasStarted.compareAndSet(true, false)) { |
||||||
|
// 关闭异常处理
|
||||||
|
ThrowableLogAppender.getInstance().disable(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 执行-检测异常 |
||||||
|
* |
||||||
|
* @return 能够检测出的异常情况 |
||||||
|
*/ |
||||||
|
public Stream<DetectorResult> detect() { |
||||||
|
|
||||||
|
return detectorManager.getValue().detect(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 针对某一项进行检测 |
||||||
|
* |
||||||
|
* @param type 检测类型 |
||||||
|
* @return 检测结果 |
||||||
|
*/ |
||||||
|
public Optional<DetectorResult> detect(DetectorType type) { |
||||||
|
|
||||||
|
return detectorManager.getValue().detect(type); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 执行-捕获异常 |
||||||
|
* |
||||||
|
* @param throwable 异常 |
||||||
|
* @return 检测结果 |
||||||
|
*/ |
||||||
|
public Optional<DetectorResult> convert(Throwable throwable) { |
||||||
|
|
||||||
|
return throwableBridge.getValue().convert(throwable); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,40 @@ |
|||||||
|
package com.fr.env.detect.base; |
||||||
|
|
||||||
|
import com.fr.env.detect.bean.DetectorType; |
||||||
|
import com.fr.env.detect.bean.DetectorResult; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Objects; |
||||||
|
import java.util.Optional; |
||||||
|
import java.util.stream.Stream; |
||||||
|
|
||||||
|
/** |
||||||
|
* created by Harrison on 2022/05/24 |
||||||
|
**/ |
||||||
|
class DetectorManager { |
||||||
|
|
||||||
|
private List<ExceptionDetector> detectors = new ArrayList<>(); |
||||||
|
|
||||||
|
public void register(ExceptionDetector detector) { |
||||||
|
|
||||||
|
if (detector != null) { |
||||||
|
detectors.add(detector); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public Stream<DetectorResult> detect() { |
||||||
|
|
||||||
|
return detectors.stream() |
||||||
|
.map(ExceptionDetector::detect) |
||||||
|
.filter(Objects::nonNull); |
||||||
|
} |
||||||
|
|
||||||
|
public Optional<DetectorResult> detect(DetectorType type) { |
||||||
|
|
||||||
|
return detectors.stream() |
||||||
|
.filter((detector -> type == detector.type())) |
||||||
|
.findFirst() |
||||||
|
.map(ExceptionDetector::detect); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,25 @@ |
|||||||
|
package com.fr.env.detect.base; |
||||||
|
|
||||||
|
import com.fr.env.detect.bean.DetectorType; |
||||||
|
import com.fr.env.detect.bean.DetectorResult; |
||||||
|
|
||||||
|
/** |
||||||
|
* created by Harrison on 2022/05/13 |
||||||
|
**/ |
||||||
|
public interface ExceptionDetector { |
||||||
|
|
||||||
|
/** |
||||||
|
* 检测类型 |
||||||
|
* |
||||||
|
* @return TYPE |
||||||
|
*/ |
||||||
|
DetectorType type(); |
||||||
|
|
||||||
|
/** |
||||||
|
* 检测结果 |
||||||
|
* |
||||||
|
* @return 结果 |
||||||
|
*/ |
||||||
|
DetectorResult detect(); |
||||||
|
|
||||||
|
} |
@ -0,0 +1,21 @@ |
|||||||
|
package com.fr.env.detect.base; |
||||||
|
|
||||||
|
/** |
||||||
|
* created by Harrison on 2022/05/13 |
||||||
|
**/ |
||||||
|
public class ExceptionDetectorConfig { |
||||||
|
|
||||||
|
|
||||||
|
public static ExceptionDetectorConfig getInstance() { |
||||||
|
return ExceptionDetectorConfigHolder.INSTANCE; |
||||||
|
} |
||||||
|
|
||||||
|
private static class ExceptionDetectorConfigHolder { |
||||||
|
private static final ExceptionDetectorConfig INSTANCE = new ExceptionDetectorConfig(); |
||||||
|
} |
||||||
|
|
||||||
|
public boolean isOpen() { |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,40 @@ |
|||||||
|
package com.fr.env.detect.base; |
||||||
|
|
||||||
|
import com.fr.env.detect.bean.DetectorResult; |
||||||
|
import com.fr.env.detect.thowable.ThrowableConverter; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Objects; |
||||||
|
import java.util.Optional; |
||||||
|
|
||||||
|
/** |
||||||
|
* created by Harrison on 2022/05/13 |
||||||
|
**/ |
||||||
|
class ThrowableBridge { |
||||||
|
|
||||||
|
private List<ThrowableConverter> throwableConverters = new ArrayList<>(); |
||||||
|
|
||||||
|
public void register(ThrowableConverter throwableConverter) { |
||||||
|
|
||||||
|
if (throwableConverter != null) { |
||||||
|
throwableConverters.add(throwableConverter); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 将 throwable 转化成检测的结果 |
||||||
|
* |
||||||
|
* @param throwable 异常 |
||||||
|
* @return 结果 |
||||||
|
*/ |
||||||
|
public Optional<DetectorResult> convert(Throwable throwable) { |
||||||
|
|
||||||
|
return throwableConverters |
||||||
|
.stream() |
||||||
|
.filter((e) -> e.accept(throwable)) |
||||||
|
.map((e) -> e.convert(throwable)) |
||||||
|
.filter(Objects::nonNull) |
||||||
|
.findFirst(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,4 @@ |
|||||||
|
/** |
||||||
|
* 设计器环境检测 见 {@see https://kms.fineres.com/pages/viewpage.action?pageId=388333688}
|
||||||
|
*/ |
||||||
|
package com.fr.env.detect.base; |
@ -0,0 +1,102 @@ |
|||||||
|
package com.fr.env.detect.bean; |
||||||
|
|
||||||
|
import org.jetbrains.annotations.Nullable; |
||||||
|
|
||||||
|
/** |
||||||
|
* 检测结果 |
||||||
|
* |
||||||
|
* created by Harrison on 2022/05/13 |
||||||
|
**/ |
||||||
|
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) { |
||||||
|
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; |
||||||
|
} |
||||||
|
|
||||||
|
@Nullable |
||||||
|
public ExceptionSolution getSolution() { |
||||||
|
return solution; |
||||||
|
} |
||||||
|
|
||||||
|
@Nullable |
||||||
|
public ExceptionLog getExceptionLog() { |
||||||
|
return exceptionLog; |
||||||
|
} |
||||||
|
|
||||||
|
public static DetectorResultBuilder builder() { |
||||||
|
|
||||||
|
return new DetectorResultBuilder(); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public static final class DetectorResultBuilder { |
||||||
|
|
||||||
|
private DetectorType type; |
||||||
|
private DetectorStatus status; |
||||||
|
|
||||||
|
private ExceptionTips tips; |
||||||
|
private ExceptionSolution solution; |
||||||
|
private ExceptionLog exceptionLog; |
||||||
|
|
||||||
|
private DetectorResultBuilder() { |
||||||
|
} |
||||||
|
|
||||||
|
public DetectorResultBuilder withType(DetectorType type) { |
||||||
|
this.type = type; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public DetectorResultBuilder withStatus(DetectorStatus status) { |
||||||
|
this.status = status; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public DetectorResultBuilder withTips(ExceptionTips tips) { |
||||||
|
this.tips = tips; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public DetectorResultBuilder withSolution(ExceptionSolution solution) { |
||||||
|
this.solution = solution; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public DetectorResultBuilder withExceptionLog(ExceptionLog exceptionLog) { |
||||||
|
this.exceptionLog = exceptionLog; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public DetectorResult build() { |
||||||
|
|
||||||
|
DetectorResult detectorResult = new DetectorResult(type, tips, solution, exceptionLog); |
||||||
|
detectorResult.status = this.status; |
||||||
|
return detectorResult; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,22 @@ |
|||||||
|
package com.fr.env.detect.bean; |
||||||
|
|
||||||
|
/** |
||||||
|
* created by Harrison on 2022/05/25 |
||||||
|
**/ |
||||||
|
public enum DetectorStatus { |
||||||
|
|
||||||
|
/** |
||||||
|
* 成功 |
||||||
|
*/ |
||||||
|
SUCCESS, |
||||||
|
|
||||||
|
/** |
||||||
|
* 失败 |
||||||
|
*/ |
||||||
|
FAILED, |
||||||
|
|
||||||
|
/** |
||||||
|
* 异常 |
||||||
|
*/ |
||||||
|
UNKNOWN |
||||||
|
} |
@ -0,0 +1,88 @@ |
|||||||
|
package com.fr.env.detect.bean; |
||||||
|
|
||||||
|
/** |
||||||
|
* 检测的原生数据 |
||||||
|
* |
||||||
|
* created by Harrison on 2022/05/13 |
||||||
|
**/ |
||||||
|
public enum DetectorType { |
||||||
|
|
||||||
|
/** |
||||||
|
* 缺少 JAR |
||||||
|
*/ |
||||||
|
LACK_OF_JAR(Kind.JAR, WorkType.LOCAL), |
||||||
|
|
||||||
|
/** |
||||||
|
* JAR 包版本不一致 |
||||||
|
*/ |
||||||
|
JAR_IN_CONSISTENCE(Kind.JAR, WorkType.SIMPLE), |
||||||
|
|
||||||
|
/** |
||||||
|
* JAR 包冲突 |
||||||
|
*/ |
||||||
|
JAR_CONFLICT(Kind.JAR, WorkType.REMOTE), |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* FineDB 权限问题 |
||||||
|
*/ |
||||||
|
FINE_DB_PERMISSION(Kind.FINE_DB, WorkType.LOCAL), |
||||||
|
|
||||||
|
/** |
||||||
|
* FineDB 锁 |
||||||
|
*/ |
||||||
|
FINE_DB_LOCKED(Kind.FINE_DB, WorkType.LOCAL), |
||||||
|
|
||||||
|
/** |
||||||
|
* FineDB 脏数据 |
||||||
|
*/ |
||||||
|
FINE_DB_DIRTY(Kind.FINE_DB, WorkType.SIMPLE) |
||||||
|
; |
||||||
|
|
||||||
|
private final Kind kind; |
||||||
|
|
||||||
|
private final WorkType workType; |
||||||
|
|
||||||
|
DetectorType(Kind kind, WorkType workType) { |
||||||
|
|
||||||
|
this.kind = kind; |
||||||
|
this.workType = workType; |
||||||
|
} |
||||||
|
|
||||||
|
public Kind getKind() { |
||||||
|
return kind; |
||||||
|
} |
||||||
|
|
||||||
|
public WorkType getWorkType() { |
||||||
|
return workType; |
||||||
|
} |
||||||
|
|
||||||
|
public enum Kind { |
||||||
|
|
||||||
|
/** |
||||||
|
* JAR 类型 |
||||||
|
*/ |
||||||
|
JAR, |
||||||
|
/** |
||||||
|
* FineDB 类型 |
||||||
|
*/ |
||||||
|
FINE_DB |
||||||
|
} |
||||||
|
|
||||||
|
public enum WorkType { |
||||||
|
|
||||||
|
/** |
||||||
|
* 本地 |
||||||
|
*/ |
||||||
|
LOCAL, |
||||||
|
/** |
||||||
|
* 远程 |
||||||
|
*/ |
||||||
|
REMOTE, |
||||||
|
/** |
||||||
|
* 全部 |
||||||
|
*/ |
||||||
|
SIMPLE |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,24 @@ |
|||||||
|
package com.fr.env.detect.bean; |
||||||
|
|
||||||
|
/** |
||||||
|
* created by Harrison on 2022/05/13 |
||||||
|
**/ |
||||||
|
public class ExceptionLog { |
||||||
|
|
||||||
|
private final String errorCode; |
||||||
|
|
||||||
|
private final String locale; |
||||||
|
|
||||||
|
public ExceptionLog(String errorCode, String locale) { |
||||||
|
this.errorCode = errorCode; |
||||||
|
this.locale = locale; |
||||||
|
} |
||||||
|
|
||||||
|
public String getErrorCode() { |
||||||
|
return errorCode; |
||||||
|
} |
||||||
|
|
||||||
|
public String getLocale() { |
||||||
|
return locale; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,24 @@ |
|||||||
|
package com.fr.env.detect.bean; |
||||||
|
|
||||||
|
/** |
||||||
|
* created by Harrison on 2022/05/13 |
||||||
|
**/ |
||||||
|
public class ExceptionSolution { |
||||||
|
|
||||||
|
private Message message; |
||||||
|
|
||||||
|
private SolutionAction action; |
||||||
|
|
||||||
|
public ExceptionSolution(Message message, SolutionAction action) { |
||||||
|
this.message = message; |
||||||
|
this.action = action; |
||||||
|
} |
||||||
|
|
||||||
|
public Message getMessage() { |
||||||
|
return message; |
||||||
|
} |
||||||
|
|
||||||
|
public SolutionAction getAction() { |
||||||
|
return action; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,19 @@ |
|||||||
|
package com.fr.env.detect.bean; |
||||||
|
|
||||||
|
/** |
||||||
|
* 异常提示 |
||||||
|
* |
||||||
|
* created by Harrison on 2022/05/13 |
||||||
|
**/ |
||||||
|
public class ExceptionTips { |
||||||
|
|
||||||
|
private Message message; |
||||||
|
|
||||||
|
public ExceptionTips(Message message) { |
||||||
|
this.message = message; |
||||||
|
} |
||||||
|
|
||||||
|
public Message getMessage() { |
||||||
|
return message; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,70 @@ |
|||||||
|
package com.fr.env.detect.bean; |
||||||
|
|
||||||
|
/** |
||||||
|
* created by Harrison on 2022/05/24 |
||||||
|
**/ |
||||||
|
public interface Message { |
||||||
|
|
||||||
|
/** |
||||||
|
* 消息类型 |
||||||
|
* |
||||||
|
* @return 类型 |
||||||
|
*/ |
||||||
|
Type getType(); |
||||||
|
|
||||||
|
enum Type { |
||||||
|
|
||||||
|
/** |
||||||
|
* 简单 |
||||||
|
*/ |
||||||
|
SIMPLE, |
||||||
|
|
||||||
|
/** |
||||||
|
* 链接 |
||||||
|
*/ |
||||||
|
LINK |
||||||
|
} |
||||||
|
|
||||||
|
class Simple implements Message { |
||||||
|
|
||||||
|
private String message; |
||||||
|
|
||||||
|
public Simple(String message) { |
||||||
|
this.message = message; |
||||||
|
} |
||||||
|
|
||||||
|
public String getMessage() { |
||||||
|
return message; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Type getType() { |
||||||
|
return Type.SIMPLE; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
class Link implements Message { |
||||||
|
|
||||||
|
private String text; |
||||||
|
|
||||||
|
private String link; |
||||||
|
|
||||||
|
public Link(String text, String link) { |
||||||
|
this.text = text; |
||||||
|
this.link = link; |
||||||
|
} |
||||||
|
|
||||||
|
public String getText() { |
||||||
|
return text; |
||||||
|
} |
||||||
|
|
||||||
|
public String getLink() { |
||||||
|
return link; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Type getType() { |
||||||
|
return Type.LINK; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,11 @@ |
|||||||
|
package com.fr.env.detect.bean; |
||||||
|
|
||||||
|
/** |
||||||
|
* created by Harrison on 2022/05/24 |
||||||
|
**/ |
||||||
|
public interface SolutionAction { |
||||||
|
|
||||||
|
String name(); |
||||||
|
|
||||||
|
void run(); |
||||||
|
} |
@ -0,0 +1,26 @@ |
|||||||
|
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); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,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; |
||||||
|
|
||||||
|
/** |
||||||
|
* created by Harrison on 2022/05/25 |
||||||
|
**/ |
||||||
|
public class HsqlDirtyDetector extends CatchExceptionDetector { |
||||||
|
|
||||||
|
public HsqlDirtyDetector(ThrowableStore throwableStore) { |
||||||
|
|
||||||
|
super(DetectorType.FINE_DB_DIRTY, throwableStore, new FineDbDirtyConverter()); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,85 @@ |
|||||||
|
package com.fr.env.detect.impl; |
||||||
|
|
||||||
|
import com.fr.env.detect.base.AbstractExceptionDetector; |
||||||
|
import com.fr.env.detect.bean.DetectorResult; |
||||||
|
import com.fr.env.detect.bean.DetectorType; |
||||||
|
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.third.guava.collect.MapDifference; |
||||||
|
import com.fr.third.guava.collect.Maps; |
||||||
|
import com.fr.workspace.WorkContext; |
||||||
|
|
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Map; |
||||||
|
import java.util.stream.Collectors; |
||||||
|
|
||||||
|
/** |
||||||
|
* created by Harrison on 2022/05/25 |
||||||
|
**/ |
||||||
|
public class JarInconsistentDetector extends AbstractExceptionDetector { |
||||||
|
|
||||||
|
public JarInconsistentDetector() { |
||||||
|
|
||||||
|
super(DetectorType.JAR_IN_CONSISTENCE); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public DetectorResult detect() { |
||||||
|
|
||||||
|
DetectorResult.DetectorResultBuilder builder = DetectorResult.builder(); |
||||||
|
// 检测有哪些 JAR 包, 当前是否缺少对应的 JAR 包
|
||||||
|
BuildInfoOperator buildInfoOperator = WorkContext.getCurrent().get(BuildInfoOperator.class); |
||||||
|
List<BuildInfo> buildInfos = buildInfoOperator.getBuildInfos(); |
||||||
|
|
||||||
|
if (WorkContext.getCurrent().isLocal()) { |
||||||
|
|
||||||
|
String designerBuild = buildInfos.stream() |
||||||
|
.filter(this::isDesignerJar) |
||||||
|
.map(BuildInfo::getGroupBuild) |
||||||
|
.filter(StringUtils::isNotEmpty) |
||||||
|
.findFirst() |
||||||
|
.orElseThrow(DetectorException::new); |
||||||
|
|
||||||
|
List<BuildInfo> inConsistentInfos = buildInfos.stream() |
||||||
|
.filter((e) -> !StringUtils.equals(designerBuild, e.getGroupBuild())) |
||||||
|
.collect(Collectors.toList()); |
||||||
|
|
||||||
|
} else { |
||||||
|
|
||||||
|
// 远程情况
|
||||||
|
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); |
||||||
|
// 两边都有的 JAR 的不同之处
|
||||||
|
Map<String, String> diffInCommon = difference.entriesInCommon(); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
return builder.build(); |
||||||
|
} |
||||||
|
|
||||||
|
private boolean isDesignerJar(BuildInfo info) { |
||||||
|
|
||||||
|
return StringUtils.contains(info.getJar(), "fine-report-designer"); |
||||||
|
} |
||||||
|
|
||||||
|
private Map<String, String> groupBy(List<BuildInfo> localInfos) { |
||||||
|
|
||||||
|
Map<String, String> localMap = new HashMap<>(); |
||||||
|
for (BuildInfo localInfo : localInfos) { |
||||||
|
String jar = localInfo.getJar(); |
||||||
|
String groupContent = localInfo.getGroupBuild(); |
||||||
|
localMap.put(jar, groupContent); |
||||||
|
} |
||||||
|
return localMap; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,43 @@ |
|||||||
|
package com.fr.env.detect.impl; |
||||||
|
|
||||||
|
import com.fr.env.detect.base.AbstractExceptionDetector; |
||||||
|
import com.fr.env.detect.bean.DetectorResult; |
||||||
|
import com.fr.env.detect.bean.DetectorType; |
||||||
|
import com.fr.general.build.BuildInfo; |
||||||
|
import com.fr.general.build.BuildInfoOperator; |
||||||
|
import com.fr.stable.StringUtils; |
||||||
|
import com.fr.workspace.WorkContext; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* created by Harrison on 2022/05/24 |
||||||
|
**/ |
||||||
|
public class JarLackDetector extends AbstractExceptionDetector { |
||||||
|
|
||||||
|
public JarLackDetector() { |
||||||
|
super(DetectorType.LACK_OF_JAR); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public DetectorResult detect() { |
||||||
|
|
||||||
|
DetectorResult.DetectorResultBuilder builder = DetectorResult.builder(); |
||||||
|
|
||||||
|
// 检测有哪些 JAR 包, 当前是否缺少对应的 JAR 包
|
||||||
|
BuildInfoOperator buildInfoOperator = WorkContext.getCurrent().get(BuildInfoOperator.class); |
||||||
|
List<BuildInfo> buildInfos = buildInfoOperator.getBuildInfos(); |
||||||
|
for (BuildInfo buildInfo : buildInfos) { |
||||||
|
String jar = buildInfo.getJar(); |
||||||
|
String buildContent = buildInfo.getGroupBuild(); |
||||||
|
boolean isLack = StringUtils.isEmpty(buildContent); |
||||||
|
if (isLack) { |
||||||
|
// 处理信息
|
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return builder.build(); |
||||||
|
|
||||||
|
} |
||||||
|
} |
@ -0,0 +1,53 @@ |
|||||||
|
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<Class<?>> throwableClassSet = new HashSet<>(); |
||||||
|
|
||||||
|
private Set<Class<?>> 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; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,33 @@ |
|||||||
|
package com.fr.env.detect.impl.converter; |
||||||
|
|
||||||
|
import com.fr.env.detect.bean.DetectorResult; |
||||||
|
import com.fr.env.detect.thowable.ThrowableConverter; |
||||||
|
import com.fr.third.org.hibernate.exception.GenericJDBCException; |
||||||
|
import org.jetbrains.annotations.Nullable; |
||||||
|
|
||||||
|
/** |
||||||
|
* created by Harrison on 2022/05/25 |
||||||
|
**/ |
||||||
|
public class FineDbDirtyConverter implements ThrowableConverter { |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean accept(Throwable throwable) { |
||||||
|
|
||||||
|
Throwable sign = throwable; |
||||||
|
while (sign != null) { |
||||||
|
if (sign instanceof GenericJDBCException) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
sign = sign.getCause(); |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public @Nullable DetectorResult convert(Throwable throwable) { |
||||||
|
|
||||||
|
// 检测 Config
|
||||||
|
// todo
|
||||||
|
return null; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,31 @@ |
|||||||
|
package com.fr.env.detect.impl.converter; |
||||||
|
|
||||||
|
import com.fr.env.detect.bean.DetectorResult; |
||||||
|
import com.fr.env.detect.thowable.ThrowableConverter; |
||||||
|
import com.fr.third.org.hsqldb.HsqlException; |
||||||
|
|
||||||
|
/** |
||||||
|
* created by Harrison on 2022/05/24 |
||||||
|
**/ |
||||||
|
public class FineDbLockedConverter implements ThrowableConverter { |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean accept(Throwable throwable) { |
||||||
|
|
||||||
|
Throwable sign = throwable; |
||||||
|
while (sign != null) { |
||||||
|
if (sign instanceof HsqlException) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
sign = sign.getCause(); |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public DetectorResult convert(Throwable throwable) { |
||||||
|
|
||||||
|
// todo
|
||||||
|
return null; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,33 @@ |
|||||||
|
package com.fr.env.detect.impl.converter; |
||||||
|
|
||||||
|
import com.fr.env.detect.bean.DetectorResult; |
||||||
|
import com.fr.env.detect.thowable.ThrowableConverter; |
||||||
|
import com.fr.third.org.hsqldb.HsqlException; |
||||||
|
|
||||||
|
/** |
||||||
|
* HSQL 下的权限检测 |
||||||
|
* |
||||||
|
* created by Harrison on 2022/05/24 |
||||||
|
**/ |
||||||
|
public class FineDbPermissionConverter implements ThrowableConverter { |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean accept(Throwable throwable) { |
||||||
|
|
||||||
|
Throwable sign = throwable; |
||||||
|
while (sign != null) { |
||||||
|
if (sign instanceof HsqlException) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
sign = sign.getCause(); |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public DetectorResult convert(Throwable throwable) { |
||||||
|
|
||||||
|
// todo
|
||||||
|
return null; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,28 @@ |
|||||||
|
package com.fr.env.detect.thowable; |
||||||
|
|
||||||
|
import com.fr.env.detect.bean.DetectorResult; |
||||||
|
import org.jetbrains.annotations.Nullable; |
||||||
|
|
||||||
|
/** |
||||||
|
* created by Harrison on 2022/05/13 |
||||||
|
**/ |
||||||
|
public interface ThrowableConverter { |
||||||
|
|
||||||
|
/** |
||||||
|
* 是否支持该异常 |
||||||
|
* |
||||||
|
* @param throwable 异常 |
||||||
|
* @return 是/否 |
||||||
|
*/ |
||||||
|
boolean accept(Throwable throwable); |
||||||
|
|
||||||
|
/** |
||||||
|
* 将异常转化为结果 |
||||||
|
* |
||||||
|
* @param throwable 异常 |
||||||
|
* @return 转化结果 |
||||||
|
*/ |
||||||
|
@Nullable |
||||||
|
DetectorResult convert(Throwable throwable); |
||||||
|
|
||||||
|
} |
@ -0,0 +1,58 @@ |
|||||||
|
package com.fr.env.detect.thowable; |
||||||
|
|
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
import com.fr.log.LogHandler; |
||||||
|
import com.fr.third.apache.logging.log4j.Level; |
||||||
|
import com.fr.third.apache.logging.log4j.core.Filter; |
||||||
|
import com.fr.third.apache.logging.log4j.core.Layout; |
||||||
|
import com.fr.third.apache.logging.log4j.core.LogEvent; |
||||||
|
import com.fr.third.apache.logging.log4j.core.appender.AbstractAppender; |
||||||
|
import com.fr.third.apache.logging.log4j.core.config.Property; |
||||||
|
|
||||||
|
import java.io.Serializable; |
||||||
|
|
||||||
|
/** |
||||||
|
* created by Harrison on 2022/05/13 |
||||||
|
**/ |
||||||
|
public class ThrowableLogAppender extends AbstractAppender { |
||||||
|
|
||||||
|
public ThrowableLogAppender(String name, Filter filter, Layout<? extends Serializable> layout, boolean ignoreExceptions, Property[] properties) { |
||||||
|
super(name, filter, layout, ignoreExceptions, properties); |
||||||
|
} |
||||||
|
|
||||||
|
public static ThrowableLogAppender getInstance() { |
||||||
|
return ExceptionLogAppenderHolder.INSTANCE; |
||||||
|
} |
||||||
|
|
||||||
|
private static class ExceptionLogAppenderHolder { |
||||||
|
private static final ThrowableLogAppender INSTANCE = new ThrowableLogAppender("exception-detect", null, null, false, null); |
||||||
|
} |
||||||
|
|
||||||
|
private LogHandler<ThrowableLogAppender> logHandler = toHandler(); |
||||||
|
|
||||||
|
@Override |
||||||
|
public void append(LogEvent logEvent) { |
||||||
|
|
||||||
|
if (logEvent.getLevel() == Level.ERROR) { |
||||||
|
Throwable thrown = logEvent.getThrown(); |
||||||
|
ThrowableStore.getInstance().add(thrown); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private LogHandler<ThrowableLogAppender> toHandler() { |
||||||
|
|
||||||
|
final ThrowableLogAppender appender = this; |
||||||
|
return () -> appender; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public void enable() { |
||||||
|
|
||||||
|
FineLoggerFactory.getLogger().addLogAppender(logHandler); |
||||||
|
} |
||||||
|
|
||||||
|
public void disable() { |
||||||
|
|
||||||
|
FineLoggerFactory.getLogger().removeLogAppender(logHandler); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,36 @@ |
|||||||
|
package com.fr.env.detect.thowable; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* 异常存储中心 |
||||||
|
* |
||||||
|
* created by Harrison on 2022/05/13 |
||||||
|
**/ |
||||||
|
public class ThrowableStore { |
||||||
|
|
||||||
|
public static ThrowableStore getInstance() { |
||||||
|
return ThrowableStoreHolder.INSTANCE; |
||||||
|
} |
||||||
|
|
||||||
|
private static class ThrowableStoreHolder { |
||||||
|
private static final ThrowableStore INSTANCE = new ThrowableStore(); |
||||||
|
} |
||||||
|
|
||||||
|
private List<Throwable> exceptions = new ArrayList<>(); |
||||||
|
|
||||||
|
public void add(Throwable throwable) { |
||||||
|
if (throwable != null) { |
||||||
|
exceptions.add(throwable); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public List<Throwable> getAll() { |
||||||
|
return exceptions; |
||||||
|
} |
||||||
|
|
||||||
|
public void reset() { |
||||||
|
exceptions.clear(); |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue