diff --git a/pf4j/src/main/java/org/pf4j/CompoundPluginLoader.java b/pf4j/src/main/java/org/pf4j/CompoundPluginLoader.java new file mode 100644 index 0000000..b5c2fad --- /dev/null +++ b/pf4j/src/main/java/org/pf4j/CompoundPluginLoader.java @@ -0,0 +1,81 @@ +/* + * Copyright 2017 Decebal Suiu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.pf4j; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; + +/** + * @author Decebal Suiu + */ +public class CompoundPluginLoader implements PluginLoader { + + private static final Logger log = LoggerFactory.getLogger(CompoundPluginLoader.class); + + private List loaders = new ArrayList<>(); + + public CompoundPluginLoader add(PluginLoader loader) { + if (loader == null) { + throw new IllegalArgumentException("null not allowed"); + } + + loaders.add(loader); + + return this; + } + + public int size() { + return loaders.size(); + } + + @Override + public boolean isApplicable(Path pluginPath) { + for (PluginLoader loader : loaders) { + if (loader.isApplicable(pluginPath)) { + return true; + } + } + + return false; + } + + @Override + public ClassLoader loadPlugin(Path pluginPath, PluginDescriptor pluginDescriptor) { + for (PluginLoader loader : loaders) { + if (loader.isApplicable(pluginPath)) { + log.debug("'{}' is applicable for plugin '{}'", loader, pluginPath); + try { + ClassLoader classLoader = loader.loadPlugin(pluginPath, pluginDescriptor); + if (classLoader != null) { + return classLoader; + } + } catch (Exception e) { + // log the exception and continue with the next loader + log.error(e.getMessage()); // ?! + } + } else { + log.debug("'{}' is not applicable for plugin '{}'", loader, pluginPath); + } + } + + throw new RuntimeException("No PluginLoader for plugin '" + pluginPath + "' and descriptor '" + pluginDescriptor + "'"); + } + +} diff --git a/pf4j/src/main/java/org/pf4j/DefaultPluginLoader.java b/pf4j/src/main/java/org/pf4j/DefaultPluginLoader.java index bdd31eb..71e3590 100644 --- a/pf4j/src/main/java/org/pf4j/DefaultPluginLoader.java +++ b/pf4j/src/main/java/org/pf4j/DefaultPluginLoader.java @@ -18,6 +18,7 @@ package org.pf4j; import org.pf4j.util.FileUtils; import java.io.File; +import java.nio.file.Files; import java.nio.file.Path; import java.util.List; @@ -38,6 +39,11 @@ public class DefaultPluginLoader implements PluginLoader { this.pluginClasspath = pluginClasspath; } + @Override + public boolean isApplicable(Path pluginPath) { + return Files.exists(pluginPath) && Files.isDirectory(pluginPath); + } + @Override public ClassLoader loadPlugin(Path pluginPath, PluginDescriptor pluginDescriptor) { PluginClassLoader pluginClassLoader = createPluginClassLoader(pluginPath, pluginDescriptor); diff --git a/pf4j/src/main/java/org/pf4j/DefaultPluginManager.java b/pf4j/src/main/java/org/pf4j/DefaultPluginManager.java index de1ef2f..1010bcf 100644 --- a/pf4j/src/main/java/org/pf4j/DefaultPluginManager.java +++ b/pf4j/src/main/java/org/pf4j/DefaultPluginManager.java @@ -88,7 +88,9 @@ public class DefaultPluginManager extends AbstractPluginManager { @Override protected PluginLoader createPluginLoader() { - return new DefaultPluginLoader(this, pluginClasspath); + return new CompoundPluginLoader() + .add(new DefaultPluginLoader(this, pluginClasspath)) + .add(new JarPluginLoader(this)); } @Override diff --git a/pf4j/src/main/java/org/pf4j/JarPluginLoader.java b/pf4j/src/main/java/org/pf4j/JarPluginLoader.java new file mode 100644 index 0000000..113b244 --- /dev/null +++ b/pf4j/src/main/java/org/pf4j/JarPluginLoader.java @@ -0,0 +1,47 @@ +/* + * Copyright 2017 Decebal Suiu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.pf4j; + +import org.pf4j.util.FileUtils; + +import java.nio.file.Files; +import java.nio.file.Path; + +/** + * @author Decebal Suiu + */ +public class JarPluginLoader implements PluginLoader { + + protected PluginManager pluginManager; + + public JarPluginLoader(PluginManager pluginManager) { + this.pluginManager = pluginManager; + } + + @Override + public boolean isApplicable(Path pluginPath) { + return Files.exists(pluginPath) && FileUtils.isJarFile(pluginPath); + } + + @Override + public ClassLoader loadPlugin(Path pluginPath, PluginDescriptor pluginDescriptor) { + PluginClassLoader pluginClassLoader = new PluginClassLoader(pluginManager, pluginDescriptor, getClass().getClassLoader()); + pluginClassLoader.addFile(pluginPath.toFile()); + + return pluginClassLoader; + } + +} diff --git a/pf4j/src/main/java/org/pf4j/JarPluginManager.java b/pf4j/src/main/java/org/pf4j/JarPluginManager.java index bd94299..9e66df8 100644 --- a/pf4j/src/main/java/org/pf4j/JarPluginManager.java +++ b/pf4j/src/main/java/org/pf4j/JarPluginManager.java @@ -40,11 +40,6 @@ public class JarPluginManager extends DefaultPluginManager { return new JarPluginRepository(getPluginsRoot(), isDevelopment()); } - @Override - protected PluginLoader createPluginLoader() { - return new JarPluginLoader(this, pluginClasspath); - } - class JarPluginRepository extends BasePluginRepository { public JarPluginRepository(Path pluginsRoot, boolean development) { @@ -71,24 +66,4 @@ public class JarPluginManager extends DefaultPluginManager { } - class JarPluginLoader extends DefaultPluginLoader { - - public JarPluginLoader(PluginManager pluginManager, PluginClasspath pluginClasspath) { - super(pluginManager, pluginClasspath); - } - - @Override - public ClassLoader loadPlugin(Path pluginPath, PluginDescriptor pluginDescriptor) { - if (isDevelopment()) { - return super.loadPlugin(pluginPath, pluginDescriptor); - } - - PluginClassLoader pluginClassLoader = new PluginClassLoader(pluginManager, pluginDescriptor, getClass().getClassLoader()); - pluginClassLoader.addFile(pluginPath.toFile()); - - return pluginClassLoader; - } - - } - } diff --git a/pf4j/src/main/java/org/pf4j/PluginLoader.java b/pf4j/src/main/java/org/pf4j/PluginLoader.java index 5ac2755..fc20b22 100644 --- a/pf4j/src/main/java/org/pf4j/PluginLoader.java +++ b/pf4j/src/main/java/org/pf4j/PluginLoader.java @@ -24,6 +24,14 @@ import java.nio.file.Path; */ public interface PluginLoader { + /** + * Returns true if this loader is applicable to the given {@link Path}. + * + * @param pluginPath + * @return + */ + boolean isApplicable(Path pluginPath); + ClassLoader loadPlugin(Path pluginPath, PluginDescriptor pluginDescriptor); }