From a487cbf37a0e3c6d36113d5da7c0571398a19d43 Mon Sep 17 00:00:00 2001 From: decebals Date: Fri, 3 May 2019 01:08:02 +0300 Subject: [PATCH] Improve #307 (add support for development mode) --- .../java/org/pf4j/AbstractPluginManager.java | 4 +- .../main/java/org/pf4j/BasePluginLoader.java | 88 +++++++++++++++++++ .../java/org/pf4j/CompoundPluginLoader.java | 16 ++++ .../org/pf4j/CompoundPluginRepository.java | 22 ++++- .../java/org/pf4j/DefaultPluginClasspath.java | 9 +- .../java/org/pf4j/DefaultPluginLoader.java | 59 ++----------- .../java/org/pf4j/DefaultPluginManager.java | 23 ++--- .../org/pf4j/DefaultPluginRepository.java | 17 +--- .../org/pf4j/DevelopmentPluginClasspath.java | 8 +- .../org/pf4j/DevelopmentPluginLoader.java | 29 ++++++ .../org/pf4j/DevelopmentPluginRepository.java | 55 ++++++++++++ .../main/java/org/pf4j/JarPluginManager.java | 8 +- .../main/java/org/pf4j/PluginClasspath.java | 17 ++-- .../src/main/java/org/pf4j/PluginManager.java | 9 +- .../main/java/org/pf4j/ZipPluginManager.java | 8 +- .../CompoundPluginDescriptorFinderTest.java | 7 +- .../org/pf4j/DefaultPluginRepositoryTest.java | 30 +------ .../pf4j/DevelopmentPluginRepositoryTest.java | 61 +++++++++++++ 18 files changed, 334 insertions(+), 136 deletions(-) create mode 100644 pf4j/src/main/java/org/pf4j/BasePluginLoader.java create mode 100644 pf4j/src/main/java/org/pf4j/DevelopmentPluginLoader.java create mode 100644 pf4j/src/main/java/org/pf4j/DevelopmentPluginRepository.java create mode 100644 pf4j/src/test/java/org/pf4j/DevelopmentPluginRepositoryTest.java diff --git a/pf4j/src/main/java/org/pf4j/AbstractPluginManager.java b/pf4j/src/main/java/org/pf4j/AbstractPluginManager.java index 9e86909..fc0a22e 100644 --- a/pf4j/src/main/java/org/pf4j/AbstractPluginManager.java +++ b/pf4j/src/main/java/org/pf4j/AbstractPluginManager.java @@ -45,6 +45,8 @@ public abstract class AbstractPluginManager implements PluginManager { private static final Logger log = LoggerFactory.getLogger(AbstractPluginManager.class); public static final String PLUGINS_DIR_PROPERTY_NAME = "pf4j.pluginsDir"; + public static final String MODE_PROPERTY_NAME = "pf4j.mode"; + public static final String DEFAULT_PLUGINS_DIR = "plugins"; public static final String DEVELOPMENT_PLUGINS_DIR = "../plugins"; @@ -588,7 +590,7 @@ public abstract class AbstractPluginManager implements PluginManager { public RuntimeMode getRuntimeMode() { if (runtimeMode == null) { // retrieves the runtime mode from system - String modeAsString = System.getProperty("pf4j.mode", RuntimeMode.DEPLOYMENT.toString()); + String modeAsString = System.getProperty(MODE_PROPERTY_NAME, RuntimeMode.DEPLOYMENT.toString()); runtimeMode = RuntimeMode.byName(modeAsString); } diff --git a/pf4j/src/main/java/org/pf4j/BasePluginLoader.java b/pf4j/src/main/java/org/pf4j/BasePluginLoader.java new file mode 100644 index 0000000..e4f22f3 --- /dev/null +++ b/pf4j/src/main/java/org/pf4j/BasePluginLoader.java @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2012-present the original author or authors. + * + * 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.io.File; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; + +/** + * Load all information needed by a plugin. + * This means add to the plugin's {@link ClassLoader} all the jar files and + * all the class files specified in the {@link PluginClasspath}. + * + * @author Decebal Suiu + */ +public class BasePluginLoader implements PluginLoader { + + protected PluginManager pluginManager; + protected PluginClasspath pluginClasspath; + + public BasePluginLoader(PluginManager pluginManager, PluginClasspath pluginClasspath) { + this.pluginManager = pluginManager; + this.pluginClasspath = pluginClasspath; + } + + @Override + public boolean isApplicable(Path pluginPath) { + return Files.exists(pluginPath); + } + + @Override + public ClassLoader loadPlugin(Path pluginPath, PluginDescriptor pluginDescriptor) { + PluginClassLoader pluginClassLoader = createPluginClassLoader(pluginPath, pluginDescriptor); + + loadClasses(pluginPath, pluginClassLoader); + loadJars(pluginPath, pluginClassLoader); + + return pluginClassLoader; + } + + protected PluginClassLoader createPluginClassLoader(Path pluginPath, PluginDescriptor pluginDescriptor) { + return new PluginClassLoader(pluginManager, pluginDescriptor, getClass().getClassLoader()); + } + + /** + * Add all {@code *.class} files from {@link PluginClasspath#getClassesDirectories()} + * to the plugin's {@link ClassLoader}. + */ + protected void loadClasses(Path pluginPath, PluginClassLoader pluginClassLoader) { + for (String directory : pluginClasspath.getClassesDirectories()) { + File file = pluginPath.resolve(directory).toFile(); + if (file.exists() && file.isDirectory()) { + pluginClassLoader.addFile(file); + } + } + } + + /** + * Add all {@code *.jar} files from {@link PluginClasspath#getJarsDirectories()} + * to the plugin's {@link ClassLoader}. + */ + protected void loadJars(Path pluginPath, PluginClassLoader pluginClassLoader) { + for (String jarsDirectory : pluginClasspath.getJarsDirectories()) { + Path file = pluginPath.resolve(jarsDirectory); + List jars = FileUtils.getJars(file); + for (File jar : jars) { + pluginClassLoader.addFile(jar); + } + } + } + +} diff --git a/pf4j/src/main/java/org/pf4j/CompoundPluginLoader.java b/pf4j/src/main/java/org/pf4j/CompoundPluginLoader.java index fe10d68..c20e4bb 100644 --- a/pf4j/src/main/java/org/pf4j/CompoundPluginLoader.java +++ b/pf4j/src/main/java/org/pf4j/CompoundPluginLoader.java @@ -21,6 +21,7 @@ import org.slf4j.LoggerFactory; import java.nio.file.Path; import java.util.ArrayList; import java.util.List; +import java.util.function.BooleanSupplier; /** * @author Decebal Suiu @@ -41,6 +42,21 @@ public class CompoundPluginLoader implements PluginLoader { return this; } + /** + * Add a {@link PluginLoader} only if the {@code condition} is satisfied. + * + * @param loader + * @param condition + * @return + */ + public CompoundPluginLoader add(PluginLoader loader, BooleanSupplier condition) { + if (condition.getAsBoolean()) { + return add(loader); + } + + return this; + } + public int size() { return loaders.size(); } diff --git a/pf4j/src/main/java/org/pf4j/CompoundPluginRepository.java b/pf4j/src/main/java/org/pf4j/CompoundPluginRepository.java index c738191..aef714c 100644 --- a/pf4j/src/main/java/org/pf4j/CompoundPluginRepository.java +++ b/pf4j/src/main/java/org/pf4j/CompoundPluginRepository.java @@ -17,7 +17,10 @@ package org.pf4j; import java.nio.file.Path; import java.util.ArrayList; +import java.util.LinkedHashSet; import java.util.List; +import java.util.Set; +import java.util.function.BooleanSupplier; /** * @author Decebal Suiu @@ -37,14 +40,29 @@ public class CompoundPluginRepository implements PluginRepository { return this; } + /** + * Add a {@link PluginRepository} only if the {@code condition} is satisfied. + * + * @param repository + * @param condition + * @return + */ + public CompoundPluginRepository add(PluginRepository repository, BooleanSupplier condition) { + if (condition.getAsBoolean()) { + return add(repository); + } + + return this; + } + @Override public List getPluginsPaths() { - List paths = new ArrayList<>(); + Set paths = new LinkedHashSet<>(); for (PluginRepository repository : repositories) { paths.addAll(repository.getPluginsPaths()); } - return paths; + return new ArrayList<>(paths); } @Override diff --git a/pf4j/src/main/java/org/pf4j/DefaultPluginClasspath.java b/pf4j/src/main/java/org/pf4j/DefaultPluginClasspath.java index a78bfd3..2d64e1e 100644 --- a/pf4j/src/main/java/org/pf4j/DefaultPluginClasspath.java +++ b/pf4j/src/main/java/org/pf4j/DefaultPluginClasspath.java @@ -16,17 +16,20 @@ package org.pf4j; /** - * The default values are {@code classes} and {@code lib}. + * The default values are {@link #CLASSES_DIR} and {@code #LIB_DIR}. * * @author Decebal Suiu */ public class DefaultPluginClasspath extends PluginClasspath { + public static final String CLASSES_DIR = "classes"; + public static final String LIB_DIR = "lib"; + public DefaultPluginClasspath() { super(); - addClassesDirectories("classes"); - addLibDirectories("lib"); + addClassesDirectories(CLASSES_DIR); + addJarsDirectories(LIB_DIR); } } diff --git a/pf4j/src/main/java/org/pf4j/DefaultPluginLoader.java b/pf4j/src/main/java/org/pf4j/DefaultPluginLoader.java index 60d63be..1ee8349 100644 --- a/pf4j/src/main/java/org/pf4j/DefaultPluginLoader.java +++ b/pf4j/src/main/java/org/pf4j/DefaultPluginLoader.java @@ -15,72 +15,23 @@ */ 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; /** - * Load all information needed by a plugin. - * This means add to classpath all jar files from {@code lib} directory - * and all class files from {@code classes}. + * Load all information needed by a plugin from {@link DefaultPluginClasspath}. * * @author Decebal Suiu */ -public class DefaultPluginLoader implements PluginLoader { - - protected PluginManager pluginManager; - protected PluginClasspath pluginClasspath; +public class DefaultPluginLoader extends BasePluginLoader { - public DefaultPluginLoader(PluginManager pluginManager, PluginClasspath pluginClasspath) { - this.pluginManager = pluginManager; - this.pluginClasspath = pluginClasspath; + public DefaultPluginLoader(PluginManager pluginManager) { + super(pluginManager, new DefaultPluginClasspath()); } @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); - - loadClasses(pluginPath, pluginClassLoader); - loadJars(pluginPath, pluginClassLoader); - - return pluginClassLoader; - } - - protected PluginClassLoader createPluginClassLoader(Path pluginPath, PluginDescriptor pluginDescriptor) { - return new PluginClassLoader(pluginManager, pluginDescriptor, getClass().getClassLoader()); - } - - /** - * Add all {@code *.class} files from {@code classes} directories to plugin class loader. - */ - protected void loadClasses(Path pluginPath, PluginClassLoader pluginClassLoader) { - for (String directory : pluginClasspath.getClassesDirectories()) { - File file = pluginPath.resolve(directory).toFile(); - if (file.exists() && file.isDirectory()) { - pluginClassLoader.addFile(file); - } - } - } - - /** - * Add all {@code *.jar} files from {@code lib} directories to plugin class loader. - */ - protected void loadJars(Path pluginPath, PluginClassLoader pluginClassLoader) { - for (String libDirectory : pluginClasspath.getLibDirectories()) { - Path file = pluginPath.resolve(libDirectory); - List jars = FileUtils.getJars(file); - for (File jar : jars) { - pluginClassLoader.addFile(jar); - } - } + return super.isApplicable(pluginPath) && Files.isDirectory(pluginPath); } } diff --git a/pf4j/src/main/java/org/pf4j/DefaultPluginManager.java b/pf4j/src/main/java/org/pf4j/DefaultPluginManager.java index db5678b..cafdb4e 100644 --- a/pf4j/src/main/java/org/pf4j/DefaultPluginManager.java +++ b/pf4j/src/main/java/org/pf4j/DefaultPluginManager.java @@ -37,8 +37,6 @@ public class DefaultPluginManager extends AbstractPluginManager { public static final String PLUGINS_DIR_CONFIG_PROPERTY_NAME = "pf4j.pluginsConfigDir"; - protected PluginClasspath pluginClasspath; - public DefaultPluginManager() { super(); } @@ -76,21 +74,24 @@ public class DefaultPluginManager extends AbstractPluginManager { protected PluginStatusProvider createPluginStatusProvider() { String configDir = System.getProperty(PLUGINS_DIR_CONFIG_PROPERTY_NAME); Path configPath = configDir != null ? Paths.get(configDir) : getPluginsRoot(); + return new DefaultPluginStatusProvider(configPath); } @Override protected PluginRepository createPluginRepository() { return new CompoundPluginRepository() - .add(new JarPluginRepository(getPluginsRoot())) - .add(new DefaultPluginRepository(getPluginsRoot(), isDevelopment())); + .add(new DevelopmentPluginRepository(getPluginsRoot()), this::isDevelopment) + .add(new JarPluginRepository(getPluginsRoot()), this::isNotDevelopment) + .add(new DefaultPluginRepository(getPluginsRoot()), this::isNotDevelopment); } @Override protected PluginLoader createPluginLoader() { return new CompoundPluginLoader() - .add(new JarPluginLoader(this)) - .add(new DefaultPluginLoader(this, pluginClasspath)); + .add(new DevelopmentPluginLoader(this), this::isDevelopment) + .add(new JarPluginLoader(this), this::isNotDevelopment) + .add(new DefaultPluginLoader(this), this::isNotDevelopment); } @Override @@ -98,18 +99,8 @@ public class DefaultPluginManager extends AbstractPluginManager { return new DefaultVersionManager(); } - /** - * By default if {@link #isDevelopment()} returns {@code true} than a {@link DevelopmentPluginClasspath} - * is returned, else this method returns {@link DefaultPluginClasspath}. - */ - protected PluginClasspath createPluginClasspath() { - return isDevelopment() ? new DevelopmentPluginClasspath() : new DefaultPluginClasspath(); - } - @Override protected void initialize() { - pluginClasspath = createPluginClasspath(); - super.initialize(); if (isDevelopment()) { diff --git a/pf4j/src/main/java/org/pf4j/DefaultPluginRepository.java b/pf4j/src/main/java/org/pf4j/DefaultPluginRepository.java index 1c031b6..f50a231 100644 --- a/pf4j/src/main/java/org/pf4j/DefaultPluginRepository.java +++ b/pf4j/src/main/java/org/pf4j/DefaultPluginRepository.java @@ -39,11 +39,11 @@ public class DefaultPluginRepository extends BasePluginRepository { private static final Logger log = LoggerFactory.getLogger(DefaultPluginRepository.class); - public DefaultPluginRepository(Path pluginsRoot, boolean development) { + public DefaultPluginRepository(Path pluginsRoot) { super(pluginsRoot); AndFileFilter pluginsFilter = new AndFileFilter(new DirectoryFileFilter()); - pluginsFilter.addFileFilter(new NotFileFilter(createHiddenPluginFilter(development))); + pluginsFilter.addFileFilter(new NotFileFilter(createHiddenPluginFilter())); setFilter(pluginsFilter); } @@ -59,17 +59,8 @@ public class DefaultPluginRepository extends BasePluginRepository { return super.deletePluginPath(pluginPath); } - protected FileFilter createHiddenPluginFilter(boolean development) { - OrFileFilter hiddenPluginFilter = new OrFileFilter(new HiddenFilter()); - - if (development) { - // skip default build output folders since these will cause errors in the logs - hiddenPluginFilter - .addFileFilter(new NameFileFilter("target")) // MAVEN - .addFileFilter(new NameFileFilter("build")); // GRADLE - } - - return hiddenPluginFilter; + protected FileFilter createHiddenPluginFilter() { + return new OrFileFilter(new HiddenFilter()); } private void extractZipFiles() { diff --git a/pf4j/src/main/java/org/pf4j/DevelopmentPluginClasspath.java b/pf4j/src/main/java/org/pf4j/DevelopmentPluginClasspath.java index 15da659..4d7727d 100644 --- a/pf4j/src/main/java/org/pf4j/DevelopmentPluginClasspath.java +++ b/pf4j/src/main/java/org/pf4j/DevelopmentPluginClasspath.java @@ -27,7 +27,7 @@ public class DevelopmentPluginClasspath extends PluginClasspath { * The development plugin classpath for Maven. * The classes directory is {@code target/classes} and the lib directory is {@code target/lib}. */ - public static final PluginClasspath MAVEN = new PluginClasspath().addClassesDirectories("target/classes").addLibDirectories("target/lib"); + public static final PluginClasspath MAVEN = new PluginClasspath().addClassesDirectories("target/classes").addJarsDirectories("target/lib"); /** * The development plugin classpath for Gradle. @@ -46,9 +46,9 @@ public class DevelopmentPluginClasspath extends PluginClasspath { addClassesDirectories(GRADLE.getClassesDirectories()); addClassesDirectories(KOTLIN.getClassesDirectories()); - addLibDirectories(MAVEN.getLibDirectories()); - addLibDirectories(GRADLE.getLibDirectories()); - addLibDirectories(KOTLIN.getLibDirectories()); + addJarsDirectories(MAVEN.getJarsDirectories()); + addJarsDirectories(GRADLE.getJarsDirectories()); + addJarsDirectories(KOTLIN.getJarsDirectories()); } } diff --git a/pf4j/src/main/java/org/pf4j/DevelopmentPluginLoader.java b/pf4j/src/main/java/org/pf4j/DevelopmentPluginLoader.java new file mode 100644 index 0000000..58c9473 --- /dev/null +++ b/pf4j/src/main/java/org/pf4j/DevelopmentPluginLoader.java @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2012-present the original author or authors. + * + * 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; + +/** + * Load all information needed by a plugin from {@link DevelopmentPluginClasspath}. + * + * @author Decebal Suiu + */ +public class DevelopmentPluginLoader extends BasePluginLoader { + + public DevelopmentPluginLoader(PluginManager pluginManager) { + super(pluginManager, new DevelopmentPluginClasspath()); + } + +} diff --git a/pf4j/src/main/java/org/pf4j/DevelopmentPluginRepository.java b/pf4j/src/main/java/org/pf4j/DevelopmentPluginRepository.java new file mode 100644 index 0000000..e8f2c69 --- /dev/null +++ b/pf4j/src/main/java/org/pf4j/DevelopmentPluginRepository.java @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2012-present the original author or authors. + * + * 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.AndFileFilter; +import org.pf4j.util.DirectoryFileFilter; +import org.pf4j.util.HiddenFilter; +import org.pf4j.util.NameFileFilter; +import org.pf4j.util.NotFileFilter; +import org.pf4j.util.OrFileFilter; + +import java.io.FileFilter; +import java.nio.file.Path; + +/** + * @author Decebal Suiu + */ +public class DevelopmentPluginRepository extends BasePluginRepository { + + public static final String MAVEN_BUILD_DIR = "target"; + public static final String GRADLE_BUILD_DIR = "build"; + + public DevelopmentPluginRepository(Path pluginsRoot) { + super(pluginsRoot); + + AndFileFilter pluginsFilter = new AndFileFilter(new DirectoryFileFilter()); + pluginsFilter.addFileFilter(new NotFileFilter(createHiddenPluginFilter())); + setFilter(pluginsFilter); + } + + protected FileFilter createHiddenPluginFilter() { + OrFileFilter hiddenPluginFilter = new OrFileFilter(new HiddenFilter()); + + // skip default build output folders since these will cause errors in the logs + hiddenPluginFilter + .addFileFilter(new NameFileFilter(MAVEN_BUILD_DIR)) + .addFileFilter(new NameFileFilter(GRADLE_BUILD_DIR)); + + return hiddenPluginFilter; + } + +} diff --git a/pf4j/src/main/java/org/pf4j/JarPluginManager.java b/pf4j/src/main/java/org/pf4j/JarPluginManager.java index 68c50db..5921aa5 100644 --- a/pf4j/src/main/java/org/pf4j/JarPluginManager.java +++ b/pf4j/src/main/java/org/pf4j/JarPluginManager.java @@ -31,12 +31,16 @@ public class JarPluginManager extends DefaultPluginManager { @Override protected PluginLoader createPluginLoader() { - return new JarPluginLoader(this); + return new CompoundPluginLoader() + .add(new DevelopmentPluginLoader(this), this::isDevelopment) + .add(new JarPluginLoader(this), this::isNotDevelopment); } @Override protected PluginRepository createPluginRepository() { - return new JarPluginRepository(getPluginsRoot()); + return new CompoundPluginRepository() + .add(new DevelopmentPluginRepository(getPluginsRoot()), this::isDevelopment) + .add(new JarPluginRepository(getPluginsRoot()), this::isNotDevelopment); } } diff --git a/pf4j/src/main/java/org/pf4j/PluginClasspath.java b/pf4j/src/main/java/org/pf4j/PluginClasspath.java index 57ff9bf..757740c 100644 --- a/pf4j/src/main/java/org/pf4j/PluginClasspath.java +++ b/pf4j/src/main/java/org/pf4j/PluginClasspath.java @@ -22,14 +22,15 @@ import java.util.Set; /** * The classpath of the plugin. - * It contains {@code classes} directories and {@code lib} directories (directories that contains jars). + * It contains {@code classes} directories (directories that contain classes files) + * and {@code jars} directories (directories that contain jars files). * * @author Decebal Suiu */ public class PluginClasspath { private Set classesDirectories = new HashSet<>(); - private Set libDirectories = new HashSet<>(); + private Set jarsDirectories = new HashSet<>(); public Set getClassesDirectories() { return classesDirectories; @@ -45,16 +46,16 @@ public class PluginClasspath { return this; } - public Set getLibDirectories() { - return libDirectories; + public Set getJarsDirectories() { + return jarsDirectories; } - public PluginClasspath addLibDirectories(String... libDirectories) { - return addLibDirectories(Arrays.asList(libDirectories)); + public PluginClasspath addJarsDirectories(String... jarsDirectories) { + return addJarsDirectories(Arrays.asList(jarsDirectories)); } - public PluginClasspath addLibDirectories(Collection libDirectories) { - this.libDirectories.addAll(libDirectories); + public PluginClasspath addJarsDirectories(Collection jarsDirectories) { + this.jarsDirectories.addAll(jarsDirectories); return this; } diff --git a/pf4j/src/main/java/org/pf4j/PluginManager.java b/pf4j/src/main/java/org/pf4j/PluginManager.java index badba28..0fb9b1f 100644 --- a/pf4j/src/main/java/org/pf4j/PluginManager.java +++ b/pf4j/src/main/java/org/pf4j/PluginManager.java @@ -155,12 +155,19 @@ public interface PluginManager { RuntimeMode getRuntimeMode(); /** - * Returns {@code true} id the runtime mode is {@code RuntimeMode.DEVELOPMENT}. + * Returns {@code true} if the runtime mode is {@code RuntimeMode.DEVELOPMENT}. */ default boolean isDevelopment() { return RuntimeMode.DEVELOPMENT.equals(getRuntimeMode()); } + /** + * Returns {@code true} if the runtime mode is not {@code RuntimeMode.DEVELOPMENT}. + */ + default boolean isNotDevelopment() { + return !isDevelopment(); + } + /** * Retrieves the {@link PluginWrapper} that loaded the given class 'clazz'. */ diff --git a/pf4j/src/main/java/org/pf4j/ZipPluginManager.java b/pf4j/src/main/java/org/pf4j/ZipPluginManager.java index ab17fc9..a32d156 100644 --- a/pf4j/src/main/java/org/pf4j/ZipPluginManager.java +++ b/pf4j/src/main/java/org/pf4j/ZipPluginManager.java @@ -34,12 +34,16 @@ public class ZipPluginManager extends DefaultPluginManager { @Override protected PluginLoader createPluginLoader() { - return new DefaultPluginLoader(this, pluginClasspath); + return new CompoundPluginLoader() + .add(new DevelopmentPluginLoader(this), this::isDevelopment) + .add(new DefaultPluginLoader(this), this::isNotDevelopment); } @Override protected PluginRepository createPluginRepository() { - return new DefaultPluginRepository(getPluginsRoot(), isDevelopment()); + return new CompoundPluginRepository() + .add(new DevelopmentPluginRepository(getPluginsRoot()), this::isDevelopment) + .add(new DefaultPluginRepository(getPluginsRoot()), this::isNotDevelopment); } } diff --git a/pf4j/src/test/java/org/pf4j/CompoundPluginDescriptorFinderTest.java b/pf4j/src/test/java/org/pf4j/CompoundPluginDescriptorFinderTest.java index 7e6043b..d74bea3 100644 --- a/pf4j/src/test/java/org/pf4j/CompoundPluginDescriptorFinderTest.java +++ b/pf4j/src/test/java/org/pf4j/CompoundPluginDescriptorFinderTest.java @@ -92,13 +92,14 @@ public class CompoundPluginDescriptorFinderTest { @Test public void testSpaceCharacterInFileName() throws Exception { - PluginDescriptorFinder descriptorFinder = new PropertiesPluginDescriptorFinder(); + PluginDescriptorFinder descriptorFinder = new CompoundPluginDescriptorFinder() + .add(new ManifestPluginDescriptorFinder()); - PluginZip pluginZip = new PluginZip.Builder(pluginsPath.resolve("my plugin-1.2.3.jar"), "myPlugin") + PluginJar pluginJar = new PluginJar.Builder(pluginsPath.resolve("my plugin-1.2.3.jar"), "myPlugin") .pluginVersion("1.2.3") .build(); - PluginDescriptor pluginDescriptor = descriptorFinder.find(pluginZip.path()); + PluginDescriptor pluginDescriptor = descriptorFinder.find(pluginJar.path()); assertNotNull(pluginDescriptor); } diff --git a/pf4j/src/test/java/org/pf4j/DefaultPluginRepositoryTest.java b/pf4j/src/test/java/org/pf4j/DefaultPluginRepositoryTest.java index 3805c42..2237dfe 100644 --- a/pf4j/src/test/java/org/pf4j/DefaultPluginRepositoryTest.java +++ b/pf4j/src/test/java/org/pf4j/DefaultPluginRepositoryTest.java @@ -46,9 +46,6 @@ public class DefaultPluginRepositoryTest { Files.createFile(pluginsPath.resolve("plugin-1.zip")); Files.createDirectory(pluginsPath.resolve("plugin-2")); Files.createDirectory(pluginsPath.resolve("plugin-3")); - // standard maven/gradle bin folder - these should be skipped in development mode because the cause errors - Files.createDirectory(pluginsPath.resolve("target")); - Files.createDirectory(pluginsPath.resolve("build")); } /** @@ -56,29 +53,14 @@ public class DefaultPluginRepositoryTest { */ @Test public void testGetPluginArchives() { - PluginRepository repository = new DefaultPluginRepository(pluginsPath, false); + PluginRepository repository = new DefaultPluginRepository(pluginsPath); List pluginsPaths = repository.getPluginsPaths(); - assertEquals(5, pluginsPaths.size()); + assertEquals(3, pluginsPaths.size()); assertPathExists(pluginsPaths, pluginsPath.resolve("plugin-1")); assertPathExists(pluginsPaths, pluginsPath.resolve("plugin-2")); assertPathExists(pluginsPaths, pluginsPath.resolve("plugin-3")); - // when not in development mode we will honor these folders - assertPathExists(pluginsPaths, pluginsPath.resolve("target")); - assertPathExists(pluginsPaths, pluginsPath.resolve("build")); - } - - @Test - public void testGetPluginArchivesInDevelopmentMode() { - PluginRepository repository = new DefaultPluginRepository(pluginsPath, true); - - List pluginsPaths = repository.getPluginsPaths(); - - // target and build should be ignored - assertEquals(3, pluginsPaths.size()); - assertPathDoesNotExists(pluginsPaths, pluginsPath.resolve("target")); - assertPathDoesNotExists(pluginsPaths, pluginsPath.resolve("build")); } /** @@ -86,15 +68,13 @@ public class DefaultPluginRepositoryTest { */ @Test public void testDeletePluginPath() throws PluginException { - PluginRepository repository = new DefaultPluginRepository(pluginsPath, false); + PluginRepository repository = new DefaultPluginRepository(pluginsPath); assertTrue(Files.exists(pluginsPath.resolve("plugin-1.zip"))); assertTrue(repository.deletePluginPath(pluginsPath.resolve("plugin-1"))); assertFalse(Files.exists(pluginsPath.resolve("plugin-1.zip"))); assertTrue(repository.deletePluginPath(pluginsPath.resolve("plugin-3"))); assertFalse(repository.deletePluginPath(pluginsPath.resolve("plugin-4"))); - assertTrue(repository.deletePluginPath(pluginsPath.resolve("target"))); - assertTrue(repository.deletePluginPath(pluginsPath.resolve("build"))); List pluginsPaths = repository.getPluginsPaths(); @@ -106,8 +86,4 @@ public class DefaultPluginRepositoryTest { assertTrue(paths.contains(path), "The directory must contain the file " + path); } - private void assertPathDoesNotExists(List paths, Path path) { - assertFalse(paths.contains(path), "The directory must not contain the file " + path); - } - } diff --git a/pf4j/src/test/java/org/pf4j/DevelopmentPluginRepositoryTest.java b/pf4j/src/test/java/org/pf4j/DevelopmentPluginRepositoryTest.java new file mode 100644 index 0000000..9e4c8da --- /dev/null +++ b/pf4j/src/test/java/org/pf4j/DevelopmentPluginRepositoryTest.java @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2012-present the original author or authors. + * + * 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.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; + +/** + * @author Decebal Suiu + */ +public class DevelopmentPluginRepositoryTest { + + @TempDir + Path pluginsPath; + + @BeforeEach + public void setUp() throws IOException { + // standard maven/gradle bin folder - these should be skipped in development mode because the cause errors + Files.createDirectory(pluginsPath.resolve(DevelopmentPluginRepository.MAVEN_BUILD_DIR)); + Files.createDirectory(pluginsPath.resolve(DevelopmentPluginRepository.GRADLE_BUILD_DIR)); + } + + @Test + public void testGetPluginArchivesInDevelopmentMode() { + PluginRepository repository = new DevelopmentPluginRepository(pluginsPath); + + List pluginsPaths = repository.getPluginsPaths(); + + // target and build should be ignored + assertEquals(0, pluginsPaths.size()); + assertPathDoesNotExists(pluginsPaths, pluginsPath.resolve(DevelopmentPluginRepository.MAVEN_BUILD_DIR)); + assertPathDoesNotExists(pluginsPaths, pluginsPath.resolve(DevelopmentPluginRepository.GRADLE_BUILD_DIR)); + } + + private void assertPathDoesNotExists(List paths, Path path) { + assertFalse(paths.contains(path), "The directory must not contain the file " + path); + } + +} -- 2.39.5