Browse Source

Support multiple plugin root directories (#404)

pull/412/head
rreich 4 years ago committed by GitHub
parent
commit
f6ede83be3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 65
      pf4j/src/main/java/org/pf4j/AbstractPluginManager.java
  2. 46
      pf4j/src/main/java/org/pf4j/BasePluginRepository.java
  3. 21
      pf4j/src/main/java/org/pf4j/DefaultPluginManager.java
  4. 25
      pf4j/src/main/java/org/pf4j/DefaultPluginRepository.java
  5. 10
      pf4j/src/main/java/org/pf4j/DevelopmentPluginRepository.java
  6. 8
      pf4j/src/main/java/org/pf4j/JarPluginManager.java
  7. 10
      pf4j/src/main/java/org/pf4j/JarPluginRepository.java
  8. 12
      pf4j/src/main/java/org/pf4j/PluginManager.java
  9. 4
      pf4j/src/main/java/org/pf4j/ZipPluginManager.java
  10. 59
      pf4j/src/test/java/org/pf4j/DefaultPluginRepositoryTest.java
  11. 75
      pf4j/src/test/java/org/pf4j/LoadPluginsFromMultipleRootsTest.java
  12. 6
      pf4j/src/test/java/org/pf4j/LoadPluginsTest.java

65
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.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors;
/** /**
* This class implements the boilerplate plugin code that any {@link PluginManager} * 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 DEFAULT_PLUGINS_DIR = "plugins";
public static final String DEVELOPMENT_PLUGINS_DIR = "../plugins"; public static final String DEVELOPMENT_PLUGINS_DIR = "../plugins";
protected Path pluginsRoot; protected final List<Path> pluginsRoots = new ArrayList<>();
protected ExtensionFinder extensionFinder; protected ExtensionFinder extensionFinder;
@ -109,19 +111,28 @@ public abstract class AbstractPluginManager implements PluginManager {
protected VersionManager versionManager; 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() { public AbstractPluginManager() {
initialize(); 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) { public AbstractPluginManager(Path... pluginsRoots) {
this.pluginsRoot = pluginsRoot; 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(); initialize();
} }
@ -200,12 +211,17 @@ public abstract class AbstractPluginManager implements PluginManager {
*/ */
@Override @Override
public void loadPlugins() { public void loadPlugins() {
log.debug("Lookup plugins in '{}'", pluginsRoot); log.debug("Lookup plugins in '{}'", pluginsRoots);
// check for plugins root // check for plugins roots
if (Files.notExists(pluginsRoot) || !Files.isDirectory(pluginsRoot)) { if (pluginsRoots.isEmpty()) {
log.warn("No '{}' root", pluginsRoot); log.warn("No plugins roots configured");
return; return;
} }
pluginsRoots.forEach(path -> {
if (Files.notExists(path) || !Files.isDirectory(path)) {
log.warn("No '{}' root", path);
}
});
// get all plugin paths from repository // get all plugin paths from repository
List<Path> pluginPaths = pluginRepository.getPluginPaths(); List<Path> pluginPaths = pluginRepository.getPluginPaths();
@ -599,8 +615,15 @@ public abstract class AbstractPluginManager implements PluginManager {
return pluginLoader; return pluginLoader;
} }
@Override
public Path getPluginsRoot() { 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 @Override
@ -687,8 +710,8 @@ public abstract class AbstractPluginManager implements PluginManager {
pluginStateListeners = new ArrayList<>(); pluginStateListeners = new ArrayList<>();
if (pluginsRoot == null) { if (pluginsRoots.isEmpty()) {
pluginsRoot = createPluginsRoot(); pluginsRoots.addAll(createPluginsRoot());
} }
pluginRepository = createPluginRepository(); pluginRepository = createPluginRepository();
@ -704,20 +727,24 @@ public abstract class AbstractPluginManager implements PluginManager {
} }
/** /**
* Add the possibility to override the plugins 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 root. * 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} * If {@link #getRuntimeMode()} returns {@link RuntimeMode#DEVELOPMENT} than {@link #DEVELOPMENT_PLUGINS_DIR}
* is returned else this method returns {@link #DEFAULT_PLUGINS_DIR}. * is returned else this method returns {@link #DEFAULT_PLUGINS_DIR}.
* *
* @return the plugins root * @return the plugins root
*/ */
protected Path createPluginsRoot() { protected List<Path> createPluginsRoot() {
String pluginsDir = System.getProperty(PLUGINS_DIR_PROPERTY_NAME); String pluginsDir = System.getProperty(PLUGINS_DIR_PROPERTY_NAME);
if (pluginsDir == null) { if (pluginsDir != null && !pluginsDir.isEmpty()) {
pluginsDir = isDevelopment() ? DEVELOPMENT_PLUGINS_DIR : DEFAULT_PLUGINS_DIR; 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));
} }
/** /**

46
pf4j/src/main/java/org/pf4j/BasePluginRepository.java

@ -22,11 +22,11 @@ import java.io.FileFilter;
import java.io.IOException; import java.io.IOException;
import java.nio.file.NoSuchFileException; import java.nio.file.NoSuchFileException;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/** /**
* @author Decebal Suiu * @author Decebal Suiu
@ -34,17 +34,21 @@ import java.util.List;
*/ */
public class BasePluginRepository implements PluginRepository { public class BasePluginRepository implements PluginRepository {
protected final Path pluginsRoot; protected final List<Path> pluginsRoots;
protected FileFilter filter; protected FileFilter filter;
protected Comparator<File> comparator; protected Comparator<File> comparator;
public BasePluginRepository(Path pluginsRoot) { public BasePluginRepository(Path... pluginsRoots) {
this(pluginsRoot, null); this(Arrays.asList(pluginsRoots));
} }
public BasePluginRepository(Path pluginsRoot, FileFilter filter) { public BasePluginRepository(List<Path> pluginsRoots) {
this.pluginsRoot = pluginsRoot; this(pluginsRoots, null);
}
public BasePluginRepository(List<Path> pluginsRoots, FileFilter filter) {
this.pluginsRoots = pluginsRoots;
this.filter = filter; this.filter = filter;
// last modified file is first // last modified file is first
@ -67,22 +71,11 @@ public class BasePluginRepository implements PluginRepository {
@Override @Override
public List<Path> getPluginPaths() { public List<Path> getPluginPaths() {
File[] files = pluginsRoot.toFile().listFiles(filter); return pluginsRoots.stream()
.flatMap(path -> streamFiles(path, filter))
if ((files == null) || files.length == 0) { .sorted(comparator)
return Collections.emptyList(); .map(File::toPath)
} .collect(Collectors.toList());
if (comparator != null) {
Arrays.sort(files, comparator);
}
List<Path> paths = new ArrayList<>(files.length);
for (File file : files) {
paths.add(file.toPath());
}
return paths;
} }
@Override @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();
}
} }

21
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.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.List;
/** /**
* Default implementation of the {@link PluginManager} interface. * Default implementation of the {@link PluginManager} interface.
@ -41,8 +42,12 @@ public class DefaultPluginManager extends AbstractPluginManager {
super(); super();
} }
public DefaultPluginManager(Path pluginsRoot) { public DefaultPluginManager(Path... pluginsRoots) {
super(pluginsRoot); super(pluginsRoots);
}
public DefaultPluginManager(List<Path> pluginsRoots) {
super(pluginsRoots);
} }
@Override @Override
@ -73,7 +78,11 @@ public class DefaultPluginManager extends AbstractPluginManager {
@Override @Override
protected PluginStatusProvider createPluginStatusProvider() { protected PluginStatusProvider createPluginStatusProvider() {
String configDir = System.getProperty(PLUGINS_DIR_CONFIG_PROPERTY_NAME); 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); return new DefaultPluginStatusProvider(configPath);
} }
@ -81,9 +90,9 @@ public class DefaultPluginManager extends AbstractPluginManager {
@Override @Override
protected PluginRepository createPluginRepository() { protected PluginRepository createPluginRepository() {
return new CompoundPluginRepository() return new CompoundPluginRepository()
.add(new DevelopmentPluginRepository(getPluginsRoot()), this::isDevelopment) .add(new DevelopmentPluginRepository(getPluginsRoots()), this::isDevelopment)
.add(new JarPluginRepository(getPluginsRoot()), this::isNotDevelopment) .add(new JarPluginRepository(getPluginsRoots()), this::isNotDevelopment)
.add(new DefaultPluginRepository(getPluginsRoot()), this::isNotDevelopment); .add(new DefaultPluginRepository(getPluginsRoots()), this::isNotDevelopment);
} }
@Override @Override

25
pf4j/src/main/java/org/pf4j/DefaultPluginRepository.java

@ -29,6 +29,7 @@ import java.io.File;
import java.io.FileFilter; import java.io.FileFilter;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.Arrays;
import java.util.List; import java.util.List;
/** /**
@ -38,8 +39,12 @@ public class DefaultPluginRepository extends BasePluginRepository {
private static final Logger log = LoggerFactory.getLogger(DefaultPluginRepository.class); private static final Logger log = LoggerFactory.getLogger(DefaultPluginRepository.class);
public DefaultPluginRepository(Path pluginsRoot) { public DefaultPluginRepository(Path... pluginsRoots) {
super(pluginsRoot); this(Arrays.asList(pluginsRoots));
}
public DefaultPluginRepository(List<Path> pluginsRoots) {
super(pluginsRoots);
AndFileFilter pluginsFilter = new AndFileFilter(new DirectoryFileFilter()); AndFileFilter pluginsFilter = new AndFileFilter(new DirectoryFileFilter());
pluginsFilter.addFileFilter(new NotFileFilter(createHiddenPluginFilter())); pluginsFilter.addFileFilter(new NotFileFilter(createHiddenPluginFilter()));
@ -64,17 +69,19 @@ public class DefaultPluginRepository extends BasePluginRepository {
private void extractZipFiles() { private void extractZipFiles() {
// expand plugins zip files // expand plugins zip files
File[] zipFiles = pluginsRoot.toFile().listFiles(new ZipFileFilter()); pluginsRoots.stream()
if ((zipFiles != null) && zipFiles.length > 0) { .flatMap(path -> streamFiles(path, new ZipFileFilter()))
for (File pluginZip : zipFiles) { .map(File::toPath)
.forEach(this::expandIfZip);
}
private void expandIfZip(Path filePath) {
try { try {
FileUtils.expandIfZip(pluginZip.toPath()); FileUtils.expandIfZip(filePath);
} catch (IOException e) { } catch (IOException e) {
log.error("Cannot expand plugin zip '{}'", pluginZip); log.error("Cannot expand plugin zip '{}'", filePath);
log.error(e.getMessage(), e); log.error(e.getMessage(), e);
} }
} }
}
}
} }

10
pf4j/src/main/java/org/pf4j/DevelopmentPluginRepository.java

@ -24,6 +24,8 @@ import org.pf4j.util.OrFileFilter;
import java.io.FileFilter; import java.io.FileFilter;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.Arrays;
import java.util.List;
/** /**
* @author Decebal Suiu * @author Decebal Suiu
@ -33,8 +35,12 @@ public class DevelopmentPluginRepository extends BasePluginRepository {
public static final String MAVEN_BUILD_DIR = "target"; public static final String MAVEN_BUILD_DIR = "target";
public static final String GRADLE_BUILD_DIR = "build"; public static final String GRADLE_BUILD_DIR = "build";
public DevelopmentPluginRepository(Path pluginsRoot) { public DevelopmentPluginRepository(Path... pluginsRoots) {
super(pluginsRoot); this(Arrays.asList(pluginsRoots));
}
public DevelopmentPluginRepository(List<Path> pluginsRoots) {
super(pluginsRoots);
AndFileFilter pluginsFilter = new AndFileFilter(new DirectoryFileFilter()); AndFileFilter pluginsFilter = new AndFileFilter(new DirectoryFileFilter());
pluginsFilter.addFileFilter(new NotFileFilter(createHiddenPluginFilter())); pluginsFilter.addFileFilter(new NotFileFilter(createHiddenPluginFilter()));

8
pf4j/src/main/java/org/pf4j/JarPluginManager.java

@ -30,8 +30,8 @@ public class JarPluginManager extends DefaultPluginManager {
super(); super();
} }
public JarPluginManager(Path pluginsRoot) { public JarPluginManager(Path... pluginsRoots) {
super(pluginsRoot); super(pluginsRoots);
} }
@Override @Override
@ -49,8 +49,8 @@ public class JarPluginManager extends DefaultPluginManager {
@Override @Override
protected PluginRepository createPluginRepository() { protected PluginRepository createPluginRepository() {
return new CompoundPluginRepository() return new CompoundPluginRepository()
.add(new DevelopmentPluginRepository(getPluginsRoot()), this::isDevelopment) .add(new DevelopmentPluginRepository(getPluginsRoots()), this::isDevelopment)
.add(new JarPluginRepository(getPluginsRoot()), this::isNotDevelopment); .add(new JarPluginRepository(getPluginsRoots()), this::isNotDevelopment);
} }
} }

10
pf4j/src/main/java/org/pf4j/JarPluginRepository.java

@ -18,14 +18,20 @@ package org.pf4j;
import org.pf4j.util.JarFileFilter; import org.pf4j.util.JarFileFilter;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.Arrays;
import java.util.List;
/** /**
* @author Decebal Suiu * @author Decebal Suiu
*/ */
public class JarPluginRepository extends BasePluginRepository { public class JarPluginRepository extends BasePluginRepository {
public JarPluginRepository(Path pluginsRoot) { public JarPluginRepository(Path... pluginsRoots) {
super(pluginsRoot, new JarFileFilter()); this(Arrays.asList(pluginsRoots));
}
public JarPluginRepository(List<Path> pluginsRoots) {
super(pluginsRoots, new JarFileFilter());
} }
} }

12
pf4j/src/main/java/org/pf4j/PluginManager.java

@ -205,12 +205,22 @@ public interface PluginManager {
String getSystemVersion(); 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 * @return Path of plugins root
*/ */
@Deprecated
Path getPluginsRoot(); 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(); VersionManager getVersionManager();
} }

4
pf4j/src/main/java/org/pf4j/ZipPluginManager.java

@ -42,8 +42,8 @@ public class ZipPluginManager extends DefaultPluginManager {
@Override @Override
protected PluginRepository createPluginRepository() { protected PluginRepository createPluginRepository() {
return new CompoundPluginRepository() return new CompoundPluginRepository()
.add(new DevelopmentPluginRepository(getPluginsRoot()), this::isDevelopment) .add(new DevelopmentPluginRepository(getPluginsRoots()), this::isDevelopment)
.add(new DefaultPluginRepository(getPluginsRoot()), this::isNotDevelopment); .add(new DefaultPluginRepository(getPluginsRoots()), this::isNotDevelopment);
} }
} }

59
pf4j/src/test/java/org/pf4j/DefaultPluginRepositoryTest.java

@ -15,10 +15,11 @@
*/ */
package org.pf4j; package org.pf4j;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import org.pf4j.plugin.PluginZip; import org.pf4j.plugin.PluginZip;
import org.pf4j.util.FileUtils;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
@ -35,18 +36,40 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
*/ */
public class DefaultPluginRepositoryTest { public class DefaultPluginRepositoryTest {
@TempDir Path pluginsPath1;
Path pluginsPath; Path pluginsPath2;
@BeforeEach @BeforeEach
public void setUp() throws IOException { 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 // Prove that we can delete a folder with a file inside
Files.createFile(plugin1Path.resolve("myfile")); Files.createFile(plugin1Path.resolve("myfile"));
// Create a zip file for plugin-1 to test that it is deleted when plugin is deleted // 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(); new PluginZip.Builder(pluginsPath1.resolve("plugin-1.zip"), "plugin-1").pluginVersion("1.0").build();
Files.createDirectory(pluginsPath.resolve("plugin-2")); Files.createDirectory(pluginsPath2.resolve("plugin-2"));
Files.createDirectory(pluginsPath.resolve("plugin-3")); 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 @Test
public void testGetPluginArchives() { public void testGetPluginArchives() {
PluginRepository repository = new DefaultPluginRepository(pluginsPath); PluginRepository repository = new DefaultPluginRepository(pluginsPath1, pluginsPath2);
List<Path> pluginPaths = repository.getPluginPaths(); List<Path> pluginPaths = repository.getPluginPaths();
assertEquals(3, pluginPaths.size()); assertEquals(3, pluginPaths.size());
assertPathExists(pluginPaths, pluginsPath.resolve("plugin-1")); assertPathExists(pluginPaths, pluginsPath1.resolve("plugin-1"));
assertPathExists(pluginPaths, pluginsPath.resolve("plugin-2")); assertPathExists(pluginPaths, pluginsPath2.resolve("plugin-2"));
assertPathExists(pluginPaths, pluginsPath.resolve("plugin-3")); assertPathExists(pluginPaths, pluginsPath2.resolve("plugin-3"));
} }
/** /**
@ -69,18 +92,18 @@ public class DefaultPluginRepositoryTest {
*/ */
@Test @Test
public void testDeletePluginPath() { public void testDeletePluginPath() {
PluginRepository repository = new DefaultPluginRepository(pluginsPath); PluginRepository repository = new DefaultPluginRepository(pluginsPath1, pluginsPath2);
assertTrue(Files.exists(pluginsPath.resolve("plugin-1.zip"))); assertTrue(Files.exists(pluginsPath1.resolve("plugin-1.zip")));
assertTrue(repository.deletePluginPath(pluginsPath.resolve("plugin-1"))); assertTrue(repository.deletePluginPath(pluginsPath1.resolve("plugin-1")));
assertFalse(Files.exists(pluginsPath.resolve("plugin-1.zip"))); assertFalse(Files.exists(pluginsPath1.resolve("plugin-1.zip")));
assertTrue(repository.deletePluginPath(pluginsPath.resolve("plugin-3"))); assertTrue(repository.deletePluginPath(pluginsPath2.resolve("plugin-3")));
assertFalse(repository.deletePluginPath(pluginsPath.resolve("plugin-4"))); assertFalse(repository.deletePluginPath(pluginsPath2.resolve("plugin-4")));
List<Path> pluginPaths = repository.getPluginPaths(); List<Path> pluginPaths = repository.getPluginPaths();
assertEquals(1, pluginPaths.size()); 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) { private void assertPathExists(List<Path> paths, Path path) {

75
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()));
}
}

6
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.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.Collections;
import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.equalTo;
@ -200,6 +201,11 @@ public class LoadPluginsTest {
assertEquals(pluginsPath, pluginManager.getPluginsRoot()); assertEquals(pluginsPath, pluginManager.getPluginsRoot());
} }
@Test
public void getRoots() {
assertEquals(Collections.singletonList(pluginsPath), pluginManager.getPluginsRoots());
}
@Test @Test
public void notAPlugin() { public void notAPlugin() {
pluginsPath.resolve("not-a-zip"); pluginsPath.resolve("not-a-zip");

Loading…
Cancel
Save