From 3e8b90963b15e9c1a4462e8dce3c169f65cee504 Mon Sep 17 00:00:00 2001 From: SerLiunx-ctrl <17689543@qq.com> Date: Fri, 9 Aug 2024 16:44:20 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E9=99=84=E4=BB=B6=E6=8E=A5=E5=8F=A3=E3=80=81=E8=B0=83=E6=95=B4?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E6=A0=BC=E5=BC=8F.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ddns/config/PropertiesConfiguration.java | 4 +- .../com/serliunx/ddns/core/Attachment.java | 43 +++++++++++++++++++ .../serliunx/ddns/core/FileAttachment.java | 30 +++++++++++++ .../core/context/AbstractInstanceContext.java | 4 +- .../core/factory/FileInstanceFactory.java | 30 ++++++++++++- .../com/serliunx/ddns/util/InstanceUtils.java | 4 +- .../serliunx/ddns/util/ReflectionUtils.java | 16 +++---- .../serliunx/ddns/test/AttachmentTest.java | 29 +++++++++++++ .../com/serliunx/ddns/test/ContextTest.java | 6 +-- 9 files changed, 149 insertions(+), 17 deletions(-) create mode 100644 src/main/java/com/serliunx/ddns/core/Attachment.java create mode 100644 src/main/java/com/serliunx/ddns/core/FileAttachment.java create mode 100644 src/test/java/com/serliunx/ddns/test/AttachmentTest.java diff --git a/src/main/java/com/serliunx/ddns/config/PropertiesConfiguration.java b/src/main/java/com/serliunx/ddns/config/PropertiesConfiguration.java index bd14905..375abd9 100644 --- a/src/main/java/com/serliunx/ddns/config/PropertiesConfiguration.java +++ b/src/main/java/com/serliunx/ddns/config/PropertiesConfiguration.java @@ -38,8 +38,8 @@ public class PropertiesConfiguration extends FileConfiguration { load(); } catch (IOException e) { log.error("配置文件读取出现异常 => {}", e.toString()); - }finally { - if(inputStream != null){ + } finally { + if (inputStream != null) { try { inputStream.close(); } catch (IOException e) { diff --git a/src/main/java/com/serliunx/ddns/core/Attachment.java b/src/main/java/com/serliunx/ddns/core/Attachment.java new file mode 100644 index 0000000..c426af4 --- /dev/null +++ b/src/main/java/com/serliunx/ddns/core/Attachment.java @@ -0,0 +1,43 @@ +package com.serliunx.ddns.core; + +import java.util.Collection; + +/** + * 附件定义 + * + * @author SerLiunx + * @version 1.0.0 + * @since 2024/8/6 + */ +public interface Attachment { + + /** + * 是否存在指定附件 + * + * @param e 附件信息 + * @return 存在返回真, 否则返回假 + */ + boolean exists(E e); + + /** + * 分离指定附件 + * + * @param e 附件 + * @return 成功分离返回真, 否则返回假(不存在时返回假) + */ + boolean detach(E e); + + /** + * 添加一个附件 + * + * @param e 附件 + */ + void attach(E e); + + /** + * 获取所有附件对象 + * + * @return 所有附件对象 + */ + Collection getAttachments(); +} diff --git a/src/main/java/com/serliunx/ddns/core/FileAttachment.java b/src/main/java/com/serliunx/ddns/core/FileAttachment.java new file mode 100644 index 0000000..f93df0e --- /dev/null +++ b/src/main/java/com/serliunx/ddns/core/FileAttachment.java @@ -0,0 +1,30 @@ +package com.serliunx.ddns.core; + +import java.io.File; +import java.util.Collection; + +/** + * 文件类型的附件 + * + * @author SerLiunx + * @version 1.0.0 + * @since 2024/8/6 + */ +public interface FileAttachment extends Attachment { + + /** + * 检查所有文件附件是否都是文件夹 + */ + default boolean isAllDirectories() { + Collection files = getAttachments(); + if (files == null || files.isEmpty()) { + return false; + } + for (File file : files) { + if (!file.isDirectory()) { + return false; + } + } + return true; + } +} diff --git a/src/main/java/com/serliunx/ddns/core/context/AbstractInstanceContext.java b/src/main/java/com/serliunx/ddns/core/context/AbstractInstanceContext.java index 35cff54..bc800bc 100644 --- a/src/main/java/com/serliunx/ddns/core/context/AbstractInstanceContext.java +++ b/src/main/java/com/serliunx/ddns/core/context/AbstractInstanceContext.java @@ -52,8 +52,10 @@ public abstract class AbstractInstanceContext implements InstanceContext, Multip public void refresh() { try { instanceLock.lock(); - if (listableInstanceFactories.isEmpty()) + if (listableInstanceFactories.isEmpty()) { + log.error("启动失败, 未找到任何有效的实例工厂!"); return; + } // 初始化所有实例工厂 listableInstanceFactories.stream() diff --git a/src/main/java/com/serliunx/ddns/core/factory/FileInstanceFactory.java b/src/main/java/com/serliunx/ddns/core/factory/FileInstanceFactory.java index e5bd733..2981dd8 100644 --- a/src/main/java/com/serliunx/ddns/core/factory/FileInstanceFactory.java +++ b/src/main/java/com/serliunx/ddns/core/factory/FileInstanceFactory.java @@ -1,5 +1,6 @@ package com.serliunx.ddns.core.factory; +import com.serliunx.ddns.core.FileAttachment; import com.serliunx.ddns.core.InstanceFileFilter; import com.serliunx.ddns.core.instance.Instance; @@ -9,23 +10,47 @@ import java.util.stream.Collectors; /** * 文件相关实例工厂, 定义所有来源为文件的实例工厂通用逻辑 + * * @see JacksonFileInstanceFactory 使用Jackson序列化、反序列化的实例 * @see YamlFileInstanceFactory 使用SankeYaml序列化、反序列化的实例 * @author SerLiunx * @version 1.0.0 * @since 2024/5/15 */ -public abstract class FileInstanceFactory extends AbstractInstanceFactory { +public abstract class FileInstanceFactory extends AbstractInstanceFactory implements FileAttachment { /** * 存储实例信息的文件夹路径 */ protected String instanceDir; + protected Set filesAttachments; public FileInstanceFactory(String instanceDir) { this.instanceDir = instanceDir; } + @Override + public boolean exists(File file) { + return filesAttachments.contains(file); + } + + @Override + public boolean detach(File file) { + if (!exists(file)) + return false; + return filesAttachments.remove(file); + } + + @Override + public void attach(File file) { + filesAttachments.add(file); + } + + @Override + public Collection getAttachments() { + return filesAttachments; + } + @Override public int getPriority() { return 256; @@ -39,6 +64,9 @@ public abstract class FileInstanceFactory extends AbstractInstanceFactory { @Override protected Set load() { Set files = loadFiles(); + + filesAttachments = files; + if (files != null && !files.isEmpty()) { return files.stream() .map(this::loadInstance) diff --git a/src/main/java/com/serliunx/ddns/util/InstanceUtils.java b/src/main/java/com/serliunx/ddns/util/InstanceUtils.java index ae8e219..9a16db2 100644 --- a/src/main/java/com/serliunx/ddns/util/InstanceUtils.java +++ b/src/main/java/com/serliunx/ddns/util/InstanceUtils.java @@ -11,12 +11,12 @@ import com.serliunx.ddns.support.Assert; */ public final class InstanceUtils { - private InstanceUtils(){throw new UnsupportedOperationException();} + private InstanceUtils() {throw new UnsupportedOperationException();} public static void validateInstance(Instance instance) { Assert.notNull(instance); String instanceName = instance.getName(); - if(instanceName == null || instanceName.isEmpty()){ + if (instanceName == null || instanceName.isEmpty()) { throw new NullPointerException(); } } diff --git a/src/main/java/com/serliunx/ddns/util/ReflectionUtils.java b/src/main/java/com/serliunx/ddns/util/ReflectionUtils.java index 010b8a8..ebb2ff5 100644 --- a/src/main/java/com/serliunx/ddns/util/ReflectionUtils.java +++ b/src/main/java/com/serliunx/ddns/util/ReflectionUtils.java @@ -12,7 +12,7 @@ import java.util.List; */ public final class ReflectionUtils { - private ReflectionUtils(){throw new UnsupportedOperationException();} + private ReflectionUtils() {throw new UnsupportedOperationException();} /** * 获取当前类声明的所有字段 @@ -22,18 +22,18 @@ public final class ReflectionUtils { * @return 字段列表 */ public static Field[] getDeclaredFields(Class clazz, boolean setAccessible) { - if(clazz == null){ + if (clazz == null) { return null; } Field[] declaredFields = clazz.getDeclaredFields(); Field[] declaredFieldsInSuper = getDeclaredFields(clazz.getSuperclass(), setAccessible); - if(declaredFieldsInSuper != null){ + if (declaredFieldsInSuper != null) { Field[] newFields = new Field[declaredFields.length + declaredFieldsInSuper.length]; System.arraycopy(declaredFields, 0, newFields, 0, declaredFields.length); System.arraycopy(declaredFieldsInSuper, 0, newFields, declaredFields.length, declaredFieldsInSuper.length); declaredFields = newFields; } - if(setAccessible){ + if (setAccessible) { for (Field declaredField : declaredFields) { declaredField.setAccessible(true); } @@ -64,9 +64,9 @@ public final class ReflectionUtils { List srcField = getDeclaredFieldList(srcClass, true); List destField = getDeclaredFieldList(destClass, true); for (Field field : destField) { - if(onlyNull){ + if (onlyNull) { try { - if(field.get(dest) != null){ + if (field.get(dest) != null) { continue; } } catch (IllegalAccessException e) { @@ -74,10 +74,10 @@ public final class ReflectionUtils { } } for (Field sf : srcField) { - if(sf.getName().equals(field.getName())){ + if (sf.getName().equals(field.getName())) { try { field.set(dest, sf.get(src)); - }catch (Exception e){ + } catch (Exception e) { throw new RuntimeException(e); } } diff --git a/src/test/java/com/serliunx/ddns/test/AttachmentTest.java b/src/test/java/com/serliunx/ddns/test/AttachmentTest.java new file mode 100644 index 0000000..3dab102 --- /dev/null +++ b/src/test/java/com/serliunx/ddns/test/AttachmentTest.java @@ -0,0 +1,29 @@ +package com.serliunx.ddns.test; + +import com.serliunx.ddns.constant.SystemConstants; +import com.serliunx.ddns.core.Attachment; +import com.serliunx.ddns.core.FileAttachment; +import com.serliunx.ddns.core.factory.FileInstanceFactory; +import com.serliunx.ddns.core.factory.JsonFileInstanceFactory; +import com.serliunx.ddns.core.factory.YamlFileInstanceFactory; +import org.junit.Test; + +import java.io.File; +import java.util.Collection; + +/** + * @author SerLiunx + * @version 1.0.0 + * @since 2024/8/6 + */ +public class AttachmentTest { + + @Test + public void testAttachment() { + FileInstanceFactory fileInstanceFactory = new YamlFileInstanceFactory(SystemConstants.USER_INSTANCE_DIR); + fileInstanceFactory.refresh(); + + Collection files = fileInstanceFactory.getAttachments(); + files.forEach(f -> System.out.println(f.getName())); + } +} diff --git a/src/test/java/com/serliunx/ddns/test/ContextTest.java b/src/test/java/com/serliunx/ddns/test/ContextTest.java index 850993c..01ba4d9 100644 --- a/src/test/java/com/serliunx/ddns/test/ContextTest.java +++ b/src/test/java/com/serliunx/ddns/test/ContextTest.java @@ -22,9 +22,9 @@ public class ContextTest { public void testGenericContext() { GenericInstanceContext genericInstanceContext = new GenericInstanceContext(true); - genericInstanceContext.addListableInstanceFactory(new XmlFileInstanceFactory(SystemConstants.USER_INSTANCE_DIR)); - genericInstanceContext.addListableInstanceFactory(new YamlFileInstanceFactory(SystemConstants.USER_INSTANCE_DIR)); - genericInstanceContext.addListableInstanceFactory(new JsonFileInstanceFactory(SystemConstants.USER_INSTANCE_DIR)); +// genericInstanceContext.addListableInstanceFactory(new XmlFileInstanceFactory(SystemConstants.USER_INSTANCE_DIR)); +// genericInstanceContext.addListableInstanceFactory(new YamlFileInstanceFactory(SystemConstants.USER_INSTANCE_DIR)); +// genericInstanceContext.addListableInstanceFactory(new JsonFileInstanceFactory(SystemConstants.USER_INSTANCE_DIR)); genericInstanceContext.refresh(); genericInstanceContext.getInstances().forEach(System.out::println);