]> source.dussan.org Git - pf4j.git/commitdiff
Improve #307 (add support for development mode)
authordecebals <decebal.suiu@gmail.com>
Thu, 2 May 2019 22:08:02 +0000 (01:08 +0300)
committerdecebals <decebal.suiu@gmail.com>
Thu, 2 May 2019 22:08:02 +0000 (01:08 +0300)
18 files changed:
pf4j/src/main/java/org/pf4j/AbstractPluginManager.java
pf4j/src/main/java/org/pf4j/BasePluginLoader.java [new file with mode: 0644]
pf4j/src/main/java/org/pf4j/CompoundPluginLoader.java
pf4j/src/main/java/org/pf4j/CompoundPluginRepository.java
pf4j/src/main/java/org/pf4j/DefaultPluginClasspath.java
pf4j/src/main/java/org/pf4j/DefaultPluginLoader.java
pf4j/src/main/java/org/pf4j/DefaultPluginManager.java
pf4j/src/main/java/org/pf4j/DefaultPluginRepository.java
pf4j/src/main/java/org/pf4j/DevelopmentPluginClasspath.java
pf4j/src/main/java/org/pf4j/DevelopmentPluginLoader.java [new file with mode: 0644]
pf4j/src/main/java/org/pf4j/DevelopmentPluginRepository.java [new file with mode: 0644]
pf4j/src/main/java/org/pf4j/JarPluginManager.java
pf4j/src/main/java/org/pf4j/PluginClasspath.java
pf4j/src/main/java/org/pf4j/PluginManager.java
pf4j/src/main/java/org/pf4j/ZipPluginManager.java
pf4j/src/test/java/org/pf4j/CompoundPluginDescriptorFinderTest.java
pf4j/src/test/java/org/pf4j/DefaultPluginRepositoryTest.java
pf4j/src/test/java/org/pf4j/DevelopmentPluginRepositoryTest.java [new file with mode: 0644]

index 9e86909e672e823a49da46b5f43177b4e721d3c9..fc0a22e82326d5ef65cd936699a5e8a987c9a6f6 100644 (file)
@@ -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 (file)
index 0000000..e4f22f3
--- /dev/null
@@ -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<File> jars = FileUtils.getJars(file);
+            for (File jar : jars) {
+                pluginClassLoader.addFile(jar);
+            }
+        }
+    }
+
+}
index fe10d680758996ce9c0937a3b4d9ffaeaeb8faa6..c20e4bb11506ab543b2f0e430770373f5cf3e510 100644 (file)
@@ -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();
     }
index c73819152bd0477d09dcd9d64631748c56056815..aef714c9df6c8cd1434990974d0a86cb79e2a9e2 100644 (file)
@@ -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<Path> getPluginsPaths() {
-        List<Path> paths = new ArrayList<>();
+        Set<Path> paths = new LinkedHashSet<>();
         for (PluginRepository repository : repositories) {
             paths.addAll(repository.getPluginsPaths());
         }
 
-        return paths;
+        return new ArrayList<>(paths);
     }
 
     @Override
index a78bfd3cd93e7be7591acae8c0b6760f2cef6f17..2d64e1e35697df31e419ff011b8777a045c667d2 100644 (file)
 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);
     }
 
 }
index 60d63be32ebfc76b50e4e6ae954548560c824187..1ee834939d3670f5149f37c722fdd62e13f1ca2a 100644 (file)
  */
 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<File> jars = FileUtils.getJars(file);
-            for (File jar : jars) {
-                pluginClassLoader.addFile(jar);
-            }
-        }
+        return super.isApplicable(pluginPath) && Files.isDirectory(pluginPath);
     }
 
 }
index db5678ba80739556dd5e48ada018d48ffaac7bee..cafdb4ec25ab25ce49c330683ee35a0274bfec65 100644 (file)
@@ -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()) {
index 1c031b63f2ce5d1b1e5cffb7844dc14fd7f57d52..f50a231e6ae347ffe9e5c58c6b6b940824f699af 100644 (file)
@@ -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() {
index 15da659460b7f825428388d160fabd5a1b72f0fe..4d7727dda5ad935dd7d0e7591362c55635c04293 100644 (file)
@@ -27,7 +27,7 @@ public class DevelopmentPluginClasspath extends PluginClasspath {
      * The development plugin classpath for <a href="https://maven.apache.org">Maven</a>.
      * 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 <a href="https://gradle.org">Gradle</a>.
@@ -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 (file)
index 0000000..58c9473
--- /dev/null
@@ -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 (file)
index 0000000..e8f2c69
--- /dev/null
@@ -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;
+    }
+
+}
index 68c50db37e7f060c6d461caff4e2a17c688f2829..5921aa5aa996766ae3b8cbba72b01af954d63cf6 100644 (file)
@@ -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);
     }
 
 }
index 57ff9bf876ddffee981bbc73b3d27f4593768036..757740ce389752adb92aa33e5d83845ac28d7583 100644 (file)
@@ -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<String> classesDirectories = new HashSet<>();
-    private Set<String> libDirectories = new HashSet<>();
+    private Set<String> jarsDirectories = new HashSet<>();
 
     public Set<String> getClassesDirectories() {
         return classesDirectories;
@@ -45,16 +46,16 @@ public class PluginClasspath {
         return this;
     }
 
-    public Set<String> getLibDirectories() {
-        return libDirectories;
+    public Set<String> 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<String> libDirectories) {
-        this.libDirectories.addAll(libDirectories);
+    public PluginClasspath addJarsDirectories(Collection<String> jarsDirectories) {
+        this.jarsDirectories.addAll(jarsDirectories);
 
         return this;
     }
index badba287c993aba1775edf5b6191d29dba07aed3..0fb9b1fae666cda8acf6e9d0ac578299155bd001 100644 (file)
@@ -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'.
      */
index ab17fc959fd41c4fcd688282b76c2afb52df2a85..a32d156e0d05c6c16b7ce2fa141b39b76172754a 100644 (file)
@@ -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);
     }
 
 }
index 7e6043b8053b110ef52d79dcd3ec1e95989a8a29..d74bea3617c6d5de8455f2a1c38147caaadbaa41 100644 (file)
@@ -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);
     }
 
index 3805c426c333b7f9a3de11bcd58beeb82565e6e9..2237dfef6a686f859c80968fbc498b5f5b682f51 100644 (file)
@@ -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<Path> 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<Path> 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<Path> 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<Path> 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 (file)
index 0000000..9e4c8da
--- /dev/null
@@ -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<Path> 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<Path> paths, Path path) {
+        assertFalse(paths.contains(path), "The directory must not contain the file " + path);
+    }
+
+}