@@ -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<PluginLoader> 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 + "'"); | |||
} | |||
} |
@@ -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); |
@@ -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 |
@@ -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; | |||
} | |||
} |
@@ -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; | |||
} | |||
} | |||
} |
@@ -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); | |||
} |