From 1e0cc4ecc930a1d55c753e4e10b3025b73f851b7 Mon Sep 17 00:00:00 2001 From: patrick Date: Wed, 14 Aug 2024 17:41:00 +0800 Subject: [PATCH] add more builtin tools --- .../io/fluent/builtin/crypto/AesUtil.java | 124 ++++++++++++++ .../io/fluent/builtin/crypto/DesUtil.java | 88 ++++++++++ .../builtin/exception/EncryptException.java | 9 + .../builtin/exception/SystemException.java | 13 ++ .../exception/WrapMessageException.java | 19 +++ .../io/fluent/builtin/meta/TargetType.java | 32 ++++ .../builtin/time/DateFormatterPattern.java | 156 ++++++++++++++++++ .../io/fluent/builtin/time/DateParseUtil.java | 135 +++++++++++++++ .../fluent/builtin/time/TimeDifferUtil.java | 81 +++++++++ components/fluent-loader/pom.xml | 42 +++++ .../io/fluent/loader/dep/DependencyAware.java | 21 +++ .../java/io/fluent/loader/package-info.java | 1 + .../io/fluent/spring/config/SpringConfig.java | 2 +- .../io/fluent/spring/util/SpringUtils.java | 1 - .../main/resources/META-INF/spring.factories | 2 + components/pom.xml | 1 + references.yaml | 4 +- 17 files changed, 727 insertions(+), 4 deletions(-) create mode 100644 components/fluent-builtin/src/main/java/io/fluent/builtin/crypto/AesUtil.java create mode 100644 components/fluent-builtin/src/main/java/io/fluent/builtin/crypto/DesUtil.java create mode 100644 components/fluent-builtin/src/main/java/io/fluent/builtin/exception/EncryptException.java create mode 100644 components/fluent-builtin/src/main/java/io/fluent/builtin/exception/SystemException.java create mode 100644 components/fluent-builtin/src/main/java/io/fluent/builtin/exception/WrapMessageException.java create mode 100644 components/fluent-builtin/src/main/java/io/fluent/builtin/meta/TargetType.java create mode 100644 components/fluent-builtin/src/main/java/io/fluent/builtin/time/DateFormatterPattern.java create mode 100644 components/fluent-builtin/src/main/java/io/fluent/builtin/time/DateParseUtil.java create mode 100644 components/fluent-builtin/src/main/java/io/fluent/builtin/time/TimeDifferUtil.java create mode 100644 components/fluent-loader/pom.xml create mode 100644 components/fluent-loader/src/main/java/io/fluent/loader/dep/DependencyAware.java create mode 100644 components/fluent-loader/src/main/java/io/fluent/loader/package-info.java create mode 100644 components/fluent-spring/src/main/resources/META-INF/spring.factories diff --git a/components/fluent-builtin/src/main/java/io/fluent/builtin/crypto/AesUtil.java b/components/fluent-builtin/src/main/java/io/fluent/builtin/crypto/AesUtil.java new file mode 100644 index 0000000..d691cc1 --- /dev/null +++ b/components/fluent-builtin/src/main/java/io/fluent/builtin/crypto/AesUtil.java @@ -0,0 +1,124 @@ +package io.fluent.builtin.crypto; + + +import io.fluent.builtin.exception.EncryptException; + +import javax.crypto.Cipher; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; +import java.nio.charset.StandardCharsets; +import java.util.Base64; + +/** + * AES-128-CBC 算法 + * iv 默认取key + */ +public class AesUtil { + + /** + * AES + */ + static String ALGORITHM = "AES"; + /** + * AES 算法 + */ + static String AES_CBC_CIPHER = "AES/CBC/PKCS5Padding"; + /** + * 偏移量 + */ + private static final int OFFSET = 16; + + + /** + * 加密 + * + * @param data 需要加密的内容 + * @param key 加密密码 + * @param iv 加密密码 + * @return + */ + public static byte[] encrypt(byte[] data, byte[] key, byte[] iv) { + try { + if (key.length < OFFSET) { + byte[] tmp = new byte[OFFSET]; + System.arraycopy(key, 0, tmp, 0, key.length); + key = tmp; + } + if (iv.length < 16) { + byte[] tmp = new byte[16]; + System.arraycopy(iv, 0, tmp, 0, iv.length); + iv = tmp; + } + SecretKeySpec secretKey = new SecretKeySpec(key, ALGORITHM); + IvParameterSpec ivParameterSpec = new IvParameterSpec(iv, 0, OFFSET); + Cipher cipher = Cipher.getInstance(AES_CBC_CIPHER); + cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivParameterSpec); + return cipher.doFinal(data); + } catch (Exception e) { + throw new EncryptException("aes encrypt error:" + e.getMessage(), e); + } + } + + /** + * 解密 + * + * @param data 待解密内容 + * @param key 解密密钥 + * @return + */ + public static byte[] decrypt(byte[] data, byte[] key, byte[] iv) { + try { + if (key.length < 16) { + byte[] tmp = new byte[16]; + System.arraycopy(key, 0, tmp, 0, key.length); + key = tmp; + } + if (iv.length < 16) { + byte[] tmp = new byte[16]; + System.arraycopy(iv, 0, tmp, 0, iv.length); + iv = tmp; + } + SecretKeySpec secretKey = new SecretKeySpec(key, ALGORITHM); + IvParameterSpec ivParameterSpec = new IvParameterSpec(iv, 0, OFFSET); + Cipher cipher = Cipher.getInstance(AES_CBC_CIPHER); + cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameterSpec); + return cipher.doFinal(data); + } catch (Exception e) { + throw new EncryptException("ase decrypt error", e); + } + } + + /** + * 加密 + *

+ * * 定义 aes 加密的key + * * 密钥 必须是16位, 自定义, + * * 如果不是16位, 则会出现InvalidKeyException: Illegal key size + * * 解决方案有两种: + * * 需要安装Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files(可以在Oracle下载). + * * .设置设置key的长度为16个字母和数字的字符窜(128 Bit/8=16字符)就不报错了。 + * + * @param data 需要加密的内容 + * @param key 加密密码 + * @return + */ + public static String encrypt(String data, String key) { + byte[] keyBytes = key.getBytes(StandardCharsets.UTF_8); + byte[] valueByte = encrypt(data.getBytes(StandardCharsets.UTF_8), keyBytes, keyBytes); + return Base64.getEncoder().encodeToString(valueByte); + } + + /** + * 解密 + * + * @param data 待解密内容 base64 字符串 + * @param key 解密密钥 + * @return + */ + public static String decrypt(String data, String key) { + byte[] originalData = Base64.getDecoder().decode(data.getBytes()); + byte[] keyBytes = key.getBytes(StandardCharsets.UTF_8); + byte[] valueByte = decrypt(originalData, keyBytes, keyBytes); + return new String(valueByte); + } +} diff --git a/components/fluent-builtin/src/main/java/io/fluent/builtin/crypto/DesUtil.java b/components/fluent-builtin/src/main/java/io/fluent/builtin/crypto/DesUtil.java new file mode 100644 index 0000000..7b1c3ec --- /dev/null +++ b/components/fluent-builtin/src/main/java/io/fluent/builtin/crypto/DesUtil.java @@ -0,0 +1,88 @@ +package io.fluent.builtin.crypto; + + +import io.fluent.builtin.exception.EncryptException; + +import javax.crypto.Cipher; +import javax.crypto.spec.SecretKeySpec; +import java.nio.charset.StandardCharsets; +import java.util.Base64; + +/** + * des算法加解密 + * DES/ECB/PKCS5Padding + * + */ +public class DesUtil { + + /** + * AES + */ + static final String ALGORITHM = "DES"; + /** + * AES 算法 + */ + static final String DES_ECB_CIPHER = "DES/ECB/PKCS5Padding"; + + /** + * 加密 + * + * @param data 需要加密的内容 + * @param key 加密密码 + * @return + */ + public static byte[] encrypt(byte[] data, byte[] key) { + try { + //生成KEY + SecretKeySpec secretKey = new SecretKeySpec(key, ALGORITHM); + Cipher cipher = Cipher.getInstance(DES_ECB_CIPHER); + cipher.init(Cipher.ENCRYPT_MODE, secretKey); + return cipher.doFinal(data); + } catch (Exception e) { + throw new EncryptException("encrypt error", e); + } + } + + /** + * 解密 + * + * @param data 待解密内容 + * @param key 解密密钥 + * @return + */ + public static byte[] decrypt(byte[] data, byte[] key) { + try { + SecretKeySpec secretKey = new SecretKeySpec(key, ALGORITHM); + Cipher cipher = Cipher.getInstance(DES_ECB_CIPHER); + cipher.init(Cipher.DECRYPT_MODE, secretKey); + return cipher.doFinal(data); + } catch (Exception e) { + throw new EncryptException("decrypt error", e); + } + } + + /** + * 加密 + * + * @param data 需要加密的内容 + * @param key 加密密码 + * @return + */ + public static String encrypt(String data, String key) { + byte[] valueByte = encrypt(data.getBytes(StandardCharsets.UTF_8), key.getBytes(StandardCharsets.UTF_8)); + return Base64.getEncoder().encodeToString(valueByte); + } + + /** + * 解密 + * + * @param data 待解密内容 base64 字符串 + * @param key 解密密钥 + * @return + */ + public static String decrypt(String data, String key) { + byte[] originalData = Base64.getDecoder().decode(data.getBytes()); + byte[] valueByte = decrypt(originalData, key.getBytes(StandardCharsets.UTF_8)); + return new String(valueByte); + } +} diff --git a/components/fluent-builtin/src/main/java/io/fluent/builtin/exception/EncryptException.java b/components/fluent-builtin/src/main/java/io/fluent/builtin/exception/EncryptException.java new file mode 100644 index 0000000..6bcb529 --- /dev/null +++ b/components/fluent-builtin/src/main/java/io/fluent/builtin/exception/EncryptException.java @@ -0,0 +1,9 @@ +package io.fluent.builtin.exception; + +public class EncryptException extends SystemException { + + public EncryptException(String message, Throwable throwable) { + super(message, throwable); + } + +} diff --git a/components/fluent-builtin/src/main/java/io/fluent/builtin/exception/SystemException.java b/components/fluent-builtin/src/main/java/io/fluent/builtin/exception/SystemException.java new file mode 100644 index 0000000..d117ae8 --- /dev/null +++ b/components/fluent-builtin/src/main/java/io/fluent/builtin/exception/SystemException.java @@ -0,0 +1,13 @@ +package io.fluent.builtin.exception; + +public class SystemException extends WrapMessageException { + private static final long serialVersionUID = 1L; + + public SystemException(String message) { + super(message); + } + + public SystemException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/components/fluent-builtin/src/main/java/io/fluent/builtin/exception/WrapMessageException.java b/components/fluent-builtin/src/main/java/io/fluent/builtin/exception/WrapMessageException.java new file mode 100644 index 0000000..40ed0e3 --- /dev/null +++ b/components/fluent-builtin/src/main/java/io/fluent/builtin/exception/WrapMessageException.java @@ -0,0 +1,19 @@ +package io.fluent.builtin.exception; + +/** + * 只包装了 错误信息 的 {@link RuntimeException}. + * 用于 {@link com.sprainkle.spring.cloud.advance.common.core.exception.assertion.Assert} 中用于包装自定义异常信息 + * + + */ +public class WrapMessageException extends RuntimeException { + + public WrapMessageException(String message) { + super(message); + } + + public WrapMessageException(String message, Throwable cause) { + super(message, cause); + } + +} diff --git a/components/fluent-builtin/src/main/java/io/fluent/builtin/meta/TargetType.java b/components/fluent-builtin/src/main/java/io/fluent/builtin/meta/TargetType.java new file mode 100644 index 0000000..3d4ad96 --- /dev/null +++ b/components/fluent-builtin/src/main/java/io/fluent/builtin/meta/TargetType.java @@ -0,0 +1,32 @@ +package io.fluent.builtin.meta; + +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; + +public class TargetType { + + public Type getType() { + + Type t = getClass().getGenericSuperclass(); + if (!(t instanceof ParameterizedType)) { + throw new IllegalStateException("Incorrect use of TypeToken: " + t); + } + ParameterizedType pt = (ParameterizedType) t; + Type[] typeArgs = pt.getActualTypeArguments(); + if (typeArgs.length > 0) { + return typeArgs[0]; + } + throw new IllegalStateException("Incorrect use of TypeToken: " + t); + } + + @SuppressWarnings("unchecked") + public Class getClassType() { + + Type type = getType(); + if (type instanceof ParameterizedType) { + return (Class) ((ParameterizedType) type).getRawType(); + } else { + return (Class) type; + } + } +} diff --git a/components/fluent-builtin/src/main/java/io/fluent/builtin/time/DateFormatterPattern.java b/components/fluent-builtin/src/main/java/io/fluent/builtin/time/DateFormatterPattern.java new file mode 100644 index 0000000..33fd071 --- /dev/null +++ b/components/fluent-builtin/src/main/java/io/fluent/builtin/time/DateFormatterPattern.java @@ -0,0 +1,156 @@ +package io.fluent.builtin.time; + +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + +import java.time.format.DateTimeFormatter; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.regex.Pattern; + +/** + * 日期格式化类,提供常用的日期格式化对象 + * + */ +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class DateFormatterPattern { + + + /** + * 标准日期时间正则,每个字段支持单个数字或2个数字,包括: + *

+     *     yyyy-MM-dd HH:mm:ss.SSS
+     *     yyyy-MM-dd HH:mm:ss
+     *     yyyy-MM-dd HH:mm
+     *     yyyy-MM-dd
+     * 
+ * + * @since 5.3.6 + */ + public static final Pattern REGEX_NORM = Pattern.compile("\\d{4}-\\d{1,2}-\\d{1,2}(\\s\\d{1,2}:\\d{1,2}(:\\d{1,2})?)?(.\\d{1,3})?"); + + //-------------------------------------------------------------------------------------------------------------------------------- Normal + /** + * 年月格式:yyyy-MM + */ + public static final String NORM_MONTH_PATTERN = "yyyy-MM"; + /** + * 简单年月格式:yyyyMM + */ + public static final String SIMPLE_MONTH_PATTERN = "yyyyMM"; + /** + * 标准日期格式:yyyy-MM-dd + */ + public static final String NORM_DATE_PATTERN = "yyyy-MM-dd"; + /** + * 标准时间格式:HH:mm:ss + */ + public static final String NORM_TIME_PATTERN = "HH:mm:ss"; + /** + * 标准日期时间格式,精确到分:yyyy-MM-dd HH:mm + */ + public static final String NORM_DATETIME_MINUTE_PATTERN = "yyyy-MM-dd HH:mm"; + /** + * 标准日期时间格式,精确到秒:yyyy-MM-dd HH:mm:ss + */ + public static final String NORM_DATETIME_PATTERN = "yyyy-MM-dd HH:mm:ss"; + /** + * 准日期时间格式,精确到毫秒:yyyy-MM-dd HH:mm:ss.SSS + */ + public static final String NORM_DATETIME_MS_PATTERN = "yyyy-MM-dd HH:mm:ss.SSS"; + /** + * ISO8601日期时间格式,精确到毫秒:yyyy-MM-dd HH:mm:ss,SSS + */ + public static final String ISO8601_PATTERN = "yyyy-MM-dd HH:mm:ss,SSS"; + /** + * 标准日期格式:yyyy年MM月dd日 + */ + public static final String CHINESE_DATE_PATTERN = "yyyy年MM月dd日"; + /** + * 标准日期格式:yyyy年MM月dd日 HH时mm分ss秒 + */ + public static final String CHINESE_DATE_TIME_PATTERN = "yyyy年MM月dd日HH时mm分ss秒"; + /** + * 标准日期格式:yyyyMMdd + */ + public static final String PURE_DATE_PATTERN = "yyyyMMdd"; + /** + * 标准日期格式:HHmmss + */ + public static final String PURE_TIME_PATTERN = "HHmmss"; + /** + * HTTP头中日期时间格式:EEE, dd MMM yyyy HH:mm:ss z + */ + public static final String HTTP_DATETIME_PATTERN = "EEE, dd MMM yyyy HH:mm:ss z"; + /** + * JDK中日期时间格式:EEE MMM dd HH:mm:ss zzz yyyy + */ + public static final String JDK_DATETIME_PATTERN = "EEE MMM dd HH:mm:ss zzz yyyy"; + /** + * UTC时间:yyyy-MM-dd'T'HH:mm:ss + */ + public static final String UTC_SIMPLE_PATTERN = "yyyy-MM-dd'T'HH:mm:ss"; + /** + * UTC时间:yyyy-MM-dd'T'HH:mm:ss.SSS + */ + public static final String UTC_SIMPLE_MS_PATTERN = "yyyy-MM-dd'T'HH:mm:ss.SSS"; + /** + * UTC时间:yyyy-MM-dd'T'HH:mm:ss'Z' + */ + public static final String UTC_PATTERN = "yyyy-MM-dd'T'HH:mm:ss'Z'"; + /** + * UTC时间:yyyy-MM-dd'T'HH:mm:ssZ + */ + public static final String UTC_WITH_ZONE_OFFSET_PATTERN = "yyyy-MM-dd'T'HH:mm:ssZ"; + /** + * UTC时间:yyyy-MM-dd'T'HH:mm:ssXXX + */ + public static final String UTC_WITH_XXX_OFFSET_PATTERN = "yyyy-MM-dd'T'HH:mm:ssXXX"; + /** + * UTC时间:yyyy-MM-dd'T'HH:mm:ss.SSS'Z' + */ + public static final String UTC_MS_PATTERN = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"; + + //-------------------------------------------------------------------------------------------------------------------------------- Pure + /** + * UTC时间:yyyy-MM-dd'T'HH:mm:ssZ + */ + public static final String UTC_MS_WITH_ZONE_OFFSET_PATTERN = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"; + /** + * UTC时间:yyyy-MM-dd'T'HH:mm:ss.SSSXXX + */ + public static final String UTC_MS_WITH_XXX_OFFSET_PATTERN = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX"; + private final static Map DATE_FORMATTER_PATTERN_MAP = new ConcurrentHashMap<>(64); + public static final DateTimeFormatter NORM_MONTH_FORMATTER = createFormatter(NORM_MONTH_PATTERN); + + + //-------------------------------------------------------------------------------------------------------------------------------- Others + public static final DateTimeFormatter SIMPLE_MONTH_FORMATTER = createFormatter(SIMPLE_MONTH_PATTERN); + public static final DateTimeFormatter NORM_DATE_FORMATTER = createFormatter(NORM_DATE_PATTERN); + public static final DateTimeFormatter NORM_TIME_FORMATTER = createFormatter(NORM_TIME_PATTERN); + public static final DateTimeFormatter NORM_DATETIME_MINUTE_FORMATTER = createFormatter(NORM_DATETIME_MINUTE_PATTERN); + public static final DateTimeFormatter NORM_DATETIME_FORMATTER = createFormatter(NORM_DATETIME_PATTERN); + public static final DateTimeFormatter NORM_DATETIME_MS_FORMATTER = createFormatter(NORM_DATETIME_MS_PATTERN); + public static final DateTimeFormatter ISO8601_FORMATTER = createFormatter(ISO8601_PATTERN); + public static final DateTimeFormatter CHINESE_DATE_FORMATTER = createFormatter(ISO8601_PATTERN); + public static final DateTimeFormatter CHINESE_DATE_TIME_FORMATTER = createFormatter(CHINESE_DATE_TIME_PATTERN); + public static final DateTimeFormatter PURE_DATE_FORMATTER = createFormatter(PURE_DATE_PATTERN); + public static final DateTimeFormatter PURE_TIME_FORMATTER = createFormatter(PURE_TIME_PATTERN); + + /** + * 创建并为 DateTimeFormatter 赋予默认时区和位置信息,默认值为系统默认值。 + * Params: pattern – 日期格式 + * Returns: DateTimeFormatter + * + * @param pattern + * @return + */ + private static DateTimeFormatter createFormatter(String pattern) { + return getFormatter(pattern); + } + + public static DateTimeFormatter getFormatter(String pattern) { + return DATE_FORMATTER_PATTERN_MAP.computeIfAbsent(pattern, key -> DateTimeFormatter.ofPattern(pattern)); + + } +} diff --git a/components/fluent-builtin/src/main/java/io/fluent/builtin/time/DateParseUtil.java b/components/fluent-builtin/src/main/java/io/fluent/builtin/time/DateParseUtil.java new file mode 100644 index 0000000..bb21613 --- /dev/null +++ b/components/fluent-builtin/src/main/java/io/fluent/builtin/time/DateParseUtil.java @@ -0,0 +1,135 @@ +package io.fluent.builtin.time; + + +import io.fluent.builtin.StringUtils; + +import java.time.LocalDateTime; +import java.time.OffsetTime; +import java.time.ZoneOffset; +import java.time.format.DateTimeFormatter; + +public class DateParseUtil { + + public static final ZoneOffset DEFAULT_ZONE_OFFSET = OffsetTime.now().getOffset(); + + /** + * 解析 yyyy-MM-dd HH:mm:ss + * + * @param dateStr + * @return + */ + public static LocalDateTime parse(String dateStr) { + return LocalDateTime.parse(dateStr, DateFormatterPattern.NORM_DATETIME_FORMATTER); + } + + /** + * 解析 yyyy-MM-dd HH:mm:ss 格式成秒 + * + * @param dateStr + * @return + */ + public static Long toEpochSecond(String dateStr, DateTimeFormatter dateTimeFormatter, String offset) { + + ZoneOffset zoneOffset = StringUtils.isEmpty(offset) ? DEFAULT_ZONE_OFFSET : ZoneOffset.of(offset); + dateTimeFormatter = dateTimeFormatter == null ? DateFormatterPattern.NORM_DATETIME_FORMATTER : dateTimeFormatter; + return LocalDateTime.parse(dateStr, dateTimeFormatter).toEpochSecond(zoneOffset); + } + + /** + * 解析 yyyy-MM-dd HH:mm:ss 格式成秒 + * + * @param dateStr + * @return + */ + public static Long toEpochSecond(String dateStr, String offset) { + + + ZoneOffset zoneOffset = StringUtils.isEmpty(offset) ? DEFAULT_ZONE_OFFSET : ZoneOffset.of(offset); + return LocalDateTime.parse(dateStr, DateFormatterPattern.NORM_DATETIME_FORMATTER).toEpochSecond(zoneOffset); + } + + /** + * 解析 yyyy-MM-dd HH:mm:ss 格式成秒 + * + * @param dateStr + * @return + */ + public static Long toEpochSecond(String dateStr) { + + return LocalDateTime.parse(dateStr, DateFormatterPattern.NORM_DATETIME_FORMATTER).toEpochSecond(DEFAULT_ZONE_OFFSET); + } + + + /** + * 解析 yyyy-MM-dd HH:mm:ss 格式成毫秒 + * + * @param dateStr 时间 + * @return + */ + public static Long toEpochMilli(String dateStr, DateTimeFormatter dateTimeFormatter, String offset) { + + ZoneOffset zoneOffset = StringUtils.isEmpty(offset) ? DEFAULT_ZONE_OFFSET : ZoneOffset.of(offset); + dateTimeFormatter = dateTimeFormatter == null ? DateFormatterPattern.NORM_DATETIME_FORMATTER : dateTimeFormatter; + return LocalDateTime.parse(dateStr, dateTimeFormatter).toInstant(zoneOffset).toEpochMilli(); + } + + /** + * 解析 yyyy-MM-dd HH:mm:ss 格式成秒 + * + * @param dateStr + * @return + */ + public static Long toEpochMilli(String dateStr, String offset) { + + + ZoneOffset zoneOffset = StringUtils.isEmpty(offset) ? DEFAULT_ZONE_OFFSET : ZoneOffset.of(offset); + return LocalDateTime.parse(dateStr, DateFormatterPattern.NORM_DATETIME_FORMATTER).toInstant(zoneOffset).toEpochMilli(); + } + + /** + * 解析 yyyy-MM-dd HH:mm:ss 格式成秒 + * + * @param dateStr + * @return + */ + public static Long toEpochMilli(String dateStr) { + + return LocalDateTime.parse(dateStr, DateFormatterPattern.NORM_DATETIME_FORMATTER).toInstant(DEFAULT_ZONE_OFFSET).toEpochMilli(); + } + + /** + * LocalDateTime 解释成秒 + * + * @param localDateTime 本地日期 + * @param offset 时区 + * @return + */ + public static Long toEpochSecond(LocalDateTime localDateTime, String offset) { + + ZoneOffset zoneOffset = StringUtils.isEmpty(offset) ? DEFAULT_ZONE_OFFSET : ZoneOffset.of(offset); + return localDateTime.toEpochSecond(zoneOffset); + } + + public static Long toEpochSecond(LocalDateTime localDateTime) { + + return localDateTime.toEpochSecond(DEFAULT_ZONE_OFFSET); + } + + /** + * LocalDateTime 解释毫秒 + * + * @param localDateTime 本地日期 + * @param offset 时区 + * @return + */ + public static Long toEpochMilli(LocalDateTime localDateTime, String offset) { + + ZoneOffset zoneOffset = StringUtils.isEmpty(offset) ? DEFAULT_ZONE_OFFSET : ZoneOffset.of(offset); + return localDateTime.toInstant(zoneOffset).toEpochMilli(); + } + + public static Long toEpochMilli(LocalDateTime localDateTime) { + + return localDateTime.toInstant(DEFAULT_ZONE_OFFSET).toEpochMilli(); + } +} diff --git a/components/fluent-builtin/src/main/java/io/fluent/builtin/time/TimeDifferUtil.java b/components/fluent-builtin/src/main/java/io/fluent/builtin/time/TimeDifferUtil.java new file mode 100644 index 0000000..19290e6 --- /dev/null +++ b/components/fluent-builtin/src/main/java/io/fluent/builtin/time/TimeDifferUtil.java @@ -0,0 +1,81 @@ +package io.fluent.builtin.time; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.ZoneOffset; + +public class TimeDifferUtil { + + /** + * 相差几天 + * + * @param beginDate beginTime + * @param endDate endDate + * @return 相差几天 + */ + public static long day(LocalDate beginDate, LocalDate endDate) { + + return endDate.toEpochDay() - beginDate.toEpochDay(); + } + + /** + * 相差几年 + * + * @param beginDate beginTime + * @param endDate endDate + * @return 相差几天 + */ + public static double year(LocalDate beginDate, LocalDate endDate) { + + return (endDate.toEpochDay() - beginDate.toEpochDay()) / 365.0; + } + + /** + * 相差几天 + * + * @param beginTime beginTime + * @param endTime endTime + * @return 相差几天 + */ + public static double day(LocalDateTime beginTime, LocalDateTime endTime) { + + + long beginSecond = beginTime.toEpochSecond(ZoneOffset.UTC); + long endSecond = endTime.toEpochSecond(ZoneOffset.UTC); + return (endSecond - beginSecond) / 60.0 / 60.0 / 24.0; + } + + + /** + * 相差几小时 + */ + public static double hour(LocalDateTime beginTime, LocalDateTime endTime) { + + + long beginSecond = beginTime.toEpochSecond(ZoneOffset.UTC); + long endSecond = endTime.toEpochSecond(ZoneOffset.UTC); + return (endSecond - beginSecond) / 60.0 / 60.0; + } + + /** + * 相差几分钟 + */ + public static double minute(LocalDateTime beginTime, LocalDateTime endTime) { + + long beginSecond = beginTime.toEpochSecond(ZoneOffset.UTC); + long endSecond = endTime.toEpochSecond(ZoneOffset.UTC); + return (endSecond - beginSecond) / 60.0; + } + + /** + * 相差几秒 + */ + public static double second(LocalDateTime beginTime, LocalDateTime endTime) { + + long beginSecond = beginTime.toEpochSecond(ZoneOffset.UTC); + long endSecond = endTime.toEpochSecond(ZoneOffset.UTC); + return (endSecond - beginSecond); + } + + +} diff --git a/components/fluent-loader/pom.xml b/components/fluent-loader/pom.xml new file mode 100644 index 0000000..4f25fa6 --- /dev/null +++ b/components/fluent-loader/pom.xml @@ -0,0 +1,42 @@ + + + 4.0.0 + + io.fluent + components + 1.0-SNAPSHOT + + + fluent-loader + + + UTF-8 + 7.0.0 + + + + com.google.inject + guice + ${guice.version} + + + com.google.inject.extensions + guice-assistedinject + ${guice.version} + + + + com.google.inject.extensions + guice-servlet + ${guice.version} + + + + + + + + + \ No newline at end of file diff --git a/components/fluent-loader/src/main/java/io/fluent/loader/dep/DependencyAware.java b/components/fluent-loader/src/main/java/io/fluent/loader/dep/DependencyAware.java new file mode 100644 index 0000000..2b19c90 --- /dev/null +++ b/components/fluent-loader/src/main/java/io/fluent/loader/dep/DependencyAware.java @@ -0,0 +1,21 @@ +package io.fluent.loader.dep; + +import java.util.Set; + +public interface DependencyAware { + + /** + * Get key of the dependent object. + * @return + */ + K getId(); + + /** + * Get set of keys of other dependency objects this dependency object directly depends on. + * @return + * Should not be null. In case of no dependencies, please return an empty collection + * instead of a null value. + */ + Set getDependencies(); + +} diff --git a/components/fluent-loader/src/main/java/io/fluent/loader/package-info.java b/components/fluent-loader/src/main/java/io/fluent/loader/package-info.java new file mode 100644 index 0000000..cd2878e --- /dev/null +++ b/components/fluent-loader/src/main/java/io/fluent/loader/package-info.java @@ -0,0 +1 @@ +package io.fluent.loader; \ No newline at end of file diff --git a/components/fluent-spring/src/main/java/io/fluent/spring/config/SpringConfig.java b/components/fluent-spring/src/main/java/io/fluent/spring/config/SpringConfig.java index a501263..ddcc2fc 100644 --- a/components/fluent-spring/src/main/java/io/fluent/spring/config/SpringConfig.java +++ b/components/fluent-spring/src/main/java/io/fluent/spring/config/SpringConfig.java @@ -5,7 +5,7 @@ public class SpringConfig { - @Bean("fluentSpringUtils") + @Bean("springUtils") public SpringUtils springUtils() { return new SpringUtils(); } diff --git a/components/fluent-spring/src/main/java/io/fluent/spring/util/SpringUtils.java b/components/fluent-spring/src/main/java/io/fluent/spring/util/SpringUtils.java index 5ceb838..b53eded 100644 --- a/components/fluent-spring/src/main/java/io/fluent/spring/util/SpringUtils.java +++ b/components/fluent-spring/src/main/java/io/fluent/spring/util/SpringUtils.java @@ -19,7 +19,6 @@ /** * spring工具类 方便在非spring管理环境中获取bean * - * @author andanyang */ public final class SpringUtils implements BeanFactoryPostProcessor, ApplicationContextAware { diff --git a/components/fluent-spring/src/main/resources/META-INF/spring.factories b/components/fluent-spring/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000..bff0efa --- /dev/null +++ b/components/fluent-spring/src/main/resources/META-INF/spring.factories @@ -0,0 +1,2 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ + com.admin4j.spring.config.SpringConfig diff --git a/components/pom.xml b/components/pom.xml index 1a0bcb5..c09c7c5 100644 --- a/components/pom.xml +++ b/components/pom.xml @@ -26,6 +26,7 @@ fluent-datafactory fluent-testlibs fluent-spring + fluent-loader diff --git a/references.yaml b/references.yaml index 6d5750d..f987426 100644 --- a/references.yaml +++ b/references.yaml @@ -1,6 +1,5 @@ stacks: - https://www.stackradar.co/ - agent: - https://www.agentcrew.co/ @@ -34,7 +33,7 @@ devops: - https://gitee.com/ketr/jecloud database-tools: - - https://github.com/azimuttapp/azimutt.git + - https://github.com/azimuttapp/azimutt.git qa-tools: - https://gitee.com/cat2bug/cat2bug-platform.git qa-ai-tools: @@ -50,6 +49,7 @@ api-mgt: - https://github.com/Kong/insomnia.git - https://github.com/xyyxhcj/vpi.git low-code: + - https://gitee.com/yabushan/low-code-data-center.git - https://gitee.com/zj1983/zz.git - https://gitee.com/y_project/RuoYi-Vue.git - https://gitee.com/newcorenet/elcube-backend.git