summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrreich <rainer.reich@coremedia.com>2020-11-05 14:37:08 +0100
committerGitHub <noreply@github.com>2020-11-05 15:37:08 +0200
commitf6ede83be37a29b069a602fdf4b4864c16f2c3d2 (patch)
tree079e30e562d5f4a0f0f68fd2c87ec684b489bcdc
parentc2d9998350b3a15ff7678c9053bca434463cf915 (diff)
downloadpf4j-f6ede83be37a29b069a602fdf4b4864c16f2c3d2.tar.gz
pf4j-f6ede83be37a29b069a602fdf4b4864c16f2c3d2.zip
Support multiple plugin root directories (#404)
-rw-r--r--pf4j/src/main/java/org/pf4j/AbstractPluginManager.java65
-rw-r--r--pf4j/src/main/java/org/pf4j/BasePluginRepository.java46
-rw-r--r--pf4j/src/main/java/org/pf4j/DefaultPluginManager.java21
-rw-r--r--pf4j/src/main/java/org/pf4j/DefaultPluginRepository.java31
-rw-r--r--pf4j/src/main/java/org/pf4j/DevelopmentPluginRepository.java10
-rw-r--r--pf4j/src/main/java/org/pf4j/JarPluginManager.java8
-rw-r--r--pf4j/src/main/java/org/pf4j/JarPluginRepository.java10
-rw-r--r--pf4j/src/main/java/org/pf4j/PluginManager.java12
-rw-r--r--pf4j/src/main/java/org/pf4j/ZipPluginManager.java4
-rw-r--r--pf4j/src/test/java/org/pf4j/DefaultPluginRepositoryTest.java59
-rw-r--r--pf4j/src/test/java/org/pf4j/LoadPluginsFromMultipleRootsTest.java75
-rw-r--r--pf4j/src/test/java/org/pf4j/LoadPluginsTest.java6
12 files changed, 258 insertions, 89 deletions
diff --git a/pf4j/src/main/java/org/pf4j/AbstractPluginManager.java b/pf4j/src/main/java/org/pf4j/AbstractPluginManager.java
index 3d109e2..9562257 100644
--- a/pf4j/src/main/java/org/pf4j/AbstractPluginManager.java
+++ b/pf4j/src/main/java/org/pf4j/AbstractPluginManager.java
@@ -25,12 +25,14 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.stream.Collectors;
/**
* This class implements the boilerplate plugin code that any {@link PluginManager}
@@ -51,7 +53,7 @@ public abstract class AbstractPluginManager implements PluginManager {
public static final String DEFAULT_PLUGINS_DIR = "plugins";
public static final String DEVELOPMENT_PLUGINS_DIR = "../plugins";
- protected Path pluginsRoot;
+ protected final List<Path> pluginsRoots = new ArrayList<>();
protected ExtensionFinder extensionFinder;
@@ -109,19 +111,28 @@ public abstract class AbstractPluginManager implements PluginManager {
protected VersionManager versionManager;
/**
- * The plugins root is supplied by {@code System.getProperty("pf4j.pluginsDir", "plugins")}.
+ * The plugins roots are supplied as comma-separated list by {@code System.getProperty("pf4j.pluginsDir", "plugins")}.
*/
public AbstractPluginManager() {
initialize();
}
/**
- * Constructs {@code AbstractPluginManager} with the given plugins root.
+ * Constructs {@code AbstractPluginManager} with the given plugins roots.
*
- * @param pluginsRoot the root to search for plugins
+ * @param pluginsRoots the roots to search for plugins
*/
- public AbstractPluginManager(Path pluginsRoot) {
- this.pluginsRoot = pluginsRoot;
+ public AbstractPluginManager(Path... pluginsRoots) {
+ this(Arrays.asList(pluginsRoots));
+ }
+
+ /**
+ * Constructs {@code AbstractPluginManager} with the given plugins roots.
+ *
+ * @param pluginsRoots the roots to search for plugins
+ */
+ public AbstractPluginManager(List<Path> pluginsRoots) {
+ this.pluginsRoots.addAll(pluginsRoots);
initialize();
}
@@ -200,12 +211,17 @@ public abstract class AbstractPluginManager implements PluginManager {
*/
@Override
public void loadPlugins() {
- log.debug("Lookup plugins in '{}'", pluginsRoot);
- // check for plugins root
- if (Files.notExists(pluginsRoot) || !Files.isDirectory(pluginsRoot)) {
- log.warn("No '{}' root", pluginsRoot);
+ log.debug("Lookup plugins in '{}'", pluginsRoots);
+ // check for plugins roots
+ if (pluginsRoots.isEmpty()) {
+ log.warn("No plugins roots configured");
return;
}
+ pluginsRoots.forEach(path -> {
+ if (Files.notExists(path) || !Files.isDirectory(path)) {
+ log.warn("No '{}' root", path);
+ }
+ });
// get all plugin paths from repository
List<Path> pluginPaths = pluginRepository.getPluginPaths();
@@ -599,8 +615,15 @@ public abstract class AbstractPluginManager implements PluginManager {
return pluginLoader;
}
+ @Override
public Path getPluginsRoot() {
- return pluginsRoot;
+ return pluginsRoots.stream()
+ .findFirst()
+ .orElseThrow(() -> new IllegalStateException("pluginsRoots have not been initialized, yet."));
+ }
+
+ public List<Path> getPluginsRoots() {
+ return Collections.unmodifiableList(pluginsRoots);
}
@Override
@@ -687,8 +710,8 @@ public abstract class AbstractPluginManager implements PluginManager {
pluginStateListeners = new ArrayList<>();
- if (pluginsRoot == null) {
- pluginsRoot = createPluginsRoot();
+ if (pluginsRoots.isEmpty()) {
+ pluginsRoots.addAll(createPluginsRoot());
}
pluginRepository = createPluginRepository();
@@ -704,20 +727,24 @@ public abstract class AbstractPluginManager implements PluginManager {
}
/**
- * Add the possibility to override the plugins root.
- * If a {@link #PLUGINS_DIR_PROPERTY_NAME} system property is defined than this method returns that root.
+ * Add the possibility to override the plugins roots.
+ * If a {@link #PLUGINS_DIR_PROPERTY_NAME} system property is defined than this method returns that roots.
* If {@link #getRuntimeMode()} returns {@link RuntimeMode#DEVELOPMENT} than {@link #DEVELOPMENT_PLUGINS_DIR}
* is returned else this method returns {@link #DEFAULT_PLUGINS_DIR}.
*
* @return the plugins root
*/
- protected Path createPluginsRoot() {
+ protected List<Path> createPluginsRoot() {
String pluginsDir = System.getProperty(PLUGINS_DIR_PROPERTY_NAME);
- if (pluginsDir == null) {
- pluginsDir = isDevelopment() ? DEVELOPMENT_PLUGINS_DIR : DEFAULT_PLUGINS_DIR;
+ if (pluginsDir != null && !pluginsDir.isEmpty()) {
+ return Arrays.stream(pluginsDir.split(","))
+ .map(String::trim)
+ .map(Paths::get)
+ .collect(Collectors.toList());
}
- return Paths.get(pluginsDir);
+ pluginsDir = isDevelopment() ? DEVELOPMENT_PLUGINS_DIR : DEFAULT_PLUGINS_DIR;
+ return Collections.singletonList(Paths.get(pluginsDir));
}
/**
diff --git a/pf4j/src/main/java/org/pf4j/BasePluginRepository.java b/pf4j/src/main/java/org/pf4j/BasePluginRepository.java
index ea5ad3b..9ab8f96 100644
--- a/pf4j/src/main/java/org/pf4j/BasePluginRepository.java
+++ b/pf4j/src/main/java/org/pf4j/BasePluginRepository.java
@@ -22,11 +22,11 @@ import java.io.FileFilter;
import java.io.IOException;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
-import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collections;
import java.util.Comparator;
import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
/**
* @author Decebal Suiu
@@ -34,17 +34,21 @@ import java.util.List;
*/
public class BasePluginRepository implements PluginRepository {
- protected final Path pluginsRoot;
+ protected final List<Path> pluginsRoots;
protected FileFilter filter;
protected Comparator<File> comparator;
- public BasePluginRepository(Path pluginsRoot) {
- this(pluginsRoot, null);
+ public BasePluginRepository(Path... pluginsRoots) {
+ this(Arrays.asList(pluginsRoots));
}
- public BasePluginRepository(Path pluginsRoot, FileFilter filter) {
- this.pluginsRoot = pluginsRoot;
+ public BasePluginRepository(List<Path> pluginsRoots) {
+ this(pluginsRoots, null);
+ }
+
+ public BasePluginRepository(List<Path> pluginsRoots, FileFilter filter) {
+ this.pluginsRoots = pluginsRoots;
this.filter = filter;
// last modified file is first
@@ -67,22 +71,11 @@ public class BasePluginRepository implements PluginRepository {
@Override
public List<Path> getPluginPaths() {
- File[] files = pluginsRoot.toFile().listFiles(filter);
-
- if ((files == null) || files.length == 0) {
- return Collections.emptyList();
- }
-
- if (comparator != null) {
- Arrays.sort(files, comparator);
- }
-
- List<Path> paths = new ArrayList<>(files.length);
- for (File file : files) {
- paths.add(file.toPath());
- }
-
- return paths;
+ return pluginsRoots.stream()
+ .flatMap(path -> streamFiles(path, filter))
+ .sorted(comparator)
+ .map(File::toPath)
+ .collect(Collectors.toList());
}
@Override
@@ -101,4 +94,11 @@ public class BasePluginRepository implements PluginRepository {
}
}
+ protected Stream<File> streamFiles(Path directory, FileFilter filter) {
+ File[] files = directory.toFile().listFiles(filter);
+ return files != null
+ ? Arrays.stream(files)
+ : Stream.empty();
+ }
+
}
diff --git a/pf4j/src/main/java/org/pf4j/DefaultPluginManager.java b/pf4j/src/main/java/org/pf4j/DefaultPluginManager.java
index 9cad187..e2667d4 100644
--- a/pf4j/src/main/java/org/pf4j/DefaultPluginManager.java
+++ b/pf4j/src/main/java/org/pf4j/DefaultPluginManager.java
@@ -21,6 +21,7 @@ import org.slf4j.LoggerFactory;
import java.nio.file.Path;
import java.nio.file.Paths;
+import java.util.List;
/**
* Default implementation of the {@link PluginManager} interface.
@@ -41,8 +42,12 @@ public class DefaultPluginManager extends AbstractPluginManager {
super();
}
- public DefaultPluginManager(Path pluginsRoot) {
- super(pluginsRoot);
+ public DefaultPluginManager(Path... pluginsRoots) {
+ super(pluginsRoots);
+ }
+
+ public DefaultPluginManager(List<Path> pluginsRoots) {
+ super(pluginsRoots);
}
@Override
@@ -73,7 +78,11 @@ public class DefaultPluginManager extends AbstractPluginManager {
@Override
protected PluginStatusProvider createPluginStatusProvider() {
String configDir = System.getProperty(PLUGINS_DIR_CONFIG_PROPERTY_NAME);
- Path configPath = configDir != null ? Paths.get(configDir) : getPluginsRoot();
+ Path configPath = configDir != null
+ ? Paths.get(configDir)
+ : getPluginsRoots().stream()
+ .findFirst()
+ .orElseThrow(() -> new IllegalArgumentException("No pluginsRoot configured"));
return new DefaultPluginStatusProvider(configPath);
}
@@ -81,9 +90,9 @@ public class DefaultPluginManager extends AbstractPluginManager {
@Override
protected PluginRepository createPluginRepository() {
return new CompoundPluginRepository()
- .add(new DevelopmentPluginRepository(getPluginsRoot()), this::isDevelopment)
- .add(new JarPluginRepository(getPluginsRoot()), this::isNotDevelopment)
- .add(new DefaultPluginRepository(getPluginsRoot()), this::isNotDevelopment);
+ .add(new DevelopmentPluginRepository(getPluginsRoots()), this::isDevelopment)
+ .add(new JarPluginRepository(getPluginsRoots()), this::isNotDevelopment)
+ .add(new DefaultPluginRepository(getPluginsRoots()), this::isNotDevelopment);
}
@Override
diff --git a/pf4j/src/main/java/org/pf4j/DefaultPluginRepository.java b/pf4j/src/main/java/org/pf4j/DefaultPluginRepository.java
index 2fafbc7..82a447f 100644
--- a/pf4j/src/main/java/org/pf4j/DefaultPluginRepository.java
+++ b/pf4j/src/main/java/org/pf4j/DefaultPluginRepository.java
@@ -29,6 +29,7 @@ import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.nio.file.Path;
+import java.util.Arrays;
import java.util.List;
/**
@@ -38,8 +39,12 @@ public class DefaultPluginRepository extends BasePluginRepository {
private static final Logger log = LoggerFactory.getLogger(DefaultPluginRepository.class);
- public DefaultPluginRepository(Path pluginsRoot) {
- super(pluginsRoot);
+ public DefaultPluginRepository(Path... pluginsRoots) {
+ this(Arrays.asList(pluginsRoots));
+ }
+
+ public DefaultPluginRepository(List<Path> pluginsRoots) {
+ super(pluginsRoots);
AndFileFilter pluginsFilter = new AndFileFilter(new DirectoryFileFilter());
pluginsFilter.addFileFilter(new NotFileFilter(createHiddenPluginFilter()));
@@ -64,16 +69,18 @@ public class DefaultPluginRepository extends BasePluginRepository {
private void extractZipFiles() {
// expand plugins zip files
- File[] zipFiles = pluginsRoot.toFile().listFiles(new ZipFileFilter());
- if ((zipFiles != null) && zipFiles.length > 0) {
- for (File pluginZip : zipFiles) {
- try {
- FileUtils.expandIfZip(pluginZip.toPath());
- } catch (IOException e) {
- log.error("Cannot expand plugin zip '{}'", pluginZip);
- log.error(e.getMessage(), e);
- }
- }
+ pluginsRoots.stream()
+ .flatMap(path -> streamFiles(path, new ZipFileFilter()))
+ .map(File::toPath)
+ .forEach(this::expandIfZip);
+ }
+
+ private void expandIfZip(Path filePath) {
+ try {
+ FileUtils.expandIfZip(filePath);
+ } catch (IOException e) {
+ log.error("Cannot expand plugin zip '{}'", filePath);
+ log.error(e.getMessage(), e);
}
}
diff --git a/pf4j/src/main/java/org/pf4j/DevelopmentPluginRepository.java b/pf4j/src/main/java/org/pf4j/DevelopmentPluginRepository.java
index e8f2c69..fdc74c9 100644
--- a/pf4j/src/main/java/org/pf4j/DevelopmentPluginRepository.java
+++ b/pf4j/src/main/java/org/pf4j/DevelopmentPluginRepository.java
@@ -24,6 +24,8 @@ import org.pf4j.util.OrFileFilter;
import java.io.FileFilter;
import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.List;
/**
* @author Decebal Suiu
@@ -33,8 +35,12 @@ 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);
+ public DevelopmentPluginRepository(Path... pluginsRoots) {
+ this(Arrays.asList(pluginsRoots));
+ }
+
+ public DevelopmentPluginRepository(List<Path> pluginsRoots) {
+ super(pluginsRoots);
AndFileFilter pluginsFilter = new AndFileFilter(new DirectoryFileFilter());
pluginsFilter.addFileFilter(new NotFileFilter(createHiddenPluginFilter()));
diff --git a/pf4j/src/main/java/org/pf4j/JarPluginManager.java b/pf4j/src/main/java/org/pf4j/JarPluginManager.java
index f280466..ebbc63d 100644
--- a/pf4j/src/main/java/org/pf4j/JarPluginManager.java
+++ b/pf4j/src/main/java/org/pf4j/JarPluginManager.java
@@ -30,8 +30,8 @@ public class JarPluginManager extends DefaultPluginManager {
super();
}
- public JarPluginManager(Path pluginsRoot) {
- super(pluginsRoot);
+ public JarPluginManager(Path... pluginsRoots) {
+ super(pluginsRoots);
}
@Override
@@ -49,8 +49,8 @@ public class JarPluginManager extends DefaultPluginManager {
@Override
protected PluginRepository createPluginRepository() {
return new CompoundPluginRepository()
- .add(new DevelopmentPluginRepository(getPluginsRoot()), this::isDevelopment)
- .add(new JarPluginRepository(getPluginsRoot()), this::isNotDevelopment);
+ .add(new DevelopmentPluginRepository(getPluginsRoots()), this::isDevelopment)
+ .add(new JarPluginRepository(getPluginsRoots()), this::isNotDevelopment);
}
}
diff --git a/pf4j/src/main/java/org/pf4j/JarPluginRepository.java b/pf4j/src/main/java/org/pf4j/JarPluginRepository.java
index a8be3ff..d629bbd 100644
--- a/pf4j/src/main/java/org/pf4j/JarPluginRepository.java
+++ b/pf4j/src/main/java/org/pf4j/JarPluginRepository.java
@@ -18,14 +18,20 @@ package org.pf4j;
import org.pf4j.util.JarFileFilter;
import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.List;
/**
* @author Decebal Suiu
*/
public class JarPluginRepository extends BasePluginRepository {
- public JarPluginRepository(Path pluginsRoot) {
- super(pluginsRoot, new JarFileFilter());
+ public JarPluginRepository(Path... pluginsRoots) {
+ this(Arrays.asList(pluginsRoots));
+ }
+
+ public JarPluginRepository(List<Path> pluginsRoots) {
+ super(pluginsRoots, new JarFileFilter());
}
}
diff --git a/pf4j/src/main/java/org/pf4j/PluginManager.java b/pf4j/src/main/java/org/pf4j/PluginManager.java
index 248b1ac..b717656 100644
--- a/pf4j/src/main/java/org/pf4j/PluginManager.java
+++ b/pf4j/src/main/java/org/pf4j/PluginManager.java
@@ -205,12 +205,22 @@ public interface PluginManager {
String getSystemVersion();
/**
- * Gets the path of the folder where plugins are installed.
+ * Gets the first path of the folders where plugins are installed.
+ *
+ * @deprecated Use {@link #getPluginsRoots()} instead to get all paths where plugins are could be installed.
*
* @return Path of plugins root
*/
+ @Deprecated
Path getPluginsRoot();
+ /**
+ * Gets the a read-only list of all paths of the folders where plugins are installed.
+ *
+ * @return Paths of plugins roots
+ */
+ List<Path> getPluginsRoots();
+
VersionManager getVersionManager();
}
diff --git a/pf4j/src/main/java/org/pf4j/ZipPluginManager.java b/pf4j/src/main/java/org/pf4j/ZipPluginManager.java
index a32d156..a22f3c6 100644
--- a/pf4j/src/main/java/org/pf4j/ZipPluginManager.java
+++ b/pf4j/src/main/java/org/pf4j/ZipPluginManager.java
@@ -42,8 +42,8 @@ public class ZipPluginManager extends DefaultPluginManager {
@Override
protected PluginRepository createPluginRepository() {
return new CompoundPluginRepository()
- .add(new DevelopmentPluginRepository(getPluginsRoot()), this::isDevelopment)
- .add(new DefaultPluginRepository(getPluginsRoot()), this::isNotDevelopment);
+ .add(new DevelopmentPluginRepository(getPluginsRoots()), this::isDevelopment)
+ .add(new DefaultPluginRepository(getPluginsRoots()), this::isNotDevelopment);
}
}
diff --git a/pf4j/src/test/java/org/pf4j/DefaultPluginRepositoryTest.java b/pf4j/src/test/java/org/pf4j/DefaultPluginRepositoryTest.java
index 3e31811..b8ffd7c 100644
--- a/pf4j/src/test/java/org/pf4j/DefaultPluginRepositoryTest.java
+++ b/pf4j/src/test/java/org/pf4j/DefaultPluginRepositoryTest.java
@@ -15,10 +15,11 @@
*/
package org.pf4j;
+import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.io.TempDir;
import org.pf4j.plugin.PluginZip;
+import org.pf4j.util.FileUtils;
import java.io.IOException;
import java.nio.file.Files;
@@ -35,18 +36,40 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
*/
public class DefaultPluginRepositoryTest {
- @TempDir
- Path pluginsPath;
+ Path pluginsPath1;
+ Path pluginsPath2;
@BeforeEach
public void setUp() throws IOException {
- Path plugin1Path = Files.createDirectory(pluginsPath.resolve("plugin-1"));
+ pluginsPath1 = Files.createTempDirectory("junit-pf4j-");
+ pluginsPath2 = Files.createTempDirectory("junit-pf4j-");
+ Path plugin1Path = Files.createDirectory(pluginsPath1.resolve("plugin-1"));
// Prove that we can delete a folder with a file inside
Files.createFile(plugin1Path.resolve("myfile"));
// Create a zip file for plugin-1 to test that it is deleted when plugin is deleted
- new PluginZip.Builder(pluginsPath.resolve("plugin-1.zip"), "plugin-1").pluginVersion("1.0").build();
- Files.createDirectory(pluginsPath.resolve("plugin-2"));
- Files.createDirectory(pluginsPath.resolve("plugin-3"));
+ new PluginZip.Builder(pluginsPath1.resolve("plugin-1.zip"), "plugin-1").pluginVersion("1.0").build();
+ Files.createDirectory(pluginsPath2.resolve("plugin-2"));
+ Files.createDirectory(pluginsPath2.resolve("plugin-3"));
+ }
+
+ @AfterEach
+ public void tearDown() throws IOException {
+ FileUtils.delete(pluginsPath1);
+ FileUtils.delete(pluginsPath2);
+ }
+
+ /**
+ * Test of {@link DefaultPluginRepository#getPluginPaths()} method.
+ */
+ @Test
+ public void testGetPluginArchivesFromSinglePath() {
+ PluginRepository repository = new DefaultPluginRepository(pluginsPath2);
+
+ List<Path> pluginPaths = repository.getPluginPaths();
+
+ assertEquals(2, pluginPaths.size());
+ assertPathExists(pluginPaths, pluginsPath2.resolve("plugin-2"));
+ assertPathExists(pluginPaths, pluginsPath2.resolve("plugin-3"));
}
/**
@@ -54,14 +77,14 @@ public class DefaultPluginRepositoryTest {
*/
@Test
public void testGetPluginArchives() {
- PluginRepository repository = new DefaultPluginRepository(pluginsPath);
+ PluginRepository repository = new DefaultPluginRepository(pluginsPath1, pluginsPath2);
List<Path> pluginPaths = repository.getPluginPaths();
assertEquals(3, pluginPaths.size());
- assertPathExists(pluginPaths, pluginsPath.resolve("plugin-1"));
- assertPathExists(pluginPaths, pluginsPath.resolve("plugin-2"));
- assertPathExists(pluginPaths, pluginsPath.resolve("plugin-3"));
+ assertPathExists(pluginPaths, pluginsPath1.resolve("plugin-1"));
+ assertPathExists(pluginPaths, pluginsPath2.resolve("plugin-2"));
+ assertPathExists(pluginPaths, pluginsPath2.resolve("plugin-3"));
}
/**
@@ -69,18 +92,18 @@ public class DefaultPluginRepositoryTest {
*/
@Test
public void testDeletePluginPath() {
- PluginRepository repository = new DefaultPluginRepository(pluginsPath);
+ PluginRepository repository = new DefaultPluginRepository(pluginsPath1, pluginsPath2);
- 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(Files.exists(pluginsPath1.resolve("plugin-1.zip")));
+ assertTrue(repository.deletePluginPath(pluginsPath1.resolve("plugin-1")));
+ assertFalse(Files.exists(pluginsPath1.resolve("plugin-1.zip")));
+ assertTrue(repository.deletePluginPath(pluginsPath2.resolve("plugin-3")));
+ assertFalse(repository.deletePluginPath(pluginsPath2.resolve("plugin-4")));
List<Path> pluginPaths = repository.getPluginPaths();
assertEquals(1, pluginPaths.size());
- assertEquals(pluginsPath.relativize(pluginPaths.get(0)).toString(), "plugin-2");
+ assertEquals(pluginsPath2.relativize(pluginPaths.get(0)).toString(), "plugin-2");
}
private void assertPathExists(List<Path> paths, Path path) {
diff --git a/pf4j/src/test/java/org/pf4j/LoadPluginsFromMultipleRootsTest.java b/pf4j/src/test/java/org/pf4j/LoadPluginsFromMultipleRootsTest.java
new file mode 100644
index 0000000..2117a62
--- /dev/null
+++ b/pf4j/src/test/java/org/pf4j/LoadPluginsFromMultipleRootsTest.java
@@ -0,0 +1,75 @@
+/*
+ * 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.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.pf4j.plugin.PluginZip;
+import org.pf4j.util.FileUtils;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+public class LoadPluginsFromMultipleRootsTest {
+
+ private DefaultPluginManager pluginManager;
+
+ Path pluginsPath1;
+ Path pluginsPath2;
+
+ @BeforeEach
+ public void setUp() throws IOException {
+ pluginsPath1 = Files.createTempDirectory("junit-pf4j-");
+ pluginsPath2 = Files.createTempDirectory("junit-pf4j-");
+ pluginManager = new DefaultPluginManager(pluginsPath1, pluginsPath2);
+ }
+
+ @AfterEach
+ public void tearDown() throws IOException {
+ FileUtils.delete(pluginsPath1);
+ FileUtils.delete(pluginsPath2);
+ }
+
+ @Test
+ public void load() throws Exception {
+ PluginZip pluginZip1 = new PluginZip.Builder(pluginsPath1.resolve("my-plugin-1.2.3.zip"), "myPlugin")
+ .pluginVersion("1.2.3")
+ .build();
+
+ PluginZip pluginZip2 = new PluginZip.Builder(pluginsPath2.resolve("my-other-plugin-4.5.6.zip"), "myOtherPlugin")
+ .pluginVersion("4.5.6")
+ .build();
+
+ assertTrue(Files.exists(pluginZip1.path()));
+ assertEquals(0, pluginManager.getPlugins().size());
+
+ pluginManager.loadPlugins();
+
+ assertTrue(Files.exists(pluginZip1.path()));
+ assertTrue(Files.exists(pluginZip1.unzippedPath()));
+ assertTrue(Files.exists(pluginZip2.path()));
+ assertTrue(Files.exists(pluginZip2.unzippedPath()));
+ assertEquals(2, pluginManager.getPlugins().size());
+ assertEquals(pluginZip1.pluginId(), pluginManager.idForPath(pluginZip1.unzippedPath()));
+ assertEquals(pluginZip2.pluginId(), pluginManager.idForPath(pluginZip2.unzippedPath()));
+ }
+
+}
diff --git a/pf4j/src/test/java/org/pf4j/LoadPluginsTest.java b/pf4j/src/test/java/org/pf4j/LoadPluginsTest.java
index e3dac02..ef2376b 100644
--- a/pf4j/src/test/java/org/pf4j/LoadPluginsTest.java
+++ b/pf4j/src/test/java/org/pf4j/LoadPluginsTest.java
@@ -23,6 +23,7 @@ import org.pf4j.plugin.PluginZip;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
+import java.util.Collections;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.equalTo;
@@ -201,6 +202,11 @@ public class LoadPluginsTest {
}
@Test
+ public void getRoots() {
+ assertEquals(Collections.singletonList(pluginsPath), pluginManager.getPluginsRoots());
+ }
+
+ @Test
public void notAPlugin() {
pluginsPath.resolve("not-a-zip");