From 374bf0a2230d61a5fb9967ffe5029c9da9f903f1 Mon Sep 17 00:00:00 2001 From: Linyuzai <120718461@qq.com> Date: Sat, 8 Jun 2024 20:40:28 +0800 Subject: [PATCH] plugin filter/matcher/convertor --- .../plugin/core/concept/AbstractPlugin.java | 40 ++-- .../core/concept/AbstractPluginConcept.java | 85 +++++---- .../linyuzai/plugin/core/concept/Plugin.java | 43 +++-- .../plugin/core/concept/PluginConcept.java | 5 +- .../plugin/core/concept/PluginEntry.java | 12 -- .../core/context/DefaultPluginContext.java | 8 +- .../context/DefaultPluginContextFactory.java | 1 - .../plugin/core/context/PluginContext.java | 4 +- .../core/convert/AbstractPluginConvertor.java | 14 +- .../ByteArrayToInputStreamMapConvertor.java | 27 --- .../ByteArrayToStringMapConvertor.java | 45 ----- .../convert/ContentToByteArrayConvertor.java | 27 +++ .../ContentToInputStreamConvertor.java | 27 +++ .../convert/ContentToStringConvertor.java | 40 ++++ .../core/convert/PluginConvertedEvent.java | 12 +- .../plugin/core/convert/PluginConvertor.java | 3 +- .../convert/PropertiesToMapConvertor.java | 40 ++++ .../convert/PropertiesToMapMapConvertor.java | 44 ----- .../core/exception/PluginException.java | 4 - .../core/extract/AbstractPluginExtractor.java | 3 +- .../plugin/core/extract/ContentExtractor.java | 12 +- .../plugin/core/extract/DynamicExtractor.java | 22 +-- .../plugin/core/extract/PluginExtractor.java | 3 +- .../core/extract/PropertiesExtractor.java | 10 +- .../core/factory/MetadataPluginFactory.java | 28 +++ .../plugin/core/factory/PluginFactory.java | 14 +- .../plugin/core/factory/SubPluginFactory.java | 21 +-- .../core/filter/AbstractPluginFilter.java | 14 +- .../core/filter/FilterWithResolver.java | 17 -- .../plugin/core/filter/NameFilter.java | 7 +- .../plugin/core/filter/PathFilter.java | 8 +- .../plugin/core/filter/PluginFilter.java | 8 +- .../core/filter/PluginFilteredEvent.java | 16 +- .../plugin/core/filter/PropertiesFilter.java | 30 ++- .../handle/DefaultPluginHandlerChain.java | 130 +++++++++++++ .../plugin/core/handle/PluginHandler.java | 32 +--- .../core/handle/PluginHandlerChain.java | 8 + .../core/match/AbstractPluginMatcher.java | 66 ++++--- .../plugin/core/match/ContentMatcher.java | 27 +-- .../core/match/PluginContextMatcher.java | 4 +- .../plugin/core/match/PluginMatchedEvent.java | 15 +- .../plugin/core/match/PluginMatcher.java | 3 +- .../core/match/PluginObjectMatcher.java | 4 +- .../plugin/core/match/PluginProperties.java | 1 + .../{PluginContent.java => PluginText.java} | 2 +- .../plugin/core/match/PropertiesMatcher.java | 40 +--- .../plugin/core/read/DependencyReader.java | 5 +- .../plugin/core/read/PluginReadable.java | 4 - .../core/read/content/ContentReader.java | 15 -- .../core/read/content/PluginContent.java | 11 -- .../core/read/metadata/MetadataReader.java | 15 -- .../core/read/metadata/PluginMetadata.java | 8 - .../metadata/PropertiesMetadataReader.java | 42 ----- .../core/resolve/AbstractPluginResolver.java | 19 -- .../plugin/core/resolve/ContentResolver.java | 11 +- .../core/resolve/DependOnResolvers.java | 23 --- .../plugin/core/resolve/EntryResolver.java | 11 +- .../plugin/core/resolve/PathNameResolver.java | 7 - .../plugin/core/resolve/PluginResolver.java | 7 +- .../core/resolve/PluginResolverChain.java | 16 -- .../core/resolve/PluginResolverChainImpl.java | 71 -------- .../resolve/PluginResolverDependency.java | 33 ---- .../core/resolve/PropertiesNameResolver.java | 39 ---- .../core/resolve/PropertiesResolver.java | 67 ++++--- .../plugin/core/tree/DefaultPluginTree.java | 22 +-- .../linyuzai/plugin/core/tree/PluginTree.java | 9 +- .../plugin/core/util/PluginUtils.java | 100 ++++++++++ .../plugin/jar/concept/JarPlugin.java | 37 ++-- .../plugin/jar/concept/JarPluginEntry.java | 15 +- .../plugin/jar/extension/NestedJarEntry.java | 2 +- .../jar/factory/JarEntryPluginFactory.java | 28 --- .../jar/factory/JarFilePluginFactory.java | 27 --- .../jar/factory/JarPathPluginFactory.java | 23 --- .../plugin/jar/factory/JarPluginFactory.java | 44 +++++ .../plugin/jar/filter/AnnotationFilter.java | 10 +- .../plugin/jar/filter/ClassFilter.java | 10 +- .../plugin/jar/filter/ClassNameFilter.java | 12 +- .../plugin/jar/filter/ModifierFilter.java | 10 +- .../plugin/jar/filter/PackageFilter.java | 13 +- .../plugin/jar/match/ClassMatcher.java | 22 +-- .../plugin/jar/match/InstanceMatcher.java | 26 +-- .../plugin/jar/match/JarPluginMatcher.java | 8 +- .../plugin/jar/read/JarContentReader.java | 35 ---- .../jar/resolve/JarClassNameResolver.java | 12 +- .../plugin/jar/resolve/JarClassResolver.java | 2 +- .../jar/resolve/JarInstanceResolver.java | 1 + .../plugin/zip/concept/ZipPlugin.java | 66 +++++++ .../plugin/zip/concept/ZipPluginEntry.java | 57 ++++++ .../plugin/zip/factory/ZipPluginFactory.java | 172 ++++++++++++++++++ 89 files changed, 1120 insertions(+), 1073 deletions(-) delete mode 100644 concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/concept/PluginEntry.java delete mode 100644 concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/convert/ByteArrayToInputStreamMapConvertor.java delete mode 100644 concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/convert/ByteArrayToStringMapConvertor.java create mode 100644 concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/convert/ContentToByteArrayConvertor.java create mode 100644 concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/convert/ContentToInputStreamConvertor.java create mode 100644 concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/convert/ContentToStringConvertor.java create mode 100644 concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/convert/PropertiesToMapConvertor.java delete mode 100644 concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/convert/PropertiesToMapMapConvertor.java create mode 100644 concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/factory/MetadataPluginFactory.java delete mode 100644 concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/filter/FilterWithResolver.java create mode 100644 concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/handle/DefaultPluginHandlerChain.java create mode 100644 concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/handle/PluginHandlerChain.java rename concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/match/{PluginContent.java => PluginText.java} (92%) delete mode 100644 concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/read/PluginReadable.java delete mode 100644 concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/read/content/ContentReader.java delete mode 100644 concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/read/content/PluginContent.java delete mode 100644 concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/read/metadata/MetadataReader.java delete mode 100644 concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/read/metadata/PluginMetadata.java delete mode 100644 concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/read/metadata/PropertiesMetadataReader.java delete mode 100644 concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/resolve/DependOnResolvers.java delete mode 100644 concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/resolve/PathNameResolver.java delete mode 100644 concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/resolve/PluginResolverChain.java delete mode 100644 concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/resolve/PluginResolverChainImpl.java delete mode 100644 concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/resolve/PluginResolverDependency.java delete mode 100644 concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/resolve/PropertiesNameResolver.java create mode 100644 concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/util/PluginUtils.java delete mode 100644 concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/factory/JarEntryPluginFactory.java delete mode 100644 concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/factory/JarFilePluginFactory.java delete mode 100644 concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/factory/JarPathPluginFactory.java create mode 100644 concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/factory/JarPluginFactory.java delete mode 100644 concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/read/JarContentReader.java create mode 100644 concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/zip/concept/ZipPlugin.java create mode 100644 concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/zip/concept/ZipPluginEntry.java create mode 100644 concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/zip/factory/ZipPluginFactory.java diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/concept/AbstractPlugin.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/concept/AbstractPlugin.java index f0508dca2..88bfbbaec 100644 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/concept/AbstractPlugin.java +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/concept/AbstractPlugin.java @@ -2,9 +2,7 @@ import com.github.linyuzai.plugin.core.context.DefaultPluginContext; import com.github.linyuzai.plugin.core.context.PluginContext; -import com.github.linyuzai.plugin.core.read.PluginReadable; import com.github.linyuzai.plugin.core.read.PluginReader; -import com.github.linyuzai.plugin.core.read.metadata.PluginMetadata; import com.github.linyuzai.plugin.core.tree.PluginTree; import lombok.Getter; import lombok.Setter; @@ -14,11 +12,13 @@ import java.util.stream.Collectors; @Getter +@Setter public abstract class AbstractPlugin implements Plugin { private final Collection readers = new ArrayList<>(); - @Setter + private Metadata metadata; + private PluginConcept concept; public void addReader(PluginReader reader) { @@ -47,26 +47,21 @@ public T read(Class type, Object key) { return null; } - @Override - public PluginMetadata getMetadata() { - return read(PluginMetadata.class, null); - } - protected PluginContext createReadContent() { return new DefaultPluginContext(null); } @Override public void prepare(PluginContext context) { - PluginTree.Node node = context.get(PluginTree.Node.class); - Collection entries = collectEntries(context); - for (PluginEntry entry : entries) { - Plugin subPlugin = getConcept().create(entry); + PluginTree.NodeFactory node = context.get(PluginTree.Node.class); + Collection entries = collectEntries(context); + for (Entry entry : entries) { + Plugin subPlugin = getConcept().create(entry, context); if (subPlugin == null) { - node.create(entry.getName(), entry, this); + node.create(entry.getId(), entry.getName(), entry); } else { - PluginTree.Node subTree = node.create(entry.getName(), subPlugin, this); - PluginContext subContext = context.createSubContext(); + PluginTree.Node subTree = node.create(subPlugin.getId(), entry.getName(), subPlugin); + PluginContext subContext = context.createSubContext(false); subContext.initialize(); subContext.set(Plugin.class, subPlugin); subContext.set(PluginTree.Node.class, subTree); @@ -81,11 +76,14 @@ public void prepare(PluginContext context) { public void release(PluginContext context) { PluginTree.Node node = context.get(PluginTree.Node.class); for (PluginTree.Node child : node.getChildren()) { - PluginContext subContext = context.createSubContext(); - subContext.set(PluginTree.Node.class, child); - subContext.set(Plugin.class, child.getPlugin()); - child.getPlugin().release(subContext); - subContext.destroy(); + if (child.getValue() instanceof Plugin) { + Plugin subPlugin = (Plugin) child.getValue(); + PluginContext subContext = context.createSubContext(false); + subContext.set(PluginTree.Node.class, child); + subContext.set(Plugin.class, subPlugin); + subPlugin.release(subContext); + subContext.destroy(); + } } for (PluginReader reader : readers) { try { @@ -97,7 +95,7 @@ public void release(PluginContext context) { onRelease(context); } - public abstract Collection collectEntries(PluginContext context); + public abstract Collection collectEntries(PluginContext context); public void onPrepare(PluginContext context) { diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/concept/AbstractPluginConcept.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/concept/AbstractPluginConcept.java index e16788fce..49d8bf8e4 100644 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/concept/AbstractPluginConcept.java +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/concept/AbstractPluginConcept.java @@ -9,8 +9,9 @@ import com.github.linyuzai.plugin.core.extract.PluginExtractor; import com.github.linyuzai.plugin.core.factory.PluginFactory; import com.github.linyuzai.plugin.core.filter.PluginFilter; +import com.github.linyuzai.plugin.core.handle.PluginHandler; +import com.github.linyuzai.plugin.core.handle.PluginHandlerChain; import com.github.linyuzai.plugin.core.resolve.PluginResolver; -import com.github.linyuzai.plugin.core.resolve.PluginResolverChainImpl; import com.github.linyuzai.plugin.core.tree.PluginTree; import com.github.linyuzai.plugin.core.tree.PluginTreeFactory; import lombok.Getter; @@ -28,14 +29,16 @@ public abstract class AbstractPluginConcept implements PluginConcept { /** * 上下文工厂 */ - protected PluginContextFactory pluginContextFactory; + protected PluginContextFactory contextFactory; /** * 事件发布者 */ - protected PluginEventPublisher pluginEventPublisher; + protected PluginEventPublisher eventPublisher; - protected PluginTreeFactory pluginTreeFactory; + protected PluginTreeFactory treeFactory; + + protected PluginHandlerChain handlerChain; /** * 插件工厂 @@ -45,17 +48,17 @@ public abstract class AbstractPluginConcept implements PluginConcept { /** * 插件解析器 */ - protected Collection pluginResolvers; + protected Collection resolvers; /** * 插件过滤器 */ - protected Collection pluginFilters; + protected Collection filters; /** * 插件提取器 */ - protected Collection pluginExtractors; + protected Collection extractors; /** * 插件缓存 @@ -69,13 +72,14 @@ public abstract class AbstractPluginConcept implements PluginConcept { * @return 插件 {@link Plugin} */ @Override - public Plugin create(Object o) { + public Plugin create(Object o, PluginContext context) { if (o instanceof Plugin) { return (Plugin) o; } for (PluginFactory factory : pluginFactories) { - if (factory.support(o, this)) { - return factory.create(o, this); + Plugin plugin = factory.create(o, context); + if (plugin != null) { + return plugin; } } return null; @@ -94,49 +98,52 @@ public Plugin create(Object o) { */ @Override public Plugin load(Object o) { - Plugin plugin = create(o); + //创建上下文 + PluginContext context = contextFactory.create(this); + context.set(PluginConcept.class, this); + //初始化上下文 + context.initialize(); + + Plugin plugin = create(o, context); if (plugin == null) { throw new PluginException("Plugin can not create: " + o); } plugin.setConcept(this); - pluginEventPublisher.publish(new PluginCreatedEvent(plugin)); + eventPublisher.publish(new PluginCreatedEvent(plugin)); - //创建上下文 - PluginContext context = pluginContextFactory.create(this); - //初始化上下文 - context.initialize(); context.set(Plugin.class, plugin); - PluginTree tree = pluginTreeFactory.create(plugin, this); + PluginTree tree = treeFactory.create(plugin, this); context.set(PluginTree.class, tree); context.set(PluginTree.Node.class, tree.getRoot()); //准备插件 plugin.prepare(context); //在上下文中添加事件发布者 - context.set(PluginEventPublisher.class, pluginEventPublisher); + context.set(PluginEventPublisher.class, eventPublisher); - pluginEventPublisher.publish(new PluginPreparedEvent(plugin)); + eventPublisher.publish(new PluginPreparedEvent(plugin)); //解析插件 - new PluginResolverChainImpl(new ArrayList<>(pluginResolvers), new ArrayList<>(pluginFilters)) - .next(context); + /*new PluginResolverChainImpl(new ArrayList<>(resolvers), new ArrayList<>(filters)) + .next(context);*/ + handlerChain.next(context); //提取插件 - for (PluginExtractor extractor : pluginExtractors) { + for (PluginExtractor extractor : extractors) { extractor.extract(context); } plugin.release(context); //销毁上下文 context.destroy(); - pluginEventPublisher.publish(new PluginReleasedEvent(plugin)); + eventPublisher.publish(new PluginReleasedEvent(plugin)); plugins.put(plugin.getId(), plugin); - pluginEventPublisher.publish(new PluginLoadedEvent(plugin)); + eventPublisher.publish(new PluginLoadedEvent(plugin)); return plugin; } @@ -152,12 +159,12 @@ public Plugin unload(Object o) { if (plugin == null) { if (o instanceof Plugin) { if (plugins.values().remove(o)) { - pluginEventPublisher.publish(new PluginUnloadedEvent((Plugin) o)); + eventPublisher.publish(new PluginUnloadedEvent((Plugin) o)); return (Plugin) o; } } } else { - pluginEventPublisher.publish(new PluginUnloadedEvent(plugin)); + eventPublisher.publish(new PluginUnloadedEvent(plugin)); return plugin; } return null; @@ -181,7 +188,7 @@ public boolean isLoad(Object o) { */ @Override public void publish(Object event) { - pluginEventPublisher.publish(event); + eventPublisher.publish(event); } /** @@ -442,17 +449,17 @@ protected void preBuild() { private void addResolversDependOnExtractors(Collection extractors) { for (PluginExtractor extractor : extractors) { //插件提取器依赖的插件解析器 - Collection> dependencies = extractor.getDependencies(); - for (Class dependency : dependencies) { + Class[] dependencies = extractor.getDependencies(); + for (Class dependency : dependencies) { //已经存在 if (containsResolver(dependency)) { continue; } //获得对应的实现类 - Class implOrDefault = - resolverDefaultImpl.getOrDefault(dependency, dependency); + /*Class implOrDefault = + resolverDefaultImpl.getOrDefault(dependency, dependency);*/ //实例化 - PluginResolver resolver = implOrDefault.newInstance(); + PluginResolver resolver = (PluginResolver) dependency.newInstance(); //添加该插件解析器依赖的解析器 addResolversWithDependencies(Collections.singletonList(resolver)); } @@ -473,11 +480,11 @@ private void addResolversWithDependencies(Collection r pluginResolvers.add(0, resolver); } - Set> unfounded = new HashSet<>(); + Set> unfounded = new HashSet<>(); for (PluginResolver resolver : resolvers) { //插件解析器依赖的插件解析器 - Collection> dependencies = resolver.getDependencies(); - for (Class dependency : dependencies) { + Class[] dependencies = resolver.getDependencies(); + for (Class dependency : dependencies) { //已经存在 if (containsResolver(dependency)) { continue; @@ -488,12 +495,10 @@ private void addResolversWithDependencies(Collection r List unfoundedPluginResolvers = new ArrayList<>(); if (!unfounded.isEmpty()) { //遍历需要但是还没有的插件解析器类 - for (Class dependency : unfounded) { + for (Class dependency : unfounded) { //获得对应的实现类 - Class implOrDefault = - resolverDefaultImpl.getOrDefault(dependency, dependency); //实例化 - PluginResolver instance = implOrDefault.newInstance(); + PluginResolver instance = (PluginResolver) dependency.newInstance(); unfoundedPluginResolvers.add(instance); } //添加这些新实例化的插件解析器依赖的插件解析器 @@ -507,7 +512,7 @@ private void addResolversWithDependencies(Collection r * @param target 目标插件解析器类 * @return 如果已经存在返回 true 否则返回 false */ - private boolean containsResolver(Class target) { + private boolean containsResolver(Class target) { for (PluginResolver resolver : pluginResolvers) { if (target.isInstance(resolver)) { return true; diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/concept/Plugin.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/concept/Plugin.java index 140334494..d59eabb20 100644 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/concept/Plugin.java +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/concept/Plugin.java @@ -1,32 +1,22 @@ package com.github.linyuzai.plugin.core.concept; import com.github.linyuzai.plugin.core.context.PluginContext; -import com.github.linyuzai.plugin.core.read.PluginReadable; -import com.github.linyuzai.plugin.core.read.PluginReader; -import com.github.linyuzai.plugin.core.read.metadata.PluginMetadata; import java.io.IOException; +import java.io.InputStream; /** * 插件抽象 */ public interface Plugin { - String PREFIX = "CONCEPT_PLUGIN@"; - - String PATH_NAME = PREFIX + "PATH_NAME"; - - String BYTE_ARRAY = PREFIX + "BYTE_ARRAY"; - - String PROPERTIES_NAME = PREFIX + "PROPERTIES_NAME"; - - String PROPERTIES = PREFIX + "PROPERTIES"; - Object getId(); T read(Class readable, Object key); - PluginMetadata getMetadata(); + Metadata getMetadata(); + + void setMetadata(Metadata metadata); PluginConcept getConcept(); @@ -41,4 +31,29 @@ public interface Plugin { * 释放 */ void release(PluginContext context); + + interface Metadata { + + String get(String key); + + String get(String key, String defaultValue); + + boolean isEmpty(); + } + + interface Entry { + + Object getId(); + + String getName(); + + Plugin getPlugin(); + + Content getContent(); + } + + interface Content { + + InputStream getInputStream() throws IOException; + } } diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/concept/PluginConcept.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/concept/PluginConcept.java index 52c354b02..92922fcd0 100644 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/concept/PluginConcept.java +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/concept/PluginConcept.java @@ -1,6 +1,7 @@ package com.github.linyuzai.plugin.core.concept; -import java.io.IOException; +import com.github.linyuzai.plugin.core.context.PluginContext; + import java.util.Map; /** @@ -14,7 +15,7 @@ public interface PluginConcept { * @param o 插件源 * @return 插件 {@link Plugin} */ - Plugin create(Object o); + Plugin create(Object o, PluginContext context); /** * 加载插件 diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/concept/PluginEntry.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/concept/PluginEntry.java deleted file mode 100644 index 4ae199e88..000000000 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/concept/PluginEntry.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.github.linyuzai.plugin.core.concept; - -import com.github.linyuzai.plugin.core.read.content.PluginContent; - -public interface PluginEntry { - - String getName(); - - Plugin getPlugin(); - - PluginContent getContent(); -} diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/context/DefaultPluginContext.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/context/DefaultPluginContext.java index c3bb5e3dc..d11740380 100644 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/context/DefaultPluginContext.java +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/context/DefaultPluginContext.java @@ -20,8 +20,12 @@ public class DefaultPluginContext implements PluginContext { private final Map map = new LinkedHashMap<>(); @Override - public PluginContext createSubContext() { - return new DefaultPluginContext(this); + public PluginContext createSubContext(boolean inherit) { + DefaultPluginContext context = new DefaultPluginContext(this); + if (inherit) { + context.map.putAll(this.map); + } + return context; } /** diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/context/DefaultPluginContextFactory.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/context/DefaultPluginContextFactory.java index 470c08e15..23a5071ee 100644 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/context/DefaultPluginContextFactory.java +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/context/DefaultPluginContextFactory.java @@ -1,6 +1,5 @@ package com.github.linyuzai.plugin.core.context; -import com.github.linyuzai.plugin.core.concept.Plugin; import com.github.linyuzai.plugin.core.concept.PluginConcept; /** diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/context/PluginContext.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/context/PluginContext.java index df5546296..fdbc5020f 100644 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/context/PluginContext.java +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/context/PluginContext.java @@ -15,7 +15,7 @@ public interface PluginContext { * @return {@link PluginConcept} */ default PluginConcept getConcept() { - return getPlugin().getConcept(); + return get(PluginConcept.class); } /** @@ -37,7 +37,7 @@ default PluginContext getRoot() { PluginContext getParent(); - PluginContext createSubContext(); + PluginContext createSubContext(boolean inherit); void publish(Object event); diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/convert/AbstractPluginConvertor.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/convert/AbstractPluginConvertor.java index 8bb6786d6..068c8783b 100644 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/convert/AbstractPluginConvertor.java +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/convert/AbstractPluginConvertor.java @@ -1,6 +1,7 @@ package com.github.linyuzai.plugin.core.convert; import com.github.linyuzai.plugin.core.context.PluginContext; +import com.github.linyuzai.plugin.core.tree.PluginTree; /** * {@link PluginConvertor} 抽象类。 @@ -20,10 +21,15 @@ public abstract class AbstractPluginConvertor implements PluginConvertor { @SuppressWarnings("unchecked") @Override public Object convert(Object source, PluginContext context) { - T original = (T) source; - R converted = doConvert(original); - context.publish(new PluginConvertedEvent(context, this, original, converted)); - return converted; + PluginTree.Node inbound = (PluginTree.Node) source; + PluginTree tree = context.get(PluginTree.class); + PluginTree.Node outbound = tree.getTransformer() + .create(this) + .inbound(inbound) + .transform(node -> node.map(it -> doConvert((T) it.getValue()))) + .outbound(); + context.publish(new PluginConvertedEvent(context, this, inbound, outbound)); + return outbound; } /** diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/convert/ByteArrayToInputStreamMapConvertor.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/convert/ByteArrayToInputStreamMapConvertor.java deleted file mode 100644 index da78ee512..000000000 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/convert/ByteArrayToInputStreamMapConvertor.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.github.linyuzai.plugin.core.convert; - -import java.io.ByteArrayInputStream; -import java.io.InputStream; -import java.util.LinkedHashMap; -import java.util.Map; - -/** - * byte[] 转 {@link InputStream} 的转换器 - */ -public class ByteArrayToInputStreamMapConvertor extends AbstractPluginConvertor, Map> { - - /** - * 将所有的 byte[] 转为 {@link ByteArrayInputStream} - * - * @param source value 类型为 byte[] 的 {@link Map} - * @return value 类型为 {@link ByteArrayInputStream} 的 {@link Map} - */ - @Override - public Map doConvert(Map source) { - Map map = new LinkedHashMap<>(); - for (Map.Entry entry : source.entrySet()) { - map.put(entry.getKey(), new ByteArrayInputStream(entry.getValue())); - } - return map; - } -} diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/convert/ByteArrayToStringMapConvertor.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/convert/ByteArrayToStringMapConvertor.java deleted file mode 100644 index dfa8c80f0..000000000 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/convert/ByteArrayToStringMapConvertor.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.github.linyuzai.plugin.core.convert; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; - -import java.nio.charset.Charset; -import java.util.LinkedHashMap; -import java.util.Map; - -/** - * byte[] 转 {@link String} 的转换器 - */ -@Setter -@Getter -@NoArgsConstructor -@AllArgsConstructor -public class ByteArrayToStringMapConvertor extends AbstractPluginConvertor, Map> { - - /** - * 编码 - */ - private Charset charset; - - public ByteArrayToStringMapConvertor(String charset) { - this.charset = Charset.forName(charset); - } - - /** - * 将所有的 byte[] 转为 {@link String} - * - * @param source value 类型为 byte[] 的 {@link Map} - * @return value 类型为 {@link String} 的 {@link Map} - */ - @Override - public Map doConvert(Map source) { - Map map = new LinkedHashMap<>(); - for (Map.Entry entry : source.entrySet()) { - String s = charset == null ? new String(entry.getValue()) : new String(entry.getValue(), charset); - map.put(entry.getKey(), s); - } - return map; - } -} diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/convert/ContentToByteArrayConvertor.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/convert/ContentToByteArrayConvertor.java new file mode 100644 index 000000000..6af940452 --- /dev/null +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/convert/ContentToByteArrayConvertor.java @@ -0,0 +1,27 @@ +package com.github.linyuzai.plugin.core.convert; + +import com.github.linyuzai.plugin.core.concept.Plugin; +import com.github.linyuzai.plugin.core.util.PluginUtils; +import lombok.SneakyThrows; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.util.Map; + +/** + * byte[] 转 {@link InputStream} 的转换器 + */ +public class ContentToByteArrayConvertor extends AbstractPluginConvertor { + + /** + * 将所有的 byte[] 转为 {@link ByteArrayInputStream} + * + * @param content value 类型为 byte[] 的 {@link Map} + * @return value 类型为 {@link ByteArrayInputStream} 的 {@link Map} + */ + @SneakyThrows + @Override + public byte[] doConvert(Plugin.Content content) { + return PluginUtils.read(content.getInputStream()); + } +} diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/convert/ContentToInputStreamConvertor.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/convert/ContentToInputStreamConvertor.java new file mode 100644 index 000000000..cdc937e50 --- /dev/null +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/convert/ContentToInputStreamConvertor.java @@ -0,0 +1,27 @@ +package com.github.linyuzai.plugin.core.convert; + +import com.github.linyuzai.plugin.core.concept.Plugin; +import lombok.SneakyThrows; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * byte[] 转 {@link InputStream} 的转换器 + */ +public class ContentToInputStreamConvertor extends AbstractPluginConvertor { + + /** + * 将所有的 byte[] 转为 {@link ByteArrayInputStream} + * + * @param content value 类型为 byte[] 的 {@link Map} + * @return value 类型为 {@link ByteArrayInputStream} 的 {@link Map} + */ + @SneakyThrows + @Override + public InputStream doConvert(Plugin.Content content) { + return content.getInputStream(); + } +} diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/convert/ContentToStringConvertor.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/convert/ContentToStringConvertor.java new file mode 100644 index 000000000..1480d3eee --- /dev/null +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/convert/ContentToStringConvertor.java @@ -0,0 +1,40 @@ +package com.github.linyuzai.plugin.core.convert; + +import com.github.linyuzai.plugin.core.concept.Plugin; +import com.github.linyuzai.plugin.core.util.PluginUtils; +import lombok.*; + +import java.nio.charset.Charset; +import java.util.Map; + +/** + * byte[] 转 {@link String} 的转换器 + */ +@Setter +@Getter +@NoArgsConstructor +@AllArgsConstructor +public class ContentToStringConvertor extends AbstractPluginConvertor { + + /** + * 编码 + */ + private Charset charset; + + public ContentToStringConvertor(String charset) { + this.charset = Charset.forName(charset); + } + + /** + * 将所有的 byte[] 转为 {@link String} + * + * @param content value 类型为 byte[] 的 {@link Map} + * @return value 类型为 {@link String} 的 {@link Map} + */ + @SneakyThrows + @Override + public String doConvert(Plugin.Content content) { + byte[] bytes = PluginUtils.read(content.getInputStream()); + return charset == null ? new String(bytes) : new String(bytes, charset); + } +} diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/convert/PluginConvertedEvent.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/convert/PluginConvertedEvent.java index dd63f9204..cf4f95ff2 100644 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/convert/PluginConvertedEvent.java +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/convert/PluginConvertedEvent.java @@ -18,20 +18,20 @@ public class PluginConvertedEvent extends PluginContextEvent { /** * 原始对象 */ - private final Object original; + private final Object inbound; /** * 转换后对象 */ - private final Object converted; + private final Object outbound; public PluginConvertedEvent(PluginContext context, PluginConvertor convertor, - Object original, - Object converted) { + Object inbound, + Object outbound) { super(context); this.convertor = convertor; - this.original = original; - this.converted = converted; + this.inbound = inbound; + this.outbound = outbound; } } diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/convert/PluginConvertor.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/convert/PluginConvertor.java index f3a17c957..f29a82ae4 100644 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/convert/PluginConvertor.java +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/convert/PluginConvertor.java @@ -1,12 +1,13 @@ package com.github.linyuzai.plugin.core.convert; import com.github.linyuzai.plugin.core.context.PluginContext; +import com.github.linyuzai.plugin.core.handle.PluginHandler; /** * 插件转换器。 * 如可将 {@link String} 类型的 json 数据转换为 {@link java.io.InputStream} 以适配指定的类型 */ -public interface PluginConvertor { +public interface PluginConvertor extends PluginHandler { /** * 转换 diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/convert/PropertiesToMapConvertor.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/convert/PropertiesToMapConvertor.java new file mode 100644 index 000000000..7bf2e917b --- /dev/null +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/convert/PropertiesToMapConvertor.java @@ -0,0 +1,40 @@ +package com.github.linyuzai.plugin.core.convert; + +import com.github.linyuzai.plugin.core.util.ReflectionUtils; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Setter; + +import java.util.Map; +import java.util.Properties; +import java.util.function.Supplier; + +/** + * {@link Properties} 转 {@link Map} 的转换器 + */ +@Setter +@Getter +@AllArgsConstructor +public class PropertiesToMapConvertor extends AbstractPluginConvertor, Map> { + + /** + * {@link Map} 类型 + */ + private Class mapClass; + + /** + * 将所有的 {@link Properties} 转为 {@link Map} + * + * @param supplier value 类型为 {@link Properties} 的 {@link Map} + * @return value 类型为 {@link Map} 的 {@link Map} + */ + @Override + public Map doConvert(Supplier supplier) { + Properties properties = supplier.get(); + Map propertiesToMap = ReflectionUtils.newMap(mapClass); + for (String propertyName : properties.stringPropertyNames()) { + propertiesToMap.put(propertyName, properties.getProperty(propertyName)); + } + return propertiesToMap; + } +} diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/convert/PropertiesToMapMapConvertor.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/convert/PropertiesToMapMapConvertor.java deleted file mode 100644 index f12da055b..000000000 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/convert/PropertiesToMapMapConvertor.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.github.linyuzai.plugin.core.convert; - -import com.github.linyuzai.plugin.core.util.ReflectionUtils; -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.Setter; - -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Properties; - -/** - * {@link Properties} 转 {@link Map} 的转换器 - */ -@Setter -@Getter -@AllArgsConstructor -public class PropertiesToMapMapConvertor extends AbstractPluginConvertor, Map>> { - - /** - * {@link Map} 类型 - */ - private Class mapClass; - - /** - * 将所有的 {@link Properties} 转为 {@link Map} - * - * @param source value 类型为 {@link Properties} 的 {@link Map} - * @return value 类型为 {@link Map} 的 {@link Map} - */ - @Override - public Map> doConvert(Map source) { - Map> map = new LinkedHashMap<>(); - for (Map.Entry entry : source.entrySet()) { - Map propertiesToMap = ReflectionUtils.newMap(mapClass); - Properties properties = entry.getValue(); - for (String propertyName : properties.stringPropertyNames()) { - propertiesToMap.put(propertyName, properties.getProperty(propertyName)); - } - map.put(entry.getKey(), propertiesToMap); - } - return map; - } -} diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/exception/PluginException.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/exception/PluginException.java index 0241d9ab3..07c4a308e 100644 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/exception/PluginException.java +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/exception/PluginException.java @@ -12,8 +12,4 @@ public PluginException(String message) { public PluginException(String message, Throwable cause) { super(message, cause); } - - public PluginException(Throwable cause) { - super(cause); - } } diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/extract/AbstractPluginExtractor.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/extract/AbstractPluginExtractor.java index 2f6c44dd0..f5b2258d4 100644 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/extract/AbstractPluginExtractor.java +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/extract/AbstractPluginExtractor.java @@ -4,6 +4,7 @@ import com.github.linyuzai.plugin.core.convert.PluginConvertor; import com.github.linyuzai.plugin.core.exception.PluginException; import com.github.linyuzai.plugin.core.format.PluginFormatter; +import com.github.linyuzai.plugin.core.handle.PluginHandler; import com.github.linyuzai.plugin.core.match.PluginMatcher; import com.github.linyuzai.plugin.core.resolve.PluginResolver; @@ -134,7 +135,7 @@ public void extract(PluginContext context) { * @return 依赖的解析器 {@link PluginResolver} 的类 */ @Override - public Collection> getDependencies() { + public Class[] getDependencies() { return getInvoker().getMatcher().getDependencies(); } } diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/extract/ContentExtractor.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/extract/ContentExtractor.java index dfbd9d2f6..6adc61266 100644 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/extract/ContentExtractor.java +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/extract/ContentExtractor.java @@ -1,7 +1,7 @@ package com.github.linyuzai.plugin.core.extract; -import com.github.linyuzai.plugin.core.convert.ByteArrayToInputStreamMapConvertor; -import com.github.linyuzai.plugin.core.convert.ByteArrayToStringMapConvertor; +import com.github.linyuzai.plugin.core.convert.ContentToInputStreamConvertor; +import com.github.linyuzai.plugin.core.convert.ContentToStringConvertor; import com.github.linyuzai.plugin.core.convert.PluginConvertor; import com.github.linyuzai.plugin.core.format.MapToObjectFormatter; import com.github.linyuzai.plugin.core.format.PluginFormatter; @@ -62,8 +62,8 @@ public PluginMatcher getMatcher(TypeMetadata metadata, Annotation[] annotations) /** * 根据 {@link TypeMetadata} 和注解获得 {@link PluginConvertor}。 - * 特殊情况,如果是 {@link InputStream} 返回 {@link ByteArrayToInputStreamMapConvertor}, - * {@link String} 返回 {@link ByteArrayToStringMapConvertor}。 + * 特殊情况,如果是 {@link InputStream} 返回 {@link ContentToInputStreamConvertor}, + * {@link String} 返回 {@link ContentToStringConvertor}。 * * @param metadata {@link TypeMetadata} * @param annotations 注解 @@ -73,10 +73,10 @@ public PluginMatcher getMatcher(TypeMetadata metadata, Annotation[] annotations) public PluginConvertor getConvertor(TypeMetadata metadata, Annotation[] annotations) { Class elementClass = metadata.getElementClass(); if (InputStream.class == elementClass) { - return new ByteArrayToInputStreamMapConvertor(); + return new ContentToInputStreamConvertor(); } if (String.class == elementClass) { - return new ByteArrayToStringMapConvertor(charset); + return new ContentToStringConvertor(charset); } return super.getConvertor(metadata, annotations); } diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/extract/DynamicExtractor.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/extract/DynamicExtractor.java index 8bc194a3d..53df7c8cc 100644 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/extract/DynamicExtractor.java +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/extract/DynamicExtractor.java @@ -3,7 +3,8 @@ import com.github.linyuzai.plugin.core.concept.Plugin; import com.github.linyuzai.plugin.core.context.PluginContext; import com.github.linyuzai.plugin.core.exception.PluginException; -import com.github.linyuzai.plugin.core.match.PluginContent; +import com.github.linyuzai.plugin.core.handle.PluginHandler; +import com.github.linyuzai.plugin.core.match.PluginText; import com.github.linyuzai.plugin.core.match.PluginProperties; import com.github.linyuzai.plugin.core.resolve.PluginResolver; import lombok.Getter; @@ -16,10 +17,8 @@ import java.lang.reflect.Type; import java.nio.charset.Charset; import java.util.Arrays; -import java.util.Collection; import java.util.LinkedHashMap; import java.util.Map; -import java.util.stream.Collectors; /** * 动态插件提取器。 @@ -77,7 +76,7 @@ public DynamicExtractor(@NonNull Object target) { * 通过 {@link Parameter} 获得一个执行器。 * 如果标注了特殊的注解将会直接匹配, * {@link PluginProperties} 返回 {@link PropertiesExtractor} 对应的执行器, - * {@link PluginContent} 返回 {@link ContentExtractor} 对应的执行器。 + * {@link PluginText} 返回 {@link ContentExtractor} 对应的执行器。 * 否则按照 {@link PluginContextExtractor} {@link PluginObjectExtractor} * {@link PropertiesExtractor} {@link ContentExtractor} 的顺序匹配执行器。 * @@ -118,13 +117,13 @@ public Invoker getInvoker(Parameter parameter) { */ public boolean hasExplicitAnnotation(Annotation annotation) { return annotation.annotationType() == PluginProperties.class || - annotation.annotationType() == PluginContent.class; + annotation.annotationType() == PluginText.class; } /** * 根据明确指定的注解获得对应的执行器。 * {@link PluginProperties} 返回 {@link PropertiesExtractor} 对应的执行器, - * {@link PluginContent} 返回 {@link ContentExtractor} 对应的执行器。 + * {@link PluginText} 返回 {@link ContentExtractor} 对应的执行器。 * * @param annotation 注解 * @param parameter 参数 {@link Parameter} @@ -134,8 +133,8 @@ public Invoker getExplicitInvoker(Annotation annotation, Parameter parameter) { if (annotation.annotationType() == PluginProperties.class) { return getPropertiesInvoker(parameter); } - if (annotation.annotationType() == PluginContent.class) { - String charset = ((PluginContent) annotation).charset(); + if (annotation.annotationType() == PluginText.class) { + String charset = ((PluginText) annotation).charset(); return getContentInvoker(parameter, charset.isEmpty() ? null : Charset.forName(charset)); } throw new PluginException(annotation + " has no explicit invoker"); @@ -309,12 +308,13 @@ public void extract(PluginContext context) { * * @return 所有依赖的解析器 {@link PluginResolver} 的类 */ + @SuppressWarnings("unchecked") @Override - public Collection> getDependencies() { + public Class[] getDependencies() { return methodInvokersMap.values().stream() .flatMap(it -> it.values().stream()) - .flatMap(it -> it.getMatcher().getDependencies().stream()) + .flatMap(it -> Arrays.stream(it.getMatcher().getDependencies())) .distinct() - .collect(Collectors.toList()); + .toArray(Class[]::new); } } diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/extract/PluginExtractor.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/extract/PluginExtractor.java index d13ba6aca..861a3033e 100644 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/extract/PluginExtractor.java +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/extract/PluginExtractor.java @@ -5,14 +5,13 @@ import com.github.linyuzai.plugin.core.format.PluginFormatter; import com.github.linyuzai.plugin.core.handle.PluginHandler; import com.github.linyuzai.plugin.core.match.PluginMatcher; -import com.github.linyuzai.plugin.core.resolve.PluginResolver; import lombok.Getter; import lombok.RequiredArgsConstructor; /** * 插件提取器 */ -public interface PluginExtractor extends PluginHandler.Dependency { +public interface PluginExtractor extends PluginHandler.Dependency { /** * 提取插件 diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/extract/PropertiesExtractor.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/extract/PropertiesExtractor.java index e4ad5b667..d8932c675 100644 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/extract/PropertiesExtractor.java +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/extract/PropertiesExtractor.java @@ -1,7 +1,7 @@ package com.github.linyuzai.plugin.core.extract; import com.github.linyuzai.plugin.core.convert.PluginConvertor; -import com.github.linyuzai.plugin.core.convert.PropertiesToMapMapConvertor; +import com.github.linyuzai.plugin.core.convert.PropertiesToMapConvertor; import com.github.linyuzai.plugin.core.exception.PluginException; import com.github.linyuzai.plugin.core.format.AbstractPluginFormatter; import com.github.linyuzai.plugin.core.format.MapToObjectFormatter; @@ -69,8 +69,8 @@ public TypeMetadata createTypeMetadata(Type type) { /** * 根据 {@link TypeMetadata} 和注解获得 {@link PluginConvertor}。 - * 特殊情况,如果是 {@link Properties} 或 {@link Map} 返回 {@link PropertiesToMapMapConvertor}, - * {@link String} 并且是一个 {@link Map} 则返回 {@link PropertiesToMapMapConvertor} 作为单个配置的类型。 + * 特殊情况,如果是 {@link Properties} 或 {@link Map} 返回 {@link PropertiesToMapConvertor}, + * {@link String} 并且是一个 {@link Map} 则返回 {@link PropertiesToMapConvertor} 作为单个配置的类型。 * * @param metadata {@link TypeMetadata} * @param annotations 注解 @@ -80,10 +80,10 @@ public TypeMetadata createTypeMetadata(Type type) { public PluginConvertor getConvertor(TypeMetadata metadata, Annotation[] annotations) { Class elementClass = metadata.getElementClass(); if (elementClass != Properties.class && Map.class.isAssignableFrom(elementClass)) { - return new PropertiesToMapMapConvertor(elementClass); + return new PropertiesToMapConvertor(elementClass); } if (metadata instanceof MapTypeMetadata && elementClass == String.class) { - return new PropertiesToMapMapConvertor(metadata.getContainerClass()); + return new PropertiesToMapConvertor(metadata.getContainerClass()); } return super.getConvertor(metadata, annotations); } diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/factory/MetadataPluginFactory.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/factory/MetadataPluginFactory.java new file mode 100644 index 000000000..9bfe79a2c --- /dev/null +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/factory/MetadataPluginFactory.java @@ -0,0 +1,28 @@ +package com.github.linyuzai.plugin.core.factory; + +import com.github.linyuzai.plugin.core.concept.Plugin; +import com.github.linyuzai.plugin.core.context.PluginContext; + +public abstract class MetadataPluginFactory implements PluginFactory { + + @Override + public Plugin create(Object o, PluginContext context) { + T source = getSource(o, context); + if (source == null) { + return null; + } + Plugin.Metadata metadata = createMetadata(source, context); + if (metadata == null) { + return null; + } + Plugin plugin = doCreate(source, metadata, context); + plugin.setMetadata(metadata); + return plugin; + } + + public abstract Plugin doCreate(T o, Plugin.Metadata metadata, PluginContext context); + + protected abstract T getSource(Object o, PluginContext context); + + protected abstract Plugin.Metadata createMetadata(T o, PluginContext context); +} diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/factory/PluginFactory.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/factory/PluginFactory.java index fbaba49bb..4f4a5cb0c 100644 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/factory/PluginFactory.java +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/factory/PluginFactory.java @@ -2,27 +2,19 @@ import com.github.linyuzai.plugin.core.concept.Plugin; import com.github.linyuzai.plugin.core.concept.PluginConcept; +import com.github.linyuzai.plugin.core.context.PluginContext; /** * 插件工厂 */ public interface PluginFactory { - /** - * 是否支持插件创建 - * - * @param o 插件源 - * @param concept {@link PluginConcept} - * @return 如果支持返回 true,否则返回 false - */ - boolean support(Object o, PluginConcept concept); - /** * 创建插件 {@link Plugin} * * @param o 插件源 - * @param concept {@link PluginConcept} + * @param context 插件上下文 * @return 插件 {@link Plugin} */ - Plugin create(Object o, PluginConcept concept); + Plugin create(Object o, PluginContext context); } diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/factory/SubPluginFactory.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/factory/SubPluginFactory.java index ff268885c..2cd283e02 100644 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/factory/SubPluginFactory.java +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/factory/SubPluginFactory.java @@ -1,26 +1,17 @@ package com.github.linyuzai.plugin.core.factory; import com.github.linyuzai.plugin.core.concept.Plugin; -import com.github.linyuzai.plugin.core.concept.PluginConcept; -import com.github.linyuzai.plugin.core.concept.PluginEntry; +import com.github.linyuzai.plugin.core.context.PluginContext; public abstract class SubPluginFactory implements PluginFactory { @Override - public boolean support(Object o, PluginConcept concept) { - if (o instanceof PluginEntry) { - return doSupport((PluginEntry) o, concept); - } else { - return false; + public Plugin create(Object o, PluginContext context) { + if (o instanceof Plugin.Entry) { + return doCreate((Plugin.Entry) o, context); } + return null; } - public abstract boolean doSupport(PluginEntry entry, PluginConcept concept); - - @Override - public Plugin create(Object o, PluginConcept concept) { - return doCreate((PluginEntry) o, concept); - } - - public abstract Plugin doCreate(PluginEntry entry, PluginConcept concept); + public abstract Plugin doCreate(Plugin.Entry entry, PluginContext context); } diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/filter/AbstractPluginFilter.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/filter/AbstractPluginFilter.java index 24ce16700..dfc23728e 100644 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/filter/AbstractPluginFilter.java +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/filter/AbstractPluginFilter.java @@ -44,19 +44,7 @@ public void filter(PluginContext context) { .inboundKey(inboundKey) .transform(node -> node.filter(it -> applyNegation(doFilter((T) it.getValue())))) .outboundKey(outboundKey); - /*Object key = getKey(); - T original = context.get(key); - if (original == null) { - throw new PluginException("No plugin can be filtered with key: " + key); - } - T filtered = doFilter(original); - context.set(key, filtered); - context.publish(new PluginFilteredEvent(context, this, original, filtered));*/ - } - - @Override - public boolean support(PluginContext context) { - return context.contains(PluginTree.class); + context.publish(new PluginFilteredEvent(context, this, inboundKey, outboundKey)); } /** diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/filter/FilterWithResolver.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/filter/FilterWithResolver.java deleted file mode 100644 index b3f6497de..000000000 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/filter/FilterWithResolver.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.github.linyuzai.plugin.core.filter; - -import com.github.linyuzai.plugin.core.resolve.PluginResolver; - -import java.lang.annotation.*; - -/** - * 标记在 {@link PluginFilter} 上用于指定过滤器对应的插件解析器 {@link PluginResolver} - */ -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -@Documented -@Deprecated -public @interface FilterWithResolver { - - Class value(); -} diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/filter/NameFilter.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/filter/NameFilter.java index 438610e67..d53f7bd55 100644 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/filter/NameFilter.java +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/filter/NameFilter.java @@ -1,7 +1,6 @@ package com.github.linyuzai.plugin.core.filter; import com.github.linyuzai.plugin.core.concept.Plugin; -import com.github.linyuzai.plugin.core.concept.PluginEntry; import com.github.linyuzai.plugin.core.handle.HandlerDependency; import com.github.linyuzai.plugin.core.resolve.EntryResolver; import com.github.linyuzai.plugin.core.util.AntPathMatcher; @@ -15,7 +14,7 @@ */ @Getter @HandlerDependency(EntryResolver.class) -public class NameFilter extends AbstractPluginFilter { +public class NameFilter extends AbstractPluginFilter { /** * 名称模式 @@ -34,11 +33,11 @@ public NameFilter(Collection names) { @Override public Object getKey() { - return Plugin.PATH_NAME; + return Plugin.Entry.class; } @Override - public boolean doFilter(PluginEntry entry) { + public boolean doFilter(Plugin.Entry entry) { return matchName(entry.getName()); } diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/filter/PathFilter.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/filter/PathFilter.java index 3fa9d7c49..e7579b7d2 100644 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/filter/PathFilter.java +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/filter/PathFilter.java @@ -1,6 +1,6 @@ package com.github.linyuzai.plugin.core.filter; -import com.github.linyuzai.plugin.core.concept.PluginEntry; +import com.github.linyuzai.plugin.core.concept.Plugin; import com.github.linyuzai.plugin.core.handle.HandlerDependency; import com.github.linyuzai.plugin.core.resolve.EntryResolver; import com.github.linyuzai.plugin.core.util.AntPathMatcher; @@ -14,7 +14,7 @@ */ @Getter @HandlerDependency(EntryResolver.class) -public class PathFilter extends AbstractPluginFilter { +public class PathFilter extends AbstractPluginFilter { /** * 路径模式 @@ -32,13 +32,13 @@ public PathFilter(Collection paths) { } @Override - public boolean doFilter(PluginEntry entry) { + public boolean doFilter(Plugin.Entry entry) { return matchPath(entry.getName()); } @Override public Object getKey() { - return PluginEntry.class; + return Plugin.Entry.class; } /** diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/filter/PluginFilter.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/filter/PluginFilter.java index 3d2aa6002..91004a0b9 100644 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/filter/PluginFilter.java +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/filter/PluginFilter.java @@ -2,17 +2,11 @@ import com.github.linyuzai.plugin.core.handle.PluginHandler; import com.github.linyuzai.plugin.core.context.PluginContext; -import com.github.linyuzai.plugin.core.resolve.PluginResolver; /** * 插件过滤器 */ -public interface PluginFilter extends PluginHandler, PluginHandler.Dependency { - - @Override - default void handle(PluginContext context) { - filter(context); - } +public interface PluginFilter extends PluginHandler, PluginHandler.Dependency { /** * 过滤插件 diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/filter/PluginFilteredEvent.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/filter/PluginFilteredEvent.java index 3893b8630..f0b419efc 100644 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/filter/PluginFilteredEvent.java +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/filter/PluginFilteredEvent.java @@ -16,22 +16,22 @@ public class PluginFilteredEvent extends PluginContextEvent { private final PluginFilter filter; /** - * 原始对象 + * 依赖的 key */ - private final Object original; + private final Object inboundKey; /** - * 过滤后对象 + * 解析的 key */ - private final Object filtered; + private final Object outboundKey; public PluginFilteredEvent(PluginContext context, PluginFilter filter, - Object original, - Object filtered) { + Object inboundKey, + Object outboundKey) { super(context); this.filter = filter; - this.original = original; - this.filtered = filtered; + this.inboundKey = inboundKey; + this.outboundKey = outboundKey; } } diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/filter/PropertiesFilter.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/filter/PropertiesFilter.java index b25995f5a..8ec9a0323 100644 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/filter/PropertiesFilter.java +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/filter/PropertiesFilter.java @@ -1,16 +1,16 @@ package com.github.linyuzai.plugin.core.filter; -import com.github.linyuzai.plugin.core.concept.Plugin; import com.github.linyuzai.plugin.core.util.AntPathMatcher; import lombok.Getter; import java.util.*; +import java.util.function.Supplier; /** * {@link Properties} 过滤器 */ @Getter -public class PropertiesFilter extends AbstractPluginFilter> { +public class PropertiesFilter extends AbstractPluginFilter> { /** * 属性健模式 @@ -29,33 +29,25 @@ public PropertiesFilter(Collection keys) { @Override public Object getKey() { - return Plugin.PROPERTIES; + return Properties.class; } /** * 遍历所有的 {@link Properties} 并过滤重新重新生成新的 {@link Properties} * - * @param plugins 需要过滤的 {@link Properties} + * @param supplier 需要过滤的 {@link Properties} * @return 过滤之后的 {@link Properties} */ @Override - public boolean doFilter(Map plugins) { - Map map = new LinkedHashMap<>(); - for (Map.Entry entry : plugins.entrySet()) { - Properties properties = entry.getValue(); - Set propertyNames = properties.stringPropertyNames(); - Properties newProperties = new Properties(); - for (String propertyName : propertyNames) { - if (applyNegation(matchPropertiesKey(propertyName))) { - String propertyValue = properties.getProperty(propertyName); - newProperties.setProperty(propertyName, propertyValue); - } - } - if (!newProperties.isEmpty()) { - map.put(entry.getKey(), newProperties); + public boolean doFilter(Supplier supplier) { + Properties properties = supplier.get(); + Set propertyNames = properties.stringPropertyNames(); + for (String propertyName : propertyNames) { + if (matchPropertiesKey(propertyName)) { + return true; } } - return true; + return false; } /** diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/handle/DefaultPluginHandlerChain.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/handle/DefaultPluginHandlerChain.java new file mode 100644 index 000000000..5a2346b30 --- /dev/null +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/handle/DefaultPluginHandlerChain.java @@ -0,0 +1,130 @@ +package com.github.linyuzai.plugin.core.handle; + +import com.github.linyuzai.plugin.core.context.PluginContext; +import com.github.linyuzai.plugin.core.filter.PluginFilter; +import com.github.linyuzai.plugin.core.resolve.PluginResolver; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; + +public class DefaultPluginHandlerChain implements PluginHandlerChain { + + private final List entries = new ArrayList<>(); + + public DefaultPluginHandlerChain(List handlers) { + List resolvers = new ArrayList<>(); + List filters = new ArrayList<>(); + for (PluginHandler handler : handlers) { + if (handler instanceof PluginResolver) { + resolvers.add(handler); + } + if (handler instanceof PluginFilter) { + filters.add(handler); + } + } + List sorted = resolveDependency(resolvers); + for (PluginHandler handler : sorted) { + List filtered = filters.stream().filter(it -> { + if (it instanceof PluginHandler.Dependency) { + Class[] dependencies = + ((PluginHandler.Dependency) it).getDependencies(); + for (Class dependency : dependencies) { + if (dependency.isInstance(handler)) { + return true; + } + } + return false; + } else { + return true; + } + }).collect(Collectors.toList()); + entries.add(new Entry(handler, filtered)); + } + } + + protected List resolveDependency(List unsorted) { + List container = new ArrayList<>(); + for (PluginHandler handler : unsorted) { + resolveDependency(handler, unsorted, container); + } + return container; + } + + //TODO 循环依赖校验 + protected void resolveDependency(PluginHandler handler, + Collection handlers, + Collection container) { + //Stack stack = new Stack<>(); + if (handler instanceof PluginHandler.Dependency) { + Class[] dependencies = + ((PluginHandler.Dependency) handler).getDependencies(); + if (dependencies.length == 0) { + container.add(handler); + } else { + for (Class dependency : dependencies) { + if (containsDependency(dependency, container)) { + continue; + } + PluginHandler dependence = findDependency(dependency, handlers); + if (dependence == null) { + throw new IllegalArgumentException("Dependency not found: " + dependency); + } + resolveDependency(dependence, handlers, container); + } + container.add(handler); + } + } else { + container.add(handler); + } + } + + protected boolean containsDependency(Class dependency, + Collection handlers) { + for (PluginHandler handler : handlers) { + if (dependency.isInstance(handler)) { + return true; + } + } + return false; + } + + protected PluginHandler findDependency(Class dependency, + Collection handlers) { + for (PluginHandler handler : handlers) { + if (dependency.isInstance(handler)) { + return handler; + } + } + return null; + } + + @Override + public void next(PluginContext context) { + doNext(context, 0); + } + + protected void doNext(PluginContext context, int index) { + if (index >= entries.size()) { + return; + } + Entry entry = entries.get(index); + ((PluginResolver) entry.resolver).resolve(context); + for (PluginHandler filter : entry.filters) { + ((PluginFilter) filter).filter(context); + } + doNext(context, index + 1); + } + + @Getter + @RequiredArgsConstructor + public static class Entry { + + private final PluginHandler resolver; + + private final List filters; + } +} diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/handle/PluginHandler.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/handle/PluginHandler.java index 09849cde0..b4196edcf 100644 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/handle/PluginHandler.java +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/handle/PluginHandler.java @@ -1,30 +1,10 @@ package com.github.linyuzai.plugin.core.handle; -import com.github.linyuzai.plugin.core.context.PluginContext; import com.github.linyuzai.plugin.core.util.ReflectionUtils; -import java.util.Arrays; -import java.util.Collection; -import java.util.stream.Collectors; - public interface PluginHandler { - /** - * 处理 - * - * @param context 上下文 {@link PluginContext} - */ - void handle(PluginContext context); - - /** - * 是否支持 - * - * @param context 上下文 {@link PluginContext} - * @return 如果支持返回 true 否则返回 false - */ - boolean support(PluginContext context); - - interface Dependency { + interface Dependency { /** * 获得依赖的处理器类。 @@ -32,14 +12,12 @@ interface Dependency { * @return 依赖的处理器类 */ @SuppressWarnings("unchecked") - default Collection> getDependencies() { + default Class[] getDependencies() { HandlerDependency annotation = ReflectionUtils.findAnnotation(getClass(), HandlerDependency.class); - if (annotation != null) { - return Arrays.stream(annotation.value()) - .map(it -> (Class) it) - .collect(Collectors.toList()); + if (annotation == null) { + return new Class[0]; } - return null; + return annotation.value(); } } } diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/handle/PluginHandlerChain.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/handle/PluginHandlerChain.java new file mode 100644 index 000000000..e698663dd --- /dev/null +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/handle/PluginHandlerChain.java @@ -0,0 +1,8 @@ +package com.github.linyuzai.plugin.core.handle; + +import com.github.linyuzai.plugin.core.context.PluginContext; + +public interface PluginHandlerChain { + + void next(PluginContext context); +} diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/match/AbstractPluginMatcher.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/match/AbstractPluginMatcher.java index 2e3a8b869..45fdcc5c4 100644 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/match/AbstractPluginMatcher.java +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/match/AbstractPluginMatcher.java @@ -1,13 +1,15 @@ package com.github.linyuzai.plugin.core.match; +import com.github.linyuzai.plugin.core.concept.Plugin; import com.github.linyuzai.plugin.core.context.PluginContext; -import com.github.linyuzai.plugin.core.exception.PluginException; import com.github.linyuzai.plugin.core.filter.NameFilter; import com.github.linyuzai.plugin.core.filter.PathFilter; +import com.github.linyuzai.plugin.core.tree.PluginTree; import lombok.Getter; import lombok.NonNull; import java.lang.annotation.Annotation; +import java.util.concurrent.atomic.AtomicInteger; /** * {@link PluginMatcher} 抽象类。 @@ -52,36 +54,52 @@ public AbstractPluginMatcher(@NonNull Annotation[] annotations) { */ @Override public Object match(PluginContext context) { - Object key = getKey(); - T source = context.get(key); - if (source == null) { - throw new PluginException("Plugin can not be matched with key: " + key); + Object inboundKey = getKey(); + PluginTree tree = context.get(PluginTree.class); + PluginTree.Node outbound = tree.getTransformer() + .create(this) + .inboundKey(inboundKey) + .transform(node -> node.filter(it -> filter(it, context))) + .outbound(); + if (hasContent(outbound)) { + context.publish(new PluginMatchedEvent(context, this, inboundKey, outbound)); + return outbound; } - T filtered = filter(source); - if (filtered == null) { - return null; - } - if (isEmpty(filtered)) { - return null; - } - context.publish(new PluginMatchedEvent(context, this, source, filtered)); - return filtered; + return null; } /** * 结合路径和名称进行过滤 * - * @param pathAndName 路径名称 + * @param node 路径名称 * @return 是否满足过滤条件 */ - public boolean filterWithAnnotation(String pathAndName) { - if (pathFilter != null && !pathFilter.matchPath(pathAndName)) { + @SuppressWarnings("unchecked") + public boolean filter(PluginTree.Node node, PluginContext context) { + if (pathFilter != null && !pathFilter.matchPath(node.getName())) { return false; } - if (nameFilter != null && !nameFilter.matchName(pathAndName)) { + if (nameFilter != null && !nameFilter.matchName(node.getName())) { return false; } - return true; + return doFilter((T) node.getValue(), context); + } + + /** + * 过滤后的插件是否为空 + * + * @param node 过滤后的插件 + * @return 如果为空返回 true 否则返回 false + */ + public boolean hasContent(PluginTree.Node node) { + AtomicInteger size = new AtomicInteger(0); + node.forEach(it -> { + if (it instanceof Plugin) { + return; + } + size.incrementAndGet(); + }); + return size.get() > 0; } /** @@ -97,13 +115,5 @@ public boolean filterWithAnnotation(String pathAndName) { * @param source 被过滤的插件 * @return 过滤后的插件 */ - public abstract T filter(T source); - - /** - * 过滤后的插件是否为空 - * - * @param filtered 过滤后的插件 - * @return 如果为空返回 true 否则返回 false - */ - public abstract boolean isEmpty(T filtered); + public abstract boolean doFilter(T source, PluginContext context); } diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/match/ContentMatcher.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/match/ContentMatcher.java index 3c79343cb..f82672047 100644 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/match/ContentMatcher.java +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/match/ContentMatcher.java @@ -1,18 +1,17 @@ package com.github.linyuzai.plugin.core.match; import com.github.linyuzai.plugin.core.concept.Plugin; +import com.github.linyuzai.plugin.core.context.PluginContext; import com.github.linyuzai.plugin.core.handle.HandlerDependency; import com.github.linyuzai.plugin.core.resolve.ContentResolver; import java.lang.annotation.Annotation; -import java.util.LinkedHashMap; -import java.util.Map; /** * 内容匹配器 */ @HandlerDependency(ContentResolver.class) -public class ContentMatcher extends AbstractPluginMatcher> { +public class ContentMatcher extends AbstractPluginMatcher { public ContentMatcher(Annotation[] annotations) { super(annotations); @@ -20,27 +19,11 @@ public ContentMatcher(Annotation[] annotations) { @Override public Object getKey() { - return Plugin.BYTE_ARRAY; + return Plugin.Content.class; } @Override - public Map filter(Map bytesMap) { - Map map = new LinkedHashMap<>(); - for (Map.Entry entry : bytesMap.entrySet()) { - Object key = entry.getKey(); - if (key instanceof String) { - if (filterWithAnnotation((String) key)) { - map.put(entry.getKey(), entry.getValue()); - } - } else { - map.put(entry.getKey(), entry.getValue()); - } - } - return map; - } - - @Override - public boolean isEmpty(Map filtered) { - return filtered.isEmpty(); + public boolean doFilter(Plugin.Content source, PluginContext context) { + return true; } } diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/match/PluginContextMatcher.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/match/PluginContextMatcher.java index 9b160125f..3f2bffa57 100644 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/match/PluginContextMatcher.java +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/match/PluginContextMatcher.java @@ -1,14 +1,14 @@ package com.github.linyuzai.plugin.core.match; import com.github.linyuzai.plugin.core.context.PluginContext; -import lombok.AllArgsConstructor; import lombok.Getter; +import lombok.RequiredArgsConstructor; /** * 插件上下文 {@link PluginContext} 匹配器 */ @Getter -@AllArgsConstructor +@RequiredArgsConstructor public class PluginContextMatcher implements PluginMatcher { /** diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/match/PluginMatchedEvent.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/match/PluginMatchedEvent.java index 8789334eb..604b8c94c 100644 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/match/PluginMatchedEvent.java +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/match/PluginMatchedEvent.java @@ -18,20 +18,17 @@ public class PluginMatchedEvent extends PluginContextEvent { /** * 原始对象 */ - private final Object original; + private final Object inboundKey; - /** - * 匹配到的对象 - */ - private final Object matched; + private final Object outbound; public PluginMatchedEvent(PluginContext context, PluginMatcher matcher, - Object original, - Object matched) { + Object inboundKey, + Object outbound) { super(context); this.matcher = matcher; - this.original = original; - this.matched = matched; + this.inboundKey = inboundKey; + this.outbound = outbound; } } diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/match/PluginMatcher.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/match/PluginMatcher.java index f69bd1910..0c6c18962 100644 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/match/PluginMatcher.java +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/match/PluginMatcher.java @@ -2,12 +2,11 @@ import com.github.linyuzai.plugin.core.context.PluginContext; import com.github.linyuzai.plugin.core.handle.PluginHandler; -import com.github.linyuzai.plugin.core.resolve.PluginResolver; /** * 插件匹配器 */ -public interface PluginMatcher extends PluginHandler.Dependency { +public interface PluginMatcher extends PluginHandler, PluginHandler.Dependency { /** * 匹配插件 diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/match/PluginObjectMatcher.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/match/PluginObjectMatcher.java index 7b778f749..73789ca75 100644 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/match/PluginObjectMatcher.java +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/match/PluginObjectMatcher.java @@ -2,14 +2,14 @@ import com.github.linyuzai.plugin.core.concept.Plugin; import com.github.linyuzai.plugin.core.context.PluginContext; -import lombok.AllArgsConstructor; import lombok.Getter; +import lombok.RequiredArgsConstructor; /** * 插件 {@link Plugin} 匹配器 */ @Getter -@AllArgsConstructor +@RequiredArgsConstructor public class PluginObjectMatcher implements PluginMatcher { /** diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/match/PluginProperties.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/match/PluginProperties.java index eb6544719..196cef3c7 100644 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/match/PluginProperties.java +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/match/PluginProperties.java @@ -8,6 +8,7 @@ /** * 用于指定匹配 {@link java.util.Properties} 或是具体的属性 */ +@Deprecated @Target(ElementType.PARAMETER) @Retention(RetentionPolicy.RUNTIME) public @interface PluginProperties { diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/match/PluginContent.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/match/PluginText.java similarity index 92% rename from concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/match/PluginContent.java rename to concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/match/PluginText.java index df716d5f0..6d9dd1997 100644 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/match/PluginContent.java +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/match/PluginText.java @@ -10,7 +10,7 @@ */ @Target(ElementType.PARAMETER) @Retention(RetentionPolicy.RUNTIME) -public @interface PluginContent { +public @interface PluginText { /** * 编码 diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/match/PropertiesMatcher.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/match/PropertiesMatcher.java index e1b997fab..7a4b8ace6 100644 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/match/PropertiesMatcher.java +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/match/PropertiesMatcher.java @@ -1,22 +1,21 @@ package com.github.linyuzai.plugin.core.match; -import com.github.linyuzai.plugin.core.concept.Plugin; +import com.github.linyuzai.plugin.core.context.PluginContext; import com.github.linyuzai.plugin.core.filter.PropertiesFilter; import com.github.linyuzai.plugin.core.handle.HandlerDependency; import com.github.linyuzai.plugin.core.resolve.PropertiesResolver; import lombok.Getter; import java.lang.annotation.Annotation; -import java.util.LinkedHashMap; -import java.util.Map; import java.util.Properties; +import java.util.function.Supplier; /** * {@link Properties} 匹配器 */ @Getter @HandlerDependency(PropertiesResolver.class) -public class PropertiesMatcher extends AbstractPluginMatcher> { +public class PropertiesMatcher extends AbstractPluginMatcher> { /** * {@link Properties} 过滤器 @@ -37,37 +36,12 @@ public PropertiesMatcher(Annotation[] annotations) { @Override public Object getKey() { - return Plugin.PROPERTIES; - } - - /** - * 遍历所有的 {@link Properties},先根据路径和名称过滤; - * 如果 {@link PropertiesFilter} 不为 null 则再使用 {@link PropertiesFilter} 过滤。 - * - * @param propertiesMap {@link Properties} 插件 {@link Map} - * @return 过滤之后的 {@link Properties} - */ - @Override - public Map filter(Map propertiesMap) { - Map map = new LinkedHashMap<>(); - for (Map.Entry entry : propertiesMap.entrySet()) { - Object key = entry.getKey(); - if (key instanceof String) { - if (filterWithAnnotation((String) key)) { - map.put(entry.getKey(), entry.getValue()); - } - } else { - map.put(entry.getKey(), entry.getValue()); - } - } - if (propertiesFilter != null) { - //return propertiesFilter.doFilter(map); - } - return map; + return Properties.class; } @Override - public boolean isEmpty(Map filtered) { - return filtered.isEmpty(); + public boolean doFilter(Supplier source, PluginContext context) { + //TODO 需要过滤? + return true; } } diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/read/DependencyReader.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/read/DependencyReader.java index a36a4f85f..28f08bc9b 100644 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/read/DependencyReader.java +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/read/DependencyReader.java @@ -2,7 +2,6 @@ import com.github.linyuzai.plugin.core.concept.Plugin; import com.github.linyuzai.plugin.core.context.PluginContext; -import com.github.linyuzai.plugin.core.read.metadata.PluginMetadata; import java.io.IOException; import java.util.*; @@ -24,7 +23,7 @@ public Object read(Object key, PluginContext context) { return doRead; } for (Plugin plugin : context.getConcept().getPlugins().values()) { - PluginMetadata metadata = plugin.getMetadata(); + Plugin.Metadata metadata = plugin.getMetadata(); String name = metadata.get("concept.plugin.name"); if (name == null || name.isEmpty()) { continue; @@ -44,7 +43,7 @@ public Object read(Object key, PluginContext context) { public abstract Class getReadableType(); public List getDependencies(Plugin plugin) throws IOException { - PluginMetadata metadata = plugin.getMetadata(); + Plugin.Metadata metadata = plugin.getMetadata(); String classes = metadata.get("concept.plugin.dependency.class"); if (classes == null) { return Collections.emptyList(); diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/read/PluginReadable.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/read/PluginReadable.java deleted file mode 100644 index ec89f5476..000000000 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/read/PluginReadable.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.github.linyuzai.plugin.core.read; - -public interface PluginReadable { -} diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/read/content/ContentReader.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/read/content/ContentReader.java deleted file mode 100644 index 6d47953bf..000000000 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/read/content/ContentReader.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.github.linyuzai.plugin.core.read.content; - -import com.github.linyuzai.plugin.core.context.PluginContext; -import com.github.linyuzai.plugin.core.read.PluginReader; - -public interface ContentReader extends PluginReader { - - @Override - PluginContent read(Object key, PluginContext context); - - @Override - default boolean support(Class readable) { - return readable == PluginContent.class; - } -} diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/read/content/PluginContent.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/read/content/PluginContent.java deleted file mode 100644 index a53f625fb..000000000 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/read/content/PluginContent.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.github.linyuzai.plugin.core.read.content; - -import com.github.linyuzai.plugin.core.read.PluginReadable; - -import java.io.IOException; -import java.io.InputStream; - -public interface PluginContent extends PluginReadable { - - InputStream getInputStream() throws IOException; -} diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/read/metadata/MetadataReader.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/read/metadata/MetadataReader.java deleted file mode 100644 index 4b0a964c9..000000000 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/read/metadata/MetadataReader.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.github.linyuzai.plugin.core.read.metadata; - -import com.github.linyuzai.plugin.core.context.PluginContext; -import com.github.linyuzai.plugin.core.read.PluginReader; - -public interface MetadataReader extends PluginReader { - - @Override - PluginMetadata read(Object key, PluginContext context); - - @Override - default boolean support(Class readable) { - return readable == PluginMetadata.class; - } -} diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/read/metadata/PluginMetadata.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/read/metadata/PluginMetadata.java deleted file mode 100644 index be53fed1d..000000000 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/read/metadata/PluginMetadata.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.github.linyuzai.plugin.core.read.metadata; - -import com.github.linyuzai.plugin.core.read.PluginReadable; - -public interface PluginMetadata extends PluginReadable { - - String get(String key); -} diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/read/metadata/PropertiesMetadataReader.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/read/metadata/PropertiesMetadataReader.java deleted file mode 100644 index debf3eebd..000000000 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/read/metadata/PropertiesMetadataReader.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.github.linyuzai.plugin.core.read.metadata; - -import com.github.linyuzai.plugin.core.concept.Plugin; -import com.github.linyuzai.plugin.core.context.PluginContext; -import com.github.linyuzai.plugin.core.read.content.PluginContent; -import lombok.Getter; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Properties; - -@Getter -public class PropertiesMetadataReader implements MetadataReader { - - private final Properties properties = new Properties(); - - public PropertiesMetadataReader(Plugin plugin) throws IOException { - this(plugin, "plugin.properties"); - } - - public PropertiesMetadataReader(Plugin plugin, String filename) throws IOException { - PluginContent metadata = plugin.read(PluginContent.class, filename); - try (InputStream is = metadata.getInputStream()) { - if (is != null) { - properties.load(is); - } - } - } - - @Override - public PluginMetadata read(Object key, PluginContext context) { - return new PropertiesMetadata(); - } - - public class PropertiesMetadata implements PluginMetadata { - - @Override - public String get(String key) { - return properties.getProperty(key); - } - } -} diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/resolve/AbstractPluginResolver.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/resolve/AbstractPluginResolver.java index 5a432c936..e61171c95 100644 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/resolve/AbstractPluginResolver.java +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/resolve/AbstractPluginResolver.java @@ -30,25 +30,6 @@ public void resolve(PluginContext context) { it -> doFilter((T) it.getValue(), context))) .outboundKey(outboundKey); context.publish(new PluginResolvedEvent(context, this, inboundKey, outboundKey)); - /*T depended = context.get(dependedKey); - if (depended == null) { - throw new PluginException("No plugin can be resolved with key: " + dependedKey); - } - R resolved = doResolve(depended, context); - context.set(resolvedKey, resolved); - context.publish(new PluginResolvedEvent(context, this, dependedKey, depended, resolvedKey, resolved)); - */ - } - - /** - * 判断上下文 {@link PluginContext} 是否存在特定 key - * - * @param context 上下文 {@link PluginContext} - * @return 如果上下文中存在 key 则返回 true 否则返回 false - */ - @Override - public boolean support(PluginContext context) { - return context.contains(PluginTree.class); } public boolean doFilter(T source, PluginContext context) { diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/resolve/ContentResolver.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/resolve/ContentResolver.java index 4d3f739c3..2f4d3a16b 100644 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/resolve/ContentResolver.java +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/resolve/ContentResolver.java @@ -1,9 +1,8 @@ package com.github.linyuzai.plugin.core.resolve; -import com.github.linyuzai.plugin.core.concept.PluginEntry; +import com.github.linyuzai.plugin.core.concept.Plugin; import com.github.linyuzai.plugin.core.context.PluginContext; import com.github.linyuzai.plugin.core.handle.HandlerDependency; -import com.github.linyuzai.plugin.core.read.content.PluginContent; import lombok.Getter; import lombok.RequiredArgsConstructor; import lombok.SneakyThrows; @@ -19,21 +18,21 @@ @Getter @RequiredArgsConstructor @HandlerDependency(EntryResolver.class) -public class ContentResolver extends AbstractPluginResolver { +public class ContentResolver extends AbstractPluginResolver { @Override - public PluginContent doResolve(PluginEntry source, PluginContext context) { + public Plugin.Content doResolve(Plugin.Entry source, PluginContext context) { return source.getContent(); } @Override public Object getInboundKey() { - return PluginEntry.class; + return Plugin.Entry.class; } @Override public Object getOutboundKey() { - return PluginContent.class; + return Plugin.Content.class; } /** diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/resolve/DependOnResolvers.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/resolve/DependOnResolvers.java deleted file mode 100644 index d9c970b18..000000000 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/resolve/DependOnResolvers.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.github.linyuzai.plugin.core.resolve; - -import com.github.linyuzai.plugin.core.match.PluginMatcher; - -import java.lang.annotation.*; - -/** - * 标记在插件解析器 {@link PluginResolver} 和插件匹配器 {@link PluginMatcher} 上, - * 指定需要依赖的插件解析器 {@link PluginResolver}。 - */ -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -@Documented -@Deprecated -public @interface DependOnResolvers { - - /** - * 需要依赖的插件解析器 {@link PluginResolver} - * - * @return 需要依赖的插件解析器 {@link PluginResolver} - */ - Class[] value() default {}; -} diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/resolve/EntryResolver.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/resolve/EntryResolver.java index 356b74153..1d4964858 100644 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/resolve/EntryResolver.java +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/resolve/EntryResolver.java @@ -1,13 +1,11 @@ package com.github.linyuzai.plugin.core.resolve; -import com.github.linyuzai.plugin.core.concept.PluginEntry; +import com.github.linyuzai.plugin.core.concept.Plugin; import com.github.linyuzai.plugin.core.context.PluginContext; import com.github.linyuzai.plugin.core.tree.PluginTree; -import lombok.SneakyThrows; public class EntryResolver implements PluginResolver { - @SneakyThrows @Override public void resolve(PluginContext context) { PluginTree tree = context.get(PluginTree.class); @@ -15,12 +13,7 @@ public void resolve(PluginContext context) { .create(this) .inbound(tree.getRoot()) .transform(node -> node) - .outboundKey(PluginEntry.class); + .outboundKey(Plugin.Entry.class); } - - @Override - public boolean support(PluginContext context) { - return true; - } } diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/resolve/PathNameResolver.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/resolve/PathNameResolver.java deleted file mode 100644 index d0d3d3fd3..000000000 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/resolve/PathNameResolver.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.github.linyuzai.plugin.core.resolve; - -/** - * 路径和名称的插件解析器 - */ -public interface PathNameResolver extends PluginResolver { -} diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/resolve/PluginResolver.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/resolve/PluginResolver.java index 6ee791166..ee33ce346 100644 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/resolve/PluginResolver.java +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/resolve/PluginResolver.java @@ -6,12 +6,7 @@ /** * 插件解析器 */ -public interface PluginResolver extends PluginHandler, PluginHandler.Dependency { - - @Override - default void handle(PluginContext context) { - resolve(context); - } +public interface PluginResolver extends PluginHandler, PluginHandler.Dependency { /** * 解析 diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/resolve/PluginResolverChain.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/resolve/PluginResolverChain.java deleted file mode 100644 index 4a0bb6aae..000000000 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/resolve/PluginResolverChain.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.github.linyuzai.plugin.core.resolve; - -import com.github.linyuzai.plugin.core.context.PluginContext; - -/** - * 插件解析链 - */ -public interface PluginResolverChain { - - /** - * 进一步解析 - * - * @param context 上下文 {@link PluginContext} - */ - void next(PluginContext context); -} diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/resolve/PluginResolverChainImpl.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/resolve/PluginResolverChainImpl.java deleted file mode 100644 index d346a4de8..000000000 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/resolve/PluginResolverChainImpl.java +++ /dev/null @@ -1,71 +0,0 @@ -package com.github.linyuzai.plugin.core.resolve; - -import com.github.linyuzai.plugin.core.context.PluginContext; -import com.github.linyuzai.plugin.core.filter.PluginFilter; -import lombok.AllArgsConstructor; -import lombok.Getter; - -import java.util.Collection; -import java.util.Iterator; - -/** - * 插件解析链 {@link PluginResolverChain} 的实现 - */ -@Getter -@AllArgsConstructor -public class PluginResolverChainImpl implements PluginResolverChain { - - /** - * 解析器 - */ - private final Collection resolvers; - - /** - * 过滤器 - */ - private final Collection filters; - - /** - * 执行解析。 - * 对于当前的上下文 {@link PluginContext}, - * 遍历所有的解析器 {@link PluginResolver}, - * 如果支持解析则直接进行解析,同时获得对应的过滤器 {@link PluginFilter} 进行过滤, - * 然后将未使用的解析器和剩余的过滤器传入下一个解析链节点。 - *

- * 获得所有支持解析的解析器 {@link PluginResolver}, - * - * @param context 上下文 {@link PluginContext} - */ - @Override - public void next(PluginContext context) { - int size = resolvers.size(); - Iterator resolverIterator = resolvers.iterator(); - while (resolverIterator.hasNext()) { - PluginResolver resolver = resolverIterator.next(); - if (resolver.support(context)) { - resolverIterator.remove(); - resolver.resolve(context); - //执行对应解析器的过滤器 - Iterator filterIterator = filters.iterator(); - while (filterIterator.hasNext()) { - PluginFilter filter = filterIterator.next(); - if (filter.support(context)) { - Collection> dependencies = filter.getDependencies(); - for (Class dependency : dependencies) { - if (dependency.isInstance(resolver)) { - filterIterator.remove(); - filter.filter(context); - } - } - } - } - } - } - //如果所有解析器都解析完成,直接返回 - //如果没有支持解析的解析器,直接返回,防止无限循环 - if (resolvers.isEmpty() || resolvers.size() == size) { - return; - } - next(context); - } -} diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/resolve/PluginResolverDependency.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/resolve/PluginResolverDependency.java deleted file mode 100644 index 7d0098c02..000000000 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/resolve/PluginResolverDependency.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.github.linyuzai.plugin.core.resolve; - -/** - * 插件解析器 {@link PluginResolver} 的依赖支持。 - * 插件进行解析时是一步一步进行的, - * 解析器解析时可能需要依赖其他解析器的解析结果, - * 将这种关系定义为解析器的依赖关系,类似于我们的包依赖 - * 这样就可以通过一定方式自动设置额外的解析器, - * 不需要手动添加大量的解析器。 - */ -@Deprecated -public interface PluginResolverDependency { - - /** - * 获得依赖的所有解析器类。 - * 默认情况下,会尝试通过类上标记的注解 {@link DependOnResolvers} 来获得。 - * - * @return 依赖的所有解析器类 - */ - @SuppressWarnings("unchecked") - default Class[] dependencies() { - Class clazz = getClass(); - //当前类有就用当前类的配置,否则查找其父类上的配置 - while (clazz != null) { - DependOnResolvers annotation = clazz.getAnnotation(DependOnResolvers.class); - if (annotation != null) { - return annotation.value(); - } - clazz = clazz.getSuperclass(); - } - return new Class[0]; - } -} diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/resolve/PropertiesNameResolver.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/resolve/PropertiesNameResolver.java deleted file mode 100644 index 7c201c2c3..000000000 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/resolve/PropertiesNameResolver.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.github.linyuzai.plugin.core.resolve; - -import com.github.linyuzai.plugin.core.concept.Plugin; -import com.github.linyuzai.plugin.core.context.PluginContext; -import com.github.linyuzai.plugin.core.handle.HandlerDependency; - -import java.util.List; -import java.util.stream.Collectors; - -/** - * {@link java.util.Properties} 名称解析器 - */ -@HandlerDependency(PathNameResolver.class) -public class PropertiesNameResolver extends AbstractPluginResolver, List> { - - /** - * 过滤文件名称中 .properties 为后缀的名称 - * - * @param filenames 文件名称 - * @param context 上下文 {@link PluginContext} - * @return {@link java.util.Properties} 名称 - */ - @Override - public List doResolve(List filenames, PluginContext context) { - return filenames.stream() - .filter(it -> it.endsWith(".properties")) - .collect(Collectors.toList()); - } - - @Override - public Object getInboundKey() { - return Plugin.PATH_NAME; - } - - @Override - public Object getOutboundKey() { - return Plugin.PROPERTIES_NAME; - } -} diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/resolve/PropertiesResolver.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/resolve/PropertiesResolver.java index 9eefecb7e..7e88ab9e3 100644 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/resolve/PropertiesResolver.java +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/resolve/PropertiesResolver.java @@ -3,50 +3,73 @@ import com.github.linyuzai.plugin.core.concept.Plugin; import com.github.linyuzai.plugin.core.context.PluginContext; import com.github.linyuzai.plugin.core.handle.HandlerDependency; +import lombok.RequiredArgsConstructor; +import lombok.SneakyThrows; -import java.util.LinkedHashMap; -import java.util.List; +import java.io.InputStream; import java.util.Map; import java.util.Properties; +import java.util.function.Supplier; /** * {@link Properties} 解析器 */ -@HandlerDependency(PropertiesNameResolver.class) -public abstract class PropertiesResolver extends AbstractPluginResolver, Map> { +@HandlerDependency(EntryResolver.class) +public class PropertiesResolver extends AbstractPluginResolver> { + + @Override + public boolean doFilter(Plugin.Entry entry, PluginContext context) { + return entry.getName().endsWith(".properties"); + } /** * 将所有名称对象的文件都加载到 {@link Properties} 对象中 * - * @param propertiesNames 名称 - * @param context 上下文 {@link PluginContext} + * @param entry 插件项 + * @param context 上下文 {@link PluginContext} * @return {@link Properties} 的 {@link Map} */ @Override - public Map doResolve(List propertiesNames, PluginContext context) { - Map propertiesMap = new LinkedHashMap<>(); - for (String propertiesName : propertiesNames) { - propertiesMap.put(propertiesName, load(context, propertiesName)); - } - return propertiesMap; + public Supplier doResolve(Plugin.Entry entry, PluginContext context) { + return new PropertiesContent(entry.getContent()); } @Override public Object getInboundKey() { - return Plugin.PROPERTIES_NAME; + return Plugin.Entry.class; } @Override public Object getOutboundKey() { - return Plugin.PROPERTIES; + return Properties.class; } - /** - * 根据名称加载一个 {@link Properties} 对象 - * - * @param context 上下文 {@link PluginContext} - * @param propertiesName 名称 - * @return {@link Properties} 对象 - */ - public abstract Properties load(PluginContext context, String propertiesName); + @RequiredArgsConstructor + public static class PropertiesContent implements Supplier { + + private final Plugin.Content content; + + private volatile Properties properties; + + @Override + public Properties get() { + if (properties == null) { + synchronized (this) { + if (properties == null) { + properties = load(); + } + } + } + return properties; + } + + @SneakyThrows + protected Properties load() { + try (InputStream is = content.getInputStream()) { + Properties properties = new Properties(); + properties.load(is); + return properties; + } + } + } } diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/tree/DefaultPluginTree.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/tree/DefaultPluginTree.java index 6b61d107a..0392af6a2 100644 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/tree/DefaultPluginTree.java +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/tree/DefaultPluginTree.java @@ -2,13 +2,11 @@ import com.github.linyuzai.plugin.core.concept.Plugin; import com.github.linyuzai.plugin.core.handle.PluginHandler; -import com.github.linyuzai.plugin.core.read.PluginReader; import com.github.linyuzai.plugin.core.tree.trace.PluginTracer; import com.github.linyuzai.plugin.core.tree.transform.PluginTransformer; import lombok.Getter; import lombok.RequiredArgsConstructor; -import java.io.IOException; import java.util.*; import java.util.function.Consumer; import java.util.function.Function; @@ -24,7 +22,7 @@ public class DefaultPluginTree implements PluginTree, PluginTransformer, PluginT private final Map traceMap = new LinkedHashMap<>(); public DefaultPluginTree(Plugin plugin) { - root = createNode(plugin.getId(), plugin, plugin, null); + root = createNode(plugin.getId(), "", plugin, null); } @Override @@ -57,20 +55,20 @@ public HandleStage getTrace(Object id) { return traceMap.get(id); } - protected DefaultNode createNode(Object id, Object value, Plugin plugin, Node parent) { - return new DefaultNode(id, value, plugin, this, parent); + protected DefaultNode createNode(Object id, String name, Object value, Node parent) { + return new DefaultNode(id, name, value, this, parent); } @SuppressWarnings("unchecked") @Getter @RequiredArgsConstructor - public class DefaultNode implements Node { + public class DefaultNode implements Node, NodeFactory { private final Object id; - private final Object value; + private final String name; - private final Plugin plugin; + private final Object value; private final PluginTree tree; @@ -98,7 +96,7 @@ protected Node doMap(Node parent, Function function, Predicate collect = children.stream() .map(it -> doMap(node, function, predicate)) .filter(Objects::nonNull) @@ -116,7 +114,7 @@ public Node doFilter(Node parent, Predicate predicate) { if (isContentNode() && !predicate.test(this)) { return null; } - DefaultNode node = createNode(id, value, plugin, parent); + DefaultNode node = createNode(id, name, value, parent); List collect = children.stream() .map(it -> doFilter(parent, predicate)) .filter(Objects::nonNull) @@ -132,8 +130,8 @@ public void forEach(Consumer consumer) { } @Override - public DefaultNode create(Object id, Object value, Plugin plugin) { - DefaultNode node = createNode(id, value, plugin, this); + public DefaultNode create(Object id, String name, Object value) { + DefaultNode node = createNode(id, name, value, this); children.add(node); return node; } diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/tree/PluginTree.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/tree/PluginTree.java index e4ba30e0e..dcae0af3c 100644 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/tree/PluginTree.java +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/tree/PluginTree.java @@ -23,9 +23,9 @@ interface Node { Object getId(); - Object getValue(); + String getName(); - Plugin getPlugin(); + Object getValue(); PluginTree getTree(); @@ -40,7 +40,10 @@ interface Node { Node filter(Predicate predicate); void forEach(Consumer consumer); + } + + interface NodeFactory { - Node create(Object id, Object value, Plugin plugin); + Node create(Object id, String name, Object value); } } diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/util/PluginUtils.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/util/PluginUtils.java new file mode 100644 index 000000000..9d7bf28d8 --- /dev/null +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/core/util/PluginUtils.java @@ -0,0 +1,100 @@ +package com.github.linyuzai.plugin.core.util; + +import com.github.linyuzai.plugin.jar.extension.NestedJarHandler; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLStreamHandler; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class PluginUtils { + + public static final int MAX_BUFFER_SIZE = Integer.MAX_VALUE - 8; + + public static final int DEFAULT_BUFFER_SIZE = 8192; + + public static byte[] read(InputStream is) throws IOException { + return read(is, Integer.MAX_VALUE); + } + + public static byte[] read(InputStream is, int len) throws IOException { + if (len < 0) { + throw new IllegalArgumentException("len < 0"); + } + + List bufs = null; + byte[] result = null; + int total = 0; + int remaining = len; + int n; + do { + byte[] buf = new byte[Math.min(remaining, DEFAULT_BUFFER_SIZE)]; + int nread = 0; + + // read to EOF which may read more or less than buffer size + while ((n = is.read(buf, nread, + Math.min(buf.length - nread, remaining))) > 0) { + nread += n; + remaining -= n; + } + + if (nread > 0) { + if (MAX_BUFFER_SIZE - total < nread) { + throw new OutOfMemoryError("Required array size too large"); + } + if (nread < buf.length) { + buf = Arrays.copyOfRange(buf, 0, nread); + } + total += nread; + if (result == null) { + result = buf; + } else { + if (bufs == null) { + bufs = new ArrayList<>(); + bufs.add(result); + } + bufs.add(buf); + } + } + // if the last call to read returned -1 or the number of bytes + // requested have been read then break + } while (n >= 0 && remaining > 0); + + if (bufs == null) { + if (result == null) { + return new byte[0]; + } + return result.length == total ? + result : Arrays.copyOf(result, total); + } + + result = new byte[total]; + int offset = 0; + remaining = total; + for (byte[] b : bufs) { + int count = Math.min(b.length, remaining); + System.arraycopy(b, 0, result, offset, count); + offset += count; + remaining -= count; + } + + return result; + } + + public static URL getURL(File file) throws MalformedURLException { + String path = file.getAbsolutePath() + "!/"; + path = path.replace("file:////", "file://"); // Fix UNC paths + return new URL("jar", "", -1, path); + } + + public static URL getURL(URL url, String name, URLStreamHandler handler) throws MalformedURLException { + String file = url.toString() + name + "!/"; + file = file.replace("file:////", "file://"); // Fix UNC paths + return new URL("jar", "", -1, file, handler); + } +} diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/concept/JarPlugin.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/concept/JarPlugin.java index 6d3b854a0..ae5cb8556 100644 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/concept/JarPlugin.java +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/concept/JarPlugin.java @@ -1,15 +1,12 @@ package com.github.linyuzai.plugin.jar.concept; import com.github.linyuzai.plugin.core.concept.AbstractPlugin; -import com.github.linyuzai.plugin.core.concept.Plugin; -import com.github.linyuzai.plugin.core.concept.PluginEntry; import com.github.linyuzai.plugin.core.context.PluginContext; -import com.github.linyuzai.plugin.core.read.metadata.PropertiesMetadataReader; import com.github.linyuzai.plugin.core.tree.PluginTree; import com.github.linyuzai.plugin.jar.extension.NestedJarEntry; import com.github.linyuzai.plugin.jar.extension.NestedJarFile; import com.github.linyuzai.plugin.jar.read.JarClassReader; -import com.github.linyuzai.plugin.jar.read.JarContentReader; +import com.github.linyuzai.plugin.zip.concept.ZipPlugin; import lombok.Getter; import lombok.SneakyThrows; @@ -28,15 +25,13 @@ @Getter public class JarPlugin extends AbstractPlugin { - public static final String JAR_PREFIX = Plugin.PREFIX + "JAR@"; + public static final String PREFIX = "CONCEPT_PLUGIN@JAR@"; - public static final String ENTRY = JAR_PREFIX + "ENTRY"; + public static final String CLASSNAME = PREFIX + "CLASSNAME"; - public static final String CLASS_NAME = JAR_PREFIX + "CLASS_NAME"; + public static final String CLASS = PREFIX + "CLASS"; - public static final String CLASS = JAR_PREFIX + "CLASS"; - - public static final String INSTANCE = JAR_PREFIX + "INSTANCE"; + public static final String INSTANCE = PREFIX + "INSTANCE"; private final URL url; @@ -54,7 +49,7 @@ public Object getId() { } @Override - public Collection collectEntries(PluginContext context) { + public Collection collectEntries(PluginContext context) { return jarFile.stream() .map(NestedJarEntry.class::cast) .map(it -> new JarPluginEntry(this, jarFile, it)) @@ -66,24 +61,9 @@ public Collection collectEntries(PluginContext context) { */ @Override public void onPrepare(PluginContext context) { - prepareContentReader(context); - prepareMetadataReader(context); prepareClassReader(context); } - protected void prepareContentReader(PluginContext context) { - addReader(new JarContentReader(jarFile)); - } - - @SneakyThrows - protected void prepareMetadataReader(PluginContext context) { - //只处理主插件 - PluginTree.Node node = context.get(PluginTree.Node.class); - if (node == null || node.getParent() == null) { - addReader(new PropertiesMetadataReader(this)); - } - } - @SneakyThrows protected void prepareClassReader(PluginContext context) { PluginTree.Node node = context.get(PluginTree.Node.class); @@ -136,4 +116,9 @@ public URL parseURL(String jarPath) { public String toString() { return "JarPlugin(" + url + ")"; } + + public static class Mode extends ZipPlugin.Mode { + + public static final String NESTED = "NESTED"; + } } diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/concept/JarPluginEntry.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/concept/JarPluginEntry.java index 6ce5f175d..9fbde60ce 100644 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/concept/JarPluginEntry.java +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/concept/JarPluginEntry.java @@ -1,19 +1,18 @@ package com.github.linyuzai.plugin.jar.concept; import com.github.linyuzai.plugin.core.concept.Plugin; -import com.github.linyuzai.plugin.core.concept.PluginEntry; -import com.github.linyuzai.plugin.core.read.content.PluginContent; import com.github.linyuzai.plugin.jar.extension.NestedJarEntry; import com.github.linyuzai.plugin.jar.extension.NestedJarFile; import lombok.Getter; import lombok.RequiredArgsConstructor; +import lombok.SneakyThrows; import java.io.IOException; import java.io.InputStream; @Getter @RequiredArgsConstructor -public class JarPluginEntry implements PluginEntry { +public class JarPluginEntry implements Plugin.Entry { private final Plugin plugin; @@ -21,17 +20,23 @@ public class JarPluginEntry implements PluginEntry { private final NestedJarEntry jarEntry; + @SneakyThrows + @Override + public Object getId() { + return jarEntry.getURL(); + } + @Override public String getName() { return jarEntry.getName(); } @Override - public PluginContent getContent() { + public Plugin.Content getContent() { return new EntryContent(); } - public class EntryContent implements PluginContent { + public class EntryContent implements Plugin.Content { @Override public InputStream getInputStream() throws IOException { diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/extension/NestedJarEntry.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/extension/NestedJarEntry.java index f496a7708..e14b5694d 100644 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/extension/NestedJarEntry.java +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/extension/NestedJarEntry.java @@ -84,7 +84,7 @@ public boolean hasName(CharSequence name, char suffix) { * @throws MalformedURLException if the URL is not valid */ public URL getURL() throws MalformedURLException { - return new URL(this.jarFile.getURL(), getName()); + return new URL(this.jarFile.getURL(), getName(), new NestedJarHandler(jarFile)); } @Override diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/factory/JarEntryPluginFactory.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/factory/JarEntryPluginFactory.java deleted file mode 100644 index c7025ef8f..000000000 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/factory/JarEntryPluginFactory.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.github.linyuzai.plugin.jar.factory; - -import com.github.linyuzai.plugin.core.concept.Plugin; -import com.github.linyuzai.plugin.core.concept.PluginConcept; -import com.github.linyuzai.plugin.core.concept.PluginEntry; -import com.github.linyuzai.plugin.core.factory.SubPluginFactory; -import com.github.linyuzai.plugin.jar.concept.JarPlugin; -import com.github.linyuzai.plugin.jar.concept.JarPluginEntry; -import com.github.linyuzai.plugin.jar.extension.NestedJarFile; -import lombok.SneakyThrows; - -/** - * 支持文件路径的 {@link JarPlugin} 工厂 - */ -public class JarEntryPluginFactory extends SubPluginFactory { - - @Override - public boolean doSupport(PluginEntry entry, PluginConcept concept) { - return entry instanceof JarPluginEntry && entry.getName().endsWith(".jar"); - } - - @SneakyThrows - @Override - public Plugin doCreate(PluginEntry entry, PluginConcept concept) { - NestedJarFile jarFile = ((JarPluginEntry) entry).getJarEntry().asJarFile(); - return new JarPlugin(jarFile); - } -} diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/factory/JarFilePluginFactory.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/factory/JarFilePluginFactory.java deleted file mode 100644 index 0292c02c4..000000000 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/factory/JarFilePluginFactory.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.github.linyuzai.plugin.jar.factory; - -import com.github.linyuzai.plugin.core.concept.Plugin; -import com.github.linyuzai.plugin.core.concept.PluginConcept; -import com.github.linyuzai.plugin.core.factory.PluginFactory; -import com.github.linyuzai.plugin.jar.concept.JarPlugin; -import com.github.linyuzai.plugin.jar.extension.NestedJarFile; -import lombok.SneakyThrows; - -import java.io.File; - -/** - * 支持 {@link File} 类型的 {@link JarPlugin} 工厂 - */ -public class JarFilePluginFactory implements PluginFactory { - - @Override - public boolean support(Object o, PluginConcept concept) { - return o instanceof File; - } - - @SneakyThrows - @Override - public Plugin create(Object o, PluginConcept concept) { - return new JarPlugin(new NestedJarFile((File) o)); - } -} diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/factory/JarPathPluginFactory.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/factory/JarPathPluginFactory.java deleted file mode 100644 index cfdba26e0..000000000 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/factory/JarPathPluginFactory.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.github.linyuzai.plugin.jar.factory; - -import com.github.linyuzai.plugin.core.concept.Plugin; -import com.github.linyuzai.plugin.core.concept.PluginConcept; -import com.github.linyuzai.plugin.jar.concept.JarPlugin; - -import java.io.File; - -/** - * 支持文件路径的 {@link JarPlugin} 工厂 - */ -public class JarPathPluginFactory extends JarFilePluginFactory { - - @Override - public boolean support(Object o, PluginConcept concept) { - return o instanceof String && ((String) o).endsWith(".jar"); - } - - @Override - public Plugin create(Object o, PluginConcept concept) { - return super.create(new File((String) o), concept); - } -} diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/factory/JarPluginFactory.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/factory/JarPluginFactory.java new file mode 100644 index 000000000..889d6dd4c --- /dev/null +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/factory/JarPluginFactory.java @@ -0,0 +1,44 @@ +package com.github.linyuzai.plugin.jar.factory; + +import com.github.linyuzai.plugin.core.concept.Plugin; +import com.github.linyuzai.plugin.core.context.PluginContext; +import com.github.linyuzai.plugin.jar.concept.JarPlugin; +import com.github.linyuzai.plugin.jar.extension.NestedJarFile; +import com.github.linyuzai.plugin.zip.factory.ZipPluginFactory; +import lombok.SneakyThrows; + +import java.io.File; +import java.net.MalformedURLException; +import java.net.URL; + +public class JarPluginFactory extends ZipPluginFactory { + + @Override + public String getMode(File file, Plugin.Metadata metadata, PluginContext context) { + String mode = metadata.get("concept.plugin.jar.mode"); + if (mode != null) { + return mode; + } + return super.getMode(file, metadata, context); + } + + @SneakyThrows + @Override + public Plugin createInMode(File file, String mode, PluginContext context) { + if (JarPlugin.Mode.NESTED.equalsIgnoreCase(mode)) { + return new JarPlugin(new NestedJarFile(file)); + } else { + return super.createInMode(file, mode, context); + } + } + + @Override + protected boolean supportFile(File file, PluginContext context) { + return file.getName().endsWith(".jar") || super.supportFile(file, context); + } + + @Override + protected URL getURL(File file) throws MalformedURLException { + return new URL("jar", "", -1, file.getAbsolutePath()); + } +} diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/filter/AnnotationFilter.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/filter/AnnotationFilter.java index d3d36c203..619d429ff 100644 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/filter/AnnotationFilter.java +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/filter/AnnotationFilter.java @@ -10,7 +10,6 @@ import java.lang.annotation.Annotation; import java.util.Arrays; import java.util.Collection; -import java.util.Map; /** * 类上注解过滤器 @@ -18,7 +17,7 @@ @Getter @RequiredArgsConstructor @HandlerDependency(JarClassResolver.class) -public class AnnotationFilter extends AbstractPluginFilter>> { +public class AnnotationFilter extends AbstractPluginFilter> { /** * 注解类 @@ -31,11 +30,8 @@ public AnnotationFilter(Class... annotationClasses) { } @Override - public boolean doFilter(Map> plugins) { - return true; - /*return plugins.entrySet().stream() - .filter(it -> applyNegation(hasAnnotation(it.getValue()))) - .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));*/ + public boolean doFilter(Class clazz) { + return hasAnnotation(clazz); } @Override diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/filter/ClassFilter.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/filter/ClassFilter.java index 7c0144d5c..cd1135b2d 100644 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/filter/ClassFilter.java +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/filter/ClassFilter.java @@ -9,7 +9,6 @@ import java.util.Arrays; import java.util.Collection; -import java.util.Map; /** * 类过滤器 @@ -17,7 +16,7 @@ @Getter @RequiredArgsConstructor @HandlerDependency(JarClassResolver.class) -public class ClassFilter extends AbstractPluginFilter>> { +public class ClassFilter extends AbstractPluginFilter> { /** * 类 @@ -29,11 +28,8 @@ public ClassFilter(Class... classes) { } @Override - public boolean doFilter(Map> plugins) { - return true; - /*return plugins.entrySet().stream() - .filter(it -> applyNegation(matchClass(it.getValue()))) - .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));*/ + public boolean doFilter(Class clazz) { + return matchClass(clazz); } @Override diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/filter/ClassNameFilter.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/filter/ClassNameFilter.java index 446133dbb..ba735e3e4 100644 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/filter/ClassNameFilter.java +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/filter/ClassNameFilter.java @@ -9,7 +9,6 @@ import java.util.Arrays; import java.util.Collection; -import java.util.Map; /** * 类名过滤器 @@ -17,7 +16,7 @@ @Getter @RequiredArgsConstructor @HandlerDependency(JarClassNameResolver.class) -public class ClassNameFilter extends AbstractPluginFilter> { +public class ClassNameFilter extends AbstractPluginFilter { /** * 类名 @@ -29,16 +28,13 @@ public ClassNameFilter(String... classNames) { } @Override - public boolean doFilter(Map plugins) { - return true; - /*return plugins.entrySet().stream() - .filter(it -> applyNegation(matchClassName(it.getValue()))) - .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));*/ + public boolean doFilter(String className) { + return matchClassName(className); } @Override public Object getKey() { - return JarPlugin.CLASS_NAME; + return JarPlugin.CLASSNAME; } /** diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/filter/ModifierFilter.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/filter/ModifierFilter.java index 02495ed50..2200b8397 100644 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/filter/ModifierFilter.java +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/filter/ModifierFilter.java @@ -9,7 +9,6 @@ import java.util.Arrays; import java.util.Collection; -import java.util.Map; import java.util.function.Function; /** @@ -18,7 +17,7 @@ @Getter @RequiredArgsConstructor @HandlerDependency(JarClassResolver.class) -public class ModifierFilter extends AbstractPluginFilter>> { +public class ModifierFilter extends AbstractPluginFilter> { /** * {@link java.lang.reflect.Modifier} 对应的 {@link Function} @@ -31,11 +30,8 @@ public ModifierFilter(Function... functions) { } @Override - public boolean doFilter(Map> plugins) { - return true; - /*return plugins.entrySet().stream() - .filter(it -> applyNegation(filterClass(it.getValue()))) - .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));*/ + public boolean doFilter(Class clazz) { + return filterClass(clazz); } @Override diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/filter/PackageFilter.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/filter/PackageFilter.java index d68c54655..27e121c37 100644 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/filter/PackageFilter.java +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/filter/PackageFilter.java @@ -9,14 +9,13 @@ import java.util.Arrays; import java.util.Collection; -import java.util.Map; /** * 包名过滤器 */ @Getter @HandlerDependency(JarClassNameResolver.class) -public class PackageFilter extends AbstractPluginFilter> { +public class PackageFilter extends AbstractPluginFilter { /** * 包名 @@ -34,17 +33,13 @@ public PackageFilter(Collection packages) { } @Override - public boolean doFilter(Map plugins) { - return true; - /*return plugins.entrySet() - .stream() - .filter(it -> applyNegation(matchPackage(it.getValue()))) - .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));*/ + public boolean doFilter(String packageName) { + return matchPackage(packageName); } @Override public Object getKey() { - return JarPlugin.CLASS_NAME; + return JarPlugin.CLASSNAME; } /** diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/match/ClassMatcher.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/match/ClassMatcher.java index c05fc4e25..63e69a885 100644 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/match/ClassMatcher.java +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/match/ClassMatcher.java @@ -1,18 +1,17 @@ package com.github.linyuzai.plugin.jar.match; +import com.github.linyuzai.plugin.core.context.PluginContext; import com.github.linyuzai.plugin.core.handle.HandlerDependency; import com.github.linyuzai.plugin.jar.concept.JarPlugin; import com.github.linyuzai.plugin.jar.resolve.JarClassResolver; import java.lang.annotation.Annotation; -import java.util.LinkedHashMap; -import java.util.Map; /** * 类匹配器 */ @HandlerDependency(JarClassResolver.class) -public class ClassMatcher extends JarPluginMatcher>> { +public class ClassMatcher extends JarPluginMatcher> { public ClassMatcher(Class target, Annotation[] annotations) { super(target, annotations); @@ -26,22 +25,11 @@ public Object getKey() { /** * 是对应的类或其子类并基于注解匹配 * - * @param classes 类 + * @param clazz 类 * @return 匹配之后的类 */ - public Map> filter(Map> classes) { - Map> map = new LinkedHashMap<>(); - for (Map.Entry> entry : classes.entrySet()) { - Class value = entry.getValue(); - if (target.isAssignableFrom(value) && filterWithAnnotation(entry.getKey(), value)) { - map.put(entry.getKey(), value); - } - } - return map; - } - @Override - public boolean isEmpty(Map> filtered) { - return filtered.isEmpty(); + public boolean doFilter(Class clazz, PluginContext context) { + return target.isAssignableFrom(clazz) && applyFilters(clazz); } } diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/match/InstanceMatcher.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/match/InstanceMatcher.java index 772ec19c8..de5efdec7 100644 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/match/InstanceMatcher.java +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/match/InstanceMatcher.java @@ -1,18 +1,17 @@ package com.github.linyuzai.plugin.jar.match; +import com.github.linyuzai.plugin.core.context.PluginContext; import com.github.linyuzai.plugin.core.handle.HandlerDependency; import com.github.linyuzai.plugin.jar.concept.JarPlugin; import com.github.linyuzai.plugin.jar.resolve.JarInstanceResolver; import java.lang.annotation.Annotation; -import java.util.LinkedHashMap; -import java.util.Map; /** * 实例匹配器 */ @HandlerDependency(JarInstanceResolver.class) -public class InstanceMatcher extends JarPluginMatcher> { +public class InstanceMatcher extends JarPluginMatcher { public InstanceMatcher(Class target, Annotation[] annotations) { super(target, annotations); @@ -23,25 +22,8 @@ public Object getKey() { return JarPlugin.INSTANCE; } - /** - * 是对应类的实例并基于注解匹配 - * - * @param instances 实例 - * @return 匹配之后的实例 - */ - public Map filter(Map instances) { - Map map = new LinkedHashMap<>(); - for (Map.Entry entry : instances.entrySet()) { - Object value = entry.getValue(); - if (target.isInstance(value) && filterWithAnnotation(entry.getKey(), value.getClass())) { - map.put(entry.getKey(), value); - } - } - return map; - } - @Override - public boolean isEmpty(Map filtered) { - return filtered.isEmpty(); + public boolean doFilter(Object instance, PluginContext context) { + return target.isInstance(instance) && applyFilters(instance.getClass()); } } diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/match/JarPluginMatcher.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/match/JarPluginMatcher.java index bf8cec71c..f913072c3 100644 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/match/JarPluginMatcher.java +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/match/JarPluginMatcher.java @@ -73,14 +73,10 @@ public JarPluginMatcher(Class target, Annotation[] annotations) { /** * 结合类相关的注解进行过滤 * - * @param pathAndName 路径和名称 - * @param clazz 类 + * @param clazz 类 * @return 是否匹配 */ - public boolean filterWithAnnotation(String pathAndName, Class clazz) { - if (!filterWithAnnotation(pathAndName)) { - return false; - } + public boolean applyFilters(Class clazz) { if (packageFilter != null && !packageFilter.matchPackage(clazz.getName())) { return false; } diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/read/JarContentReader.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/read/JarContentReader.java deleted file mode 100644 index 2d6f71b2b..000000000 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/read/JarContentReader.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.github.linyuzai.plugin.jar.read; - -import com.github.linyuzai.plugin.core.context.PluginContext; -import com.github.linyuzai.plugin.core.read.content.ContentReader; -import com.github.linyuzai.plugin.core.read.content.PluginContent; -import com.github.linyuzai.plugin.jar.extension.NestedJarFile; -import lombok.Getter; -import lombok.RequiredArgsConstructor; - -import java.io.IOException; -import java.io.InputStream; - -@Getter -@RequiredArgsConstructor -public class JarContentReader implements ContentReader { - - private final NestedJarFile jarFile; - - @Override - public PluginContent read(Object key, PluginContext context) { - return new JarContent(String.valueOf(key)); - } - - @Getter - @RequiredArgsConstructor - public class JarContent implements PluginContent { - - private final String name; - - @Override - public InputStream getInputStream() throws IOException { - return jarFile.getInputStream(name); - } - } -} diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/resolve/JarClassNameResolver.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/resolve/JarClassNameResolver.java index a36392047..fec5158ad 100644 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/resolve/JarClassNameResolver.java +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/resolve/JarClassNameResolver.java @@ -1,6 +1,6 @@ package com.github.linyuzai.plugin.jar.resolve; -import com.github.linyuzai.plugin.core.concept.PluginEntry; +import com.github.linyuzai.plugin.core.concept.Plugin; import com.github.linyuzai.plugin.core.context.PluginContext; import com.github.linyuzai.plugin.core.handle.HandlerDependency; import com.github.linyuzai.plugin.core.resolve.AbstractPluginResolver; @@ -11,10 +11,10 @@ * 类名解析器 */ @HandlerDependency(EntryResolver.class) -public class JarClassNameResolver extends AbstractPluginResolver { +public class JarClassNameResolver extends AbstractPluginResolver { @Override - public boolean doFilter(PluginEntry source, PluginContext context) { + public boolean doFilter(Plugin.Entry source, PluginContext context) { return source.getName().endsWith(".class"); } @@ -26,7 +26,7 @@ public boolean doFilter(PluginEntry source, PluginContext context) { * @return 类名 */ @Override - public String doResolve(PluginEntry entry, PluginContext context) { + public String doResolve(Plugin.Entry entry, PluginContext context) { String name = entry.getName(); return name.substring(0, name.lastIndexOf(".")) .replaceAll("/", "."); @@ -34,11 +34,11 @@ public String doResolve(PluginEntry entry, PluginContext context) { @Override public Object getInboundKey() { - return PluginEntry.class; + return Plugin.Entry.class; } @Override public Object getOutboundKey() { - return JarPlugin.CLASS_NAME; + return JarPlugin.CLASSNAME; } } diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/resolve/JarClassResolver.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/resolve/JarClassResolver.java index 3035941a6..2a5a92e07 100644 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/resolve/JarClassResolver.java +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/resolve/JarClassResolver.java @@ -27,7 +27,7 @@ public Class doResolve(String className, PluginContext context) { @Override public Object getInboundKey() { - return JarPlugin.CLASS_NAME; + return JarPlugin.CLASSNAME; } @Override diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/resolve/JarInstanceResolver.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/resolve/JarInstanceResolver.java index 727d84c68..57ddc84bf 100644 --- a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/resolve/JarInstanceResolver.java +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/jar/resolve/JarInstanceResolver.java @@ -12,6 +12,7 @@ /** * 实例解析器 */ +//TODO BeanDefinition @HandlerDependency(JarClassResolver.class) public class JarInstanceResolver extends AbstractPluginResolver, Object> { diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/zip/concept/ZipPlugin.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/zip/concept/ZipPlugin.java new file mode 100644 index 000000000..01f7bfea3 --- /dev/null +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/zip/concept/ZipPlugin.java @@ -0,0 +1,66 @@ +package com.github.linyuzai.plugin.zip.concept; + +import com.github.linyuzai.plugin.core.concept.AbstractPlugin; +import com.github.linyuzai.plugin.core.context.PluginContext; +import com.github.linyuzai.plugin.core.util.PluginUtils; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.SneakyThrows; + +import java.net.URL; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +@Getter +@RequiredArgsConstructor +public class ZipPlugin extends AbstractPlugin { + + private final ZipInputStream inputStream; + + private final URL url; + + private final Entry parent; + + @Override + public Object getId() { + return url; + } + + @SneakyThrows + @Override + public Collection collectEntries(PluginContext context) { + List entries = new ArrayList<>(); + ZipEntry entry; + while ((entry = inputStream.getNextEntry()) != null) { + if (entry.isDirectory()) { + continue; + } + String name = entry.getName(); + byte[] bytes = PluginUtils.read(inputStream); + entries.add(new ZipPluginEntry(this, name, bytes)); + inputStream.closeEntry(); + } + return entries; + } + + @SneakyThrows + @Override + public void onRelease(PluginContext context) { + inputStream.close(); + } + + @Override + public String toString() { + return "ZipPlugin(" + url + ")"; + } + + public static class Mode { + + public static final String MEMORY = "MEMORY"; + + public static final String FILE = "FILE"; + } +} diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/zip/concept/ZipPluginEntry.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/zip/concept/ZipPluginEntry.java new file mode 100644 index 000000000..65d472042 --- /dev/null +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/zip/concept/ZipPluginEntry.java @@ -0,0 +1,57 @@ +package com.github.linyuzai.plugin.zip.concept; + +import com.github.linyuzai.plugin.core.concept.Plugin; +import com.github.linyuzai.plugin.core.exception.PluginException; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +@Getter +@RequiredArgsConstructor +public class ZipPluginEntry implements Plugin.Entry { + + private final Plugin plugin; + + private final String name; + + private ZipPluginEntry parent; + + private final byte[] bytes; + + @Override + public Object getId() { + return null; + } + + @Override + public Plugin.Content getContent() { + return new EntryContent(); + } + + public class EntryContent implements Plugin.Content { + + @Override + public InputStream getInputStream() throws IOException { + if (bytes != null) { + return new ByteArrayInputStream(bytes); + } + if (parent != null) { + InputStream is = parent.getContent().getInputStream(); + ZipInputStream zis = new ZipInputStream(is); + ZipEntry entry; + while ((entry = zis.getNextEntry()) != null) { + if (name.equals(entry.getName())) { + return zis; + } + } + throw new PluginException("Plugin entry not found"); + } + throw new PluginException("Plugin entry data error"); + } + } +} diff --git a/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/zip/factory/ZipPluginFactory.java b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/zip/factory/ZipPluginFactory.java new file mode 100644 index 000000000..f96721348 --- /dev/null +++ b/concept-plugin/concept-plugin-core/src/main/java/com/github/linyuzai/plugin/zip/factory/ZipPluginFactory.java @@ -0,0 +1,172 @@ +package com.github.linyuzai.plugin.zip.factory; + +import com.github.linyuzai.plugin.core.concept.Plugin; +import com.github.linyuzai.plugin.core.context.PluginContext; +import com.github.linyuzai.plugin.core.factory.MetadataPluginFactory; +import com.github.linyuzai.plugin.zip.concept.ZipPlugin; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.SneakyThrows; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.nio.file.Files; +import java.util.Properties; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; +import java.util.zip.ZipInputStream; + +public class ZipPluginFactory extends MetadataPluginFactory { + + @Override + public Plugin doCreate(File file, Plugin.Metadata metadata, PluginContext context) { + String mode = getMode(file, metadata, context); + return createInMode(file, mode, context); + } + + public String getMode(File file, Plugin.Metadata metadata, PluginContext context) { + return metadata.get("concept.plugin.zip.mode", ZipPlugin.Mode.MEMORY); + } + + @SneakyThrows + public Plugin createInMode(File file, String mode, PluginContext context) { + ZipInputStream zis = new ZipInputStream(Files.newInputStream(file.toPath())); + URL url = getURL(file); + switch (mode.toUpperCase()) { + case ZipPlugin.Mode.MEMORY: + return new ZipPlugin(zis, url, null); + case ZipPlugin.Mode.FILE: + return new ZipPlugin(zis, url, new RootFileEntry(url, file)); + default: + throw new IllegalArgumentException("Mode not supported: " + mode); + } + } + + @Override + protected Plugin.Metadata createMetadata(File file, PluginContext context) { + try (ZipFile zipFile = new ZipFile(file)) { + ZipEntry entry = zipFile.getEntry("plugin.properties"); + if (entry == null) { + return new EmptyMetadata(); + } + try (InputStream is = zipFile.getInputStream(entry)) { + Properties properties = new Properties(); + properties.load(is); + return new PropertiesMetadata(properties); + } + } catch (Throwable e) { + return null; + } + } + + @Override + protected File getSource(Object o, PluginContext context) { + File file = getFile(o, context); + if (file != null && supportFile(file, context)) { + return file; + } + return null; + } + + protected boolean supportFile(File file, PluginContext context) { + return file.getName().endsWith(".zip"); + } + + protected File getFile(Object o, PluginContext context) { + if (o instanceof File) { + File file = (File) o; + if (file.exists()) { + return file; + } + } else if (o instanceof String) { + File file = new File((String) o); + if (file.exists()) { + return file; + } + } + return null; + } + + protected URL getURL(File file) throws MalformedURLException { + return file.toURI().toURL(); + } + + @Getter + @RequiredArgsConstructor + public static class RootFileEntry implements Plugin.Entry { + + private final Object id; + + private final File file; + + @Override + public String getName() { + return ""; + } + + @Override + public Plugin getPlugin() { + return null; + } + + @Override + public Plugin.Content getContent() { + return new RootContent(file); + } + } + + @Getter + @RequiredArgsConstructor + public static class RootContent implements Plugin.Content { + + private final File file; + + @Override + public InputStream getInputStream() throws IOException { + return Files.newInputStream(file.toPath()); + } + } + + @Getter + @RequiredArgsConstructor + public static class PropertiesMetadata implements Plugin.Metadata { + + private final Properties properties; + + @Override + public String get(String key) { + return properties.getProperty(key); + } + + @Override + public String get(String key, String defaultValue) { + return properties.getProperty(key, defaultValue); + } + + @Override + public boolean isEmpty() { + return properties.isEmpty(); + } + } + + public static class EmptyMetadata implements Plugin.Metadata { + + @Override + public String get(String key) { + return null; + } + + @Override + public String get(String key, String defaultValue) { + return defaultValue; + } + + @Override + public boolean isEmpty() { + return true; + } + } +}