}
pluginsDir = isDevelopment() ? DEVELOPMENT_PLUGINS_DIR : DEFAULT_PLUGINS_DIR;
- return Collections.singletonList(Paths.get(pluginsDir));
+ Path pluginsPath = getFileSystem().getPath(pluginsDir);
+
+ return Collections.singletonList(pluginsPath);
}
/**
import org.slf4j.LoggerFactory;
import java.nio.file.Path;
-import java.nio.file.Paths;
import java.util.List;
/**
protected PluginStatusProvider createPluginStatusProvider() {
String configDir = System.getProperty(PLUGINS_DIR_CONFIG_PROPERTY_NAME);
Path configPath = configDir != null
- ? Paths.get(configDir)
+ ? getFileSystem().getPath(configDir)
: getPluginsRoots().stream()
.findFirst()
.orElseThrow(() -> new IllegalArgumentException("No pluginsRoot configured"));
*/
package org.pf4j;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.util.List;
import java.util.Set;
VersionManager getVersionManager();
+ /**
+ * Returns the {@link FileSystem} used to deal with {@link Path}.
+ * By default, it's used {@link FileSystems#getDefault()}.
+ */
+ default FileSystem getFileSystem() {
+ return FileSystems.getDefault();
+ }
+
}
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
-import java.nio.file.Paths;
import java.util.Properties;
/**
throw new PluginRuntimeException("Cannot find the properties path");
}
+ log.debug("Lookup plugin descriptor in '{}'", propertiesPath);
+ if (Files.notExists(propertiesPath)) {
+ throw new PluginRuntimeException("Cannot find '{}' path", propertiesPath);
+ }
+
Properties properties = new Properties();
- try {
- log.debug("Lookup plugin descriptor in '{}'", propertiesPath);
- if (Files.notExists(propertiesPath)) {
- throw new PluginRuntimeException("Cannot find '{}' path", propertiesPath);
- }
-
- try (InputStream input = Files.newInputStream(propertiesPath)) {
- properties.load(input);
- } catch (IOException e) {
- throw new PluginRuntimeException(e);
- }
- } finally {
- FileUtils.closePath(propertiesPath);
+
+ try (InputStream input = Files.newInputStream(propertiesPath)) {
+ properties.load(input);
+ } catch (IOException e) {
+ throw new PluginRuntimeException(e);
}
return properties;
}
protected Path getPropertiesPath(Path pluginPath, String propertiesFileName) {
- if (Files.isDirectory(pluginPath)) {
- return pluginPath.resolve(Paths.get(propertiesFileName));
- }
-
- // it's a zip or jar file
- try {
- return FileUtils.getPath(pluginPath, propertiesFileName);
- } catch (IOException e) {
- throw new PluginRuntimeException(e);
- }
+ return pluginPath.resolve(propertiesFileName);
}
protected PluginDescriptor createPluginDescriptor(Properties properties) {
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
-import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.Collections;
Path extensionPath;
if (url.toURI().getScheme().equals("jar")) {
- extensionPath = FileUtils.getPath(url.toURI(), EXTENSIONS_RESOURCE);
+ extensionPath = FileUtils.getPath(url.toURI(), pluginManager.getFileSystem()).resolve(EXTENSIONS_RESOURCE);
} else {
- extensionPath = Paths.get(url.toURI());
+ extensionPath = pluginManager.getFileSystem().getPath(url.getPath());
}
- try {
- bucket.addAll(readExtensions(extensionPath));
- } finally {
- FileUtils.closePath(extensionPath);
- }
+ bucket.addAll(readExtensions(extensionPath));
}
private Set<String> readExtensions(Path extensionPath) throws IOException {
import java.nio.charset.StandardCharsets;
import java.nio.file.FileSystem;
import java.nio.file.FileSystemNotFoundException;
-import java.nio.file.FileSystems;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.FileTime;
+import java.nio.file.spi.FileSystemProvider;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
String directoryName = fileName.substring(0, fileName.lastIndexOf("."));
Path pluginDirectory = filePath.resolveSibling(directoryName);
- if (!Files.exists(pluginDirectory) || pluginZipDate.compareTo(Files.getLastModifiedTime(pluginDirectory)) > 0) {
+ if (Files.notExists(pluginDirectory) || pluginZipDate.compareTo(Files.getLastModifiedTime(pluginDirectory)) > 0) {
// expand '.zip' file
Unzip unzip = new Unzip();
unzip.setSource(filePath);
return isZipFile(path) || isJarFile(path);
}
- public static Path getPath(Path path, String first, String... more) throws IOException {
- URI uri = path.toUri();
- if (isZipOrJarFile(path)) {
- String pathString = path.toAbsolutePath().toString();
- // transformation for Windows OS
- pathString = StringUtils.addStart(pathString.replace("\\", "/"), "/");
- // space is replaced with %20
- pathString = pathString.replace(" ","%20");
- uri = URI.create("jar:file:" + pathString);
- }
-
- return getPath(uri, first, more);
- }
-
- public static Path getPath(URI uri, String first, String... more) throws IOException {
- return getFileSystem(uri).getPath(first, more);
- }
-
- /**
- * Quietly close a path.
- */
- public static void closePath(Path path) {
- if (path != null) {
- try {
- path.getFileSystem().close();
- } catch (Exception e) {
- // close silently
- }
- }
- }
-
public static Stream<Path> findPaths(Path path, PathFilter filter) {
return findPaths(path, Integer.MAX_VALUE, filter);
}
}
}
- private static FileSystem getFileSystem(URI uri) throws IOException {
- try {
- return FileSystems.getFileSystem(uri);
- } catch (FileSystemNotFoundException e) {
- return FileSystems.newFileSystem(uri, Collections.<String, String>emptyMap());
+ public static Path getPath(URI uri, FileSystem fileSystem) {
+ String scheme = uri.getScheme();
+ if (scheme == null) {
+ throw new IllegalArgumentException("Missing scheme");
+ }
+
+ // check for default provider to avoid loading of installed providers
+ if (scheme.equalsIgnoreCase("file")) {
+ return fileSystem.provider().getPath(uri);
}
+
+ // try to find provider
+ for (FileSystemProvider provider: FileSystemProvider.installedProviders()) {
+ if (provider.getScheme().equalsIgnoreCase(scheme)) {
+ return provider.getPath(uri);
+ }
+ }
+
+ throw new FileSystemNotFoundException("Provider '" + scheme + "' not installed");
}
}
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import org.pf4j.test.PluginJar;
-import org.pf4j.test.PluginZip;
+import org.pf4j.test.PluginManifest;
+import org.pf4j.test.PluginProperties;
import org.pf4j.test.TestPlugin;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
-import java.util.LinkedHashMap;
-import java.util.Map;
+import java.util.Arrays;
import java.util.Properties;
import static org.junit.jupiter.api.Assertions.assertEquals;
@Test
void find() throws Exception {
Path pluginPath = Files.createDirectories(pluginsPath.resolve("test-plugin-1"));
- storePropertiesToPath(getPlugin1Properties(), pluginPath);
+ storePropertiesToPath(createPropertiesPlugin1(), pluginPath);
PluginDescriptorFinder descriptorFinder = new CompoundPluginDescriptorFinder()
.add(new PropertiesPluginDescriptorFinder());
PluginDescriptorFinder descriptorFinder = new CompoundPluginDescriptorFinder()
.add(new ManifestPluginDescriptorFinder());
- PluginJar pluginJar = new PluginJar.Builder(pluginsPath.resolve("my-plugin-1.2.3.jar"), "myPlugin")
+ PluginManifest pluginManifest = new PluginManifest.Builder("myPlugin")
.pluginClass(TestPlugin.class.getName())
.pluginVersion("1.2.3")
.build();
+ PluginJar pluginJar = new PluginJar.Builder(pluginsPath.resolve("my-plugin-1.2.3.jar"), pluginManifest)
+ .build();
PluginDescriptor pluginDescriptor = descriptorFinder.find(pluginJar.path());
assertNotNull(pluginDescriptor);
PluginDescriptorFinder descriptorFinder = new CompoundPluginDescriptorFinder()
.add(new ManifestPluginDescriptorFinder());
- PluginJar pluginJar = new PluginJar.Builder(pluginsPath.resolve("my plugin-1.2.3.jar"), "myPlugin")
+ PluginManifest pluginManifest = new PluginManifest.Builder("myPlugin")
.pluginVersion("1.2.3")
.build();
+ PluginJar pluginJar = new PluginJar.Builder(pluginsPath.resolve("my plugin-1.2.3.jar"), pluginManifest)
+ .build();
PluginDescriptor pluginDescriptor = descriptorFinder.find(pluginJar.path());
assertNotNull(pluginDescriptor);
}
- private Properties getPlugin1Properties() {
- Map<String, String> map = new LinkedHashMap<>(7);
- map.put(PropertiesPluginDescriptorFinder.PLUGIN_ID, "test-plugin-1");
- map.put(PropertiesPluginDescriptorFinder.PLUGIN_CLASS, TestPlugin.class.getName());
- map.put(PropertiesPluginDescriptorFinder.PLUGIN_VERSION, "0.0.1");
- map.put(PropertiesPluginDescriptorFinder.PLUGIN_PROVIDER, "Decebal Suiu");
- map.put(PropertiesPluginDescriptorFinder.PLUGIN_DEPENDENCIES, "test-plugin-2,test-plugin-3@~1.0");
- map.put(PropertiesPluginDescriptorFinder.PLUGIN_REQUIRES, ">=1");
- map.put(PropertiesPluginDescriptorFinder.PLUGIN_LICENSE, "Apache-2.0");
-
- return PluginZip.createProperties(map);
+ private Properties createPropertiesPlugin1() {
+ return new PluginProperties.Builder("test-plugin-1")
+ .pluginClass(TestPlugin.class.getName())
+ .pluginVersion("0.0.1")
+ .pluginProvider("Decebal Suiu")
+ .pluginDependencies(Arrays.asList("test-plugin-2", "test-plugin-3@~1.0"))
+ .pluginRequires(">=1")
+ .pluginLicense("Apache-2.0")
+ .build()
+ .properties();
}
private void storePropertiesToPath(Properties properties, Path pluginPath) throws IOException {
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import org.pf4j.test.PluginJar;
+import org.pf4j.test.PluginManifest;
+import org.pf4j.test.PluginProperties;
import org.pf4j.test.PluginZip;
import java.io.IOException;
*/
@Test
void pluginDisabledNoStart() throws IOException {
- new PluginZip.Builder(pluginsPath.resolve("my-plugin-1.2.3.zip"), "myPlugin")
- .pluginVersion("1.2.3")
+ PluginProperties pluginProperties = createPluginProperties();
+ new PluginZip.Builder(pluginsPath.resolve("my-plugin-1.2.3.zip"), pluginProperties)
.build();
final PluginStatusProvider statusProvider = mock(PluginStatusProvider.class);
}
@Test
- void deleteZipPlugin() throws Exception {
- PluginZip pluginZip = new PluginZip.Builder(pluginsPath.resolve("my-plugin-1.2.3.zip"), "myPlugin")
- .pluginVersion("1.2.3")
+ void deleteZipPlugin() throws IOException {
+ PluginProperties pluginProperties = createPluginProperties();
+ PluginZip pluginZip = new PluginZip.Builder(pluginsPath.resolve("my-plugin-1.2.3.zip"), pluginProperties)
.build();
pluginManager.loadPlugin(pluginZip.path());
}
@Test
- void deleteJarPlugin() throws Exception {
- PluginJar pluginJar = new PluginJar.Builder(pluginsPath.resolve("my-plugin-1.2.3.jar"), "myPlugin")
- .pluginVersion("1.2.3")
+ void deleteJarPlugin() throws IOException {
+ PluginManifest pluginManifest = createPluginManifest();
+ PluginJar pluginJar = new PluginJar.Builder(pluginsPath.resolve("my-plugin-1.2.3.jar"), pluginManifest)
.build();
pluginManager.loadPlugin(pluginJar.path());
assertFalse(Files.exists(pluginJar.path()));
}
+ private PluginProperties createPluginProperties() {
+ return new PluginProperties.Builder("myPlugin")
+ .pluginVersion("1.2.3")
+ .build();
+ }
+
+ private PluginManifest createPluginManifest() {
+ return new PluginManifest.Builder("myPlugin")
+ .pluginVersion("1.2.3")
+ .build();
+ }
+
}
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
+import org.pf4j.test.PluginProperties;
import org.pf4j.test.PluginZip;
import org.pf4j.util.FileUtils;
// 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(pluginsPath1.resolve("plugin-1.zip"), "plugin-1").pluginVersion("1.0").build();
+ PluginProperties pluginProperties = new PluginProperties.Builder("plugin-1")
+ .pluginVersion("1.0")
+ .build();
+ new PluginZip.Builder(pluginsPath1.resolve("plugin-1.zip"), pluginProperties)
+ .build();
Files.createDirectory(pluginsPath2.resolve("plugin-2"));
Files.createDirectory(pluginsPath2.resolve("plugin-3"));
}
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import org.pf4j.test.PluginJar;
+import org.pf4j.test.PluginManifest;
import org.pf4j.test.TestExtension;
import org.pf4j.test.TestExtensionPoint;
import org.pf4j.test.TestPlugin;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
-public class JarPluginManagerTest {
+class JarPluginManagerTest {
private PluginJar pluginJar;
private JarPluginManager pluginManager;
@BeforeEach
void setUp() throws IOException {
- pluginJar = new PluginJar.Builder(pluginsPath.resolve("test-plugin.jar"), "test-plugin")
+ PluginManifest pluginManifest = new PluginManifest.Builder("test-plugin")
.pluginClass(TestPlugin.class.getName())
.pluginVersion("1.2.3")
+ .build();
+ pluginJar = new PluginJar.Builder(pluginsPath.resolve("test-plugin.jar"), pluginManifest)
.extension(TestExtension.class.getName())
.build();
}
@Test
- void unloadPlugin() throws Exception {
+ void unloadPlugin() {
pluginManager.loadPlugins();
assertEquals(1, pluginManager.getPlugins().size());
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.io.TempDir;
import org.pf4j.test.PluginJar;
+import org.pf4j.test.PluginManifest;
import org.pf4j.test.TestExtension;
import org.pf4j.test.TestPlugin;
@Test
@EnabledOnOs(WINDOWS)
void shouldUnlockFileAfterReadingExtensionsFromPlugin() throws Exception {
- PluginJar pluginJar = new PluginJar.Builder(pluginsPath.resolve("test-plugin.jar"), "test-plugin")
- .pluginClass(TestPlugin.class.getName())
- .pluginVersion("1.2.3")
+ PluginManifest pluginManifest = new PluginManifest.Builder("test-plugin")
+ .pluginClass(TestPlugin.class.getName())
+ .pluginVersion("1.2.3")
+ .build();
+ PluginJar pluginJar = new PluginJar.Builder(pluginsPath.resolve("test-plugin.jar"), pluginManifest)
.extension(TestExtension.class.getName())
.build();
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
+import org.pf4j.test.PluginProperties;
import org.pf4j.test.PluginZip;
import org.pf4j.util.FileUtils;
@Test
void load() throws Exception {
- PluginZip pluginZip1 = new PluginZip.Builder(pluginsPath1.resolve("my-plugin-1.2.3.zip"), "myPlugin")
+ PluginProperties plugin1Properties = new PluginProperties.Builder("myPlugin")
.pluginVersion("1.2.3")
.build();
+ PluginZip pluginZip1 = new PluginZip.Builder(pluginsPath1.resolve("my-plugin-1.2.3.zip"), plugin1Properties)
+ .build();
- PluginZip pluginZip2 = new PluginZip.Builder(pluginsPath2.resolve("my-other-plugin-4.5.6.zip"), "myOtherPlugin")
+ PluginProperties plugin2Properties = new PluginProperties.Builder("myOtherPlugin")
.pluginVersion("4.5.6")
.build();
+ PluginZip plugin2Zip = new PluginZip.Builder(pluginsPath2.resolve("my-other-plugin-4.5.6.zip"), plugin2Properties)
+ .build();
assertTrue(Files.exists(pluginZip1.path()));
assertEquals(0, pluginManager.getPlugins().size());
assertTrue(Files.exists(pluginZip1.path()));
assertTrue(Files.exists(pluginZip1.unzippedPath()));
- assertTrue(Files.exists(pluginZip2.path()));
- assertTrue(Files.exists(pluginZip2.unzippedPath()));
+ assertTrue(Files.exists(plugin2Zip.path()));
+ assertTrue(Files.exists(plugin2Zip.unzippedPath()));
assertEquals(2, pluginManager.getPlugins().size());
assertEquals(pluginZip1.pluginId(), pluginManager.idForPath(pluginZip1.unzippedPath()));
- assertEquals(pluginZip2.pluginId(), pluginManager.idForPath(pluginZip2.unzippedPath()));
+ assertEquals(plugin2Zip.pluginId(), pluginManager.idForPath(plugin2Zip.unzippedPath()));
}
}
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
+import org.pf4j.test.PluginProperties;
import org.pf4j.test.PluginZip;
+import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
}
@Test
- void load() throws Exception {
- PluginZip pluginZip = new PluginZip.Builder(pluginsPath.resolve("my-plugin-1.2.3.zip"), "myPlugin")
- .pluginVersion("1.2.3")
+ void load() throws IOException {
+ PluginProperties pluginProperties = createPluginProperties();
+ PluginZip pluginZip = new PluginZip.Builder(pluginsPath.resolve("my-plugin-1.2.3.zip"), pluginProperties)
.build();
assertTrue(Files.exists(pluginZip.path()));
}
@Test
- void loadTwiceFails() throws Exception {
- PluginZip pluginZip = new PluginZip.Builder(pluginsPath.resolve("my-plugin-1.2.3.zip"), "myPlugin")
- .pluginVersion("1.2.3")
+ void loadTwiceFails() throws IOException {
+ PluginProperties pluginProperties = createPluginProperties();
+ PluginZip pluginZip = new PluginZip.Builder(pluginsPath.resolve("my-plugin-1.2.3.zip"), pluginProperties)
.build();
assertNotNull(pluginManager.loadPluginFromPath(pluginZip.path()));
@Test
void loadPluginWithSameIdDifferentPathFails() throws Exception {
- String pluginId = "myPlugin";
- String pluginVersion = "1.2.3";
- Path plugin1Path = pluginsPath.resolve("my-plugin-1.2.3.zip");
- PluginZip plugin1 = new PluginZip.Builder(plugin1Path, pluginId)
- .pluginVersion(pluginVersion)
+ PluginProperties pluginProperties = createPluginProperties();
+ PluginZip plugin1 = new PluginZip.Builder(pluginsPath.resolve("my-plugin-1.2.3.zip"), pluginProperties)
.build();
-
- Path plugin2Path = pluginsPath.resolve("my-plugin-1.2.3-renamed.zip");
- PluginZip plugin2 = new PluginZip.Builder(plugin2Path, pluginId)
- .pluginVersion(pluginVersion)
+ PluginZip plugin2 = new PluginZip.Builder(pluginsPath.resolve("my-plugin-1.2.3-renamed.zip"), pluginProperties)
.build();
// Verify the first plugin with the given id is loaded
assertNotNull(pluginManager.loadPluginFromPath(plugin1.path()));
- Path loadedPlugin1Path = pluginManager.getPlugin(pluginId).getPluginPath();
+ Path loadedPlugin1Path = pluginManager.getPlugin(plugin1.pluginId()).getPluginPath();
try {
// Verify the second plugin is not loaded as it has the same metadata
fail("Expected loadPluginFromPath to fail");
} catch (PluginRuntimeException e) {
// Check the io of the loaded plugin remains the same
- PluginWrapper loadedPlugin = pluginManager.getPlugin(pluginId);
+ PluginWrapper loadedPlugin = pluginManager.getPlugin(plugin1.pluginId());
assertThat(loadedPlugin.getPluginPath(), equalTo(loadedPlugin1Path));
// Check the message includes relevant information
String message = e.getMessage();
assertThat(message, startsWith("There is an already loaded plugin"));
- assertThat(message, containsString(pluginId));
+ assertThat(message, containsString(plugin1.pluginId()));
assertThat(message, containsString("my-plugin-1.2.3-renamed"));
}
}
* uses pluginId as the unique identifier of the loaded plugin.
*/
@Test
- void loadPluginWithSameIdDifferentVersionsFails() throws Exception {
- String pluginId = "myPlugin";
- String plugin1Version = "1.2.3";
- Path plugin1Path = pluginsPath.resolve("my-plugin-1.2.3.zip");
- PluginZip plugin1 = new PluginZip.Builder(plugin1Path, pluginId)
- .pluginVersion(plugin1Version)
+ void loadPluginWithSameIdDifferentVersionsFails() throws IOException {
+ PluginProperties plugin1Properties = new PluginProperties.Builder("myPlugin")
+ .pluginVersion("1.2.3")
+ .build();
+ PluginZip plugin1 = new PluginZip.Builder(pluginsPath.resolve("my-plugin-1.2.3.zip"), plugin1Properties)
.build();
- String plugin2Version = "2.0.0";
- Path plugin2Path = pluginsPath.resolve("my-plugin-2.0.0.zip");
- PluginZip plugin2 = new PluginZip.Builder(plugin2Path, pluginId)
- .pluginVersion(plugin2Version)
+ PluginProperties plugin2Properties = new PluginProperties.Builder("myPlugin")
+ .pluginVersion("2.0.0")
+ .build();
+ PluginZip plugin2 = new PluginZip.Builder(pluginsPath.resolve("my-plugin-2.0.0.zip"), plugin2Properties)
.build();
// Verify the first plugin with the given id is loaded
assertNotNull(pluginManager.loadPluginFromPath(plugin1.path()));
- Path loadedPlugin1Path = pluginManager.getPlugin(pluginId).getPluginPath();
+ Path loadedPlugin1Path = pluginManager.getPlugin(plugin1.pluginId()).getPluginPath();
try {
// Verify the second plugin is not loaded as it has the same pluginId
pluginManager.loadPluginFromPath(plugin2.path());
fail("Expected loadPluginFromPath to fail");
} catch (PluginRuntimeException e) {
// Check the io and version of the loaded plugin remain the same
- PluginWrapper loadedPlugin = pluginManager.getPlugin(pluginId);
+ PluginWrapper loadedPlugin = pluginManager.getPlugin(plugin1.pluginId());
assertThat(loadedPlugin.getPluginPath(), equalTo(loadedPlugin1Path));
- assertThat(loadedPlugin.getDescriptor().getVersion(), equalTo(plugin1Version));
+ assertThat(loadedPlugin.getDescriptor().getVersion(), equalTo(plugin1.pluginVersion()));
}
}
@Test
- void loadUnloadLoad() throws Exception {
- PluginZip pluginZip = new PluginZip.Builder(pluginsPath.resolve("my-plugin-1.2.3.zip"), "myPlugin")
- .pluginVersion("1.2.3")
+ void loadUnloadLoad() throws IOException {
+ PluginProperties pluginProperties = createPluginProperties();
+ PluginZip pluginZip = new PluginZip.Builder(pluginsPath.resolve("my-plugin-1.2.3.zip"), pluginProperties)
.build();
pluginManager.loadPlugins();
}
@Test
- void upgrade() throws Exception {
- String pluginId = "myPlugin";
-
- new PluginZip.Builder(pluginsPath.resolve("my-plugin-1.2.3.zip"), pluginId)
- .pluginVersion("1.2.3")
+ void upgrade() throws IOException {
+ PluginProperties pluginProperties = createPluginProperties();
+ PluginZip pluginZip = new PluginZip.Builder(pluginsPath.resolve("my-plugin-1.2.3.zip"), pluginProperties)
.build();
pluginManager.loadPlugins();
assertEquals(1, pluginManager.getPlugins().size());
assertEquals(1, pluginManager.getStartedPlugins().size());
- PluginZip pluginZip2 = new PluginZip.Builder(pluginsPath.resolve("my-plugin-2.0.0.ZIP"), pluginId)
+ PluginProperties plugin2Properties = new PluginProperties.Builder("myPlugin")
.pluginVersion("2.0.0")
.build();
+ PluginZip pluginZip2 = new PluginZip.Builder(pluginsPath.resolve("my-plugin-2.0.0.ZIP"), plugin2Properties)
+ .build();
- assertEquals("1.2.3", pluginManager.getPlugin(pluginId).getDescriptor().getVersion());
+ assertEquals("1.2.3", pluginManager.getPlugin(pluginZip.pluginId()).getDescriptor().getVersion());
- pluginManager.unloadPlugin(pluginId);
+ pluginManager.unloadPlugin(pluginZip.pluginId());
pluginManager.loadPlugin(pluginZip2.path()); // or `pluginManager.loadPlugins();`
- pluginManager.startPlugin(pluginId);
+ pluginManager.startPlugin(pluginZip.pluginId());
assertEquals(1, pluginManager.getPlugins().size());
- assertEquals("2.0.0", pluginManager.getPlugin(pluginId).getDescriptor().getVersion());
+ assertEquals("2.0.0", pluginManager.getPlugin(pluginZip.pluginId()).getDescriptor().getVersion());
assertEquals("2.0.0", pluginManager.getStartedPlugins().get(0).getDescriptor().getVersion());
}
}
@Test
- void deletePlugin() throws Exception {
- PluginZip pluginZip1 = new PluginZip.Builder(pluginsPath.resolve("my-plugin-1.2.3.zip"), "myPlugin")
+ void deletePlugin() throws IOException {
+ PluginProperties plugin1Properties = new PluginProperties.Builder("myPlugin")
.pluginVersion("1.2.3")
.build();
+ PluginZip pluginZip1 = new PluginZip.Builder(pluginsPath.resolve("my-plugin-1.2.3.zip"), plugin1Properties)
+ .build();
- PluginZip pluginZip3 = new PluginZip.Builder(pluginsPath.resolve("other-3.0.0.Zip"), "other")
+ PluginProperties plugin2Properties = new PluginProperties.Builder("other")
.pluginVersion("3.0.0")
.build();
+ PluginZip pluginZip3 = new PluginZip.Builder(pluginsPath.resolve("other-3.0.0.Zip"), plugin2Properties)
+ .build();
pluginManager.loadPlugins();
pluginManager.startPlugins();
assertTrue(Files.exists(pluginZip3.unzippedPath()));
}
+ private PluginProperties createPluginProperties() {
+ return new PluginProperties.Builder("myPlugin")
+ .pluginVersion("1.2.3")
+ .build();
+ }
+
}
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
-import org.pf4j.test.PluginJar;
+import org.pf4j.test.PluginManifest;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
-import java.util.LinkedHashMap;
-import java.util.Map;
+import java.util.Arrays;
import java.util.jar.Manifest;
import static org.junit.jupiter.api.Assertions.assertEquals;
@BeforeEach
void setUp() throws IOException {
Path pluginPath = Files.createDirectories(pluginsPath.resolve("test-plugin-1"));
- storeManifestToPath(getPlugin1Manifest(), pluginPath);
+ storeManifestToPath(createManifestPlugin1(), pluginPath);
pluginPath = Files.createDirectories(pluginsPath.resolve("test-plugin-2"));
- storeManifestToPath(getPlugin2Manifest(), pluginPath);
+ storeManifestToPath(createManifestPlugin2(), pluginPath);
// empty plugin
Files.createDirectories(pluginsPath.resolve("test-plugin-3"));
// no plugin class
pluginPath = Files.createDirectories(pluginsPath.resolve("test-plugin-4"));
- storeManifestToPath(getPlugin4Manifest(), pluginPath);
+ storeManifestToPath(createManifestPlugin4(), pluginPath);
// no plugin version
pluginPath = Files.createDirectories(pluginsPath.resolve("test-plugin-5"));
- storeManifestToPath(getPlugin5Manifest(), pluginPath);
+ storeManifestToPath(createManifestPlugin5(), pluginPath);
// no plugin id
pluginPath = Files.createDirectories(pluginsPath.resolve("test-plugin-6"));
- storeManifestToPath(getPlugin6Manifest(), pluginPath);
+ storeManifestToPath(createManifestPlugin6(), pluginPath);
versionManager = new DefaultVersionManager();
}
* Test of {@link ManifestPluginDescriptorFinder#find(Path)} method.
*/
@Test
- void find() throws Exception {
+ void find() {
PluginDescriptorFinder descriptorFinder = new ManifestPluginDescriptorFinder();
PluginDescriptor plugin1 = descriptorFinder.find(pluginsPath.resolve("test-plugin-1"));
@Test
void findNotFound() {
PluginDescriptorFinder descriptorFinder = new ManifestPluginDescriptorFinder();
- assertThrows(PluginRuntimeException.class, () -> descriptorFinder.find(pluginsPath.resolve("test-plugin-3")));
+ Path pluginPath = pluginsPath.resolve("test-plugin-3");
+ assertThrows(PluginRuntimeException.class, () -> descriptorFinder.find(pluginPath));
}
- private Manifest getPlugin1Manifest() {
- Map<String, String> map = new LinkedHashMap<>(8);
- map.put(ManifestPluginDescriptorFinder.PLUGIN_ID, "test-plugin-1");
- map.put(ManifestPluginDescriptorFinder.PLUGIN_CLASS, "org.pf4j.plugin.TestPlugin");
- map.put(ManifestPluginDescriptorFinder.PLUGIN_VERSION, "0.0.1");
- map.put(ManifestPluginDescriptorFinder.PLUGIN_DESCRIPTION, "Test Plugin 1");
- map.put(ManifestPluginDescriptorFinder.PLUGIN_PROVIDER, "Decebal Suiu");
- map.put(ManifestPluginDescriptorFinder.PLUGIN_DEPENDENCIES, "test-plugin-2,test-plugin-3@~1.0");
- map.put(ManifestPluginDescriptorFinder.PLUGIN_REQUIRES, "*");
- map.put(ManifestPluginDescriptorFinder.PLUGIN_LICENSE, "Apache-2.0");
-
- return PluginJar.createManifest(map);
+ private Manifest createManifestPlugin1() {
+ return new PluginManifest.Builder("test-plugin-1")
+ .pluginClass("org.pf4j.plugin.TestPlugin")
+ .pluginVersion("0.0.1")
+ .pluginDescription("Test Plugin 1")
+ .pluginProvider("Decebal Suiu")
+ .pluginDependencies(Arrays.asList("test-plugin-2", "test-plugin-3@~1.0"))
+ .pluginRequires("*")
+ .pluginLicense("Apache-2.0")
+ .build()
+ .manifest();
}
- private Manifest getPlugin2Manifest() {
- Map<String, String> map = new LinkedHashMap<>(5);
- map.put(ManifestPluginDescriptorFinder.PLUGIN_ID, "test-plugin-2");
- map.put(ManifestPluginDescriptorFinder.PLUGIN_CLASS, "org.pf4j.plugin.TestPlugin");
- map.put(ManifestPluginDescriptorFinder.PLUGIN_VERSION, "0.0.1");
- map.put(ManifestPluginDescriptorFinder.PLUGIN_PROVIDER, "Decebal Suiu");
- map.put(ManifestPluginDescriptorFinder.PLUGIN_DEPENDENCIES, "");
-
- return PluginJar.createManifest(map);
+ private Manifest createManifestPlugin2() {
+ return new PluginManifest.Builder("test-plugin-2")
+ .pluginClass("org.pf4j.plugin.TestPlugin")
+ .pluginVersion("0.0.1")
+ .pluginProvider("Decebal Suiu")
+ .build()
+ .manifest();
}
- private Manifest getPlugin4Manifest() {
- Map<String, String> map = new LinkedHashMap<>(3);
- map.put(ManifestPluginDescriptorFinder.PLUGIN_ID, "test-plugin-1");
- map.put(ManifestPluginDescriptorFinder.PLUGIN_VERSION, "0.0.1");
- map.put(ManifestPluginDescriptorFinder.PLUGIN_PROVIDER, "Decebal Suiu");
-
- return PluginJar.createManifest(map);
+ private Manifest createManifestPlugin4() {
+ return new PluginManifest.Builder("test-plugin-4")
+ .pluginVersion("0.0.1")
+ .pluginProvider("Decebal Suiu")
+ .build()
+ .manifest();
}
- private Manifest getPlugin5Manifest() {
- Map<String, String> map = new LinkedHashMap<>(3);
- map.put(ManifestPluginDescriptorFinder.PLUGIN_ID, "test-plugin-2");
- map.put(ManifestPluginDescriptorFinder.PLUGIN_CLASS, "org.pf4j.plugin.TestPlugin");
- map.put(ManifestPluginDescriptorFinder.PLUGIN_PROVIDER, "Decebal Suiu");
-
- return PluginJar.createManifest(map);
+ private Manifest createManifestPlugin5() {
+ return new PluginManifest.Builder("test-plugin-5")
+ .pluginClass("org.pf4j.plugin.TestPlugin")
+ .pluginProvider("Decebal Suiu")
+ .build()
+ .manifest();
}
- private Manifest getPlugin6Manifest() {
- Map<String, String> map = new LinkedHashMap<>(2);
- map.put(ManifestPluginDescriptorFinder.PLUGIN_CLASS, "org.pf4j.plugin.TestPlugin");
- map.put(ManifestPluginDescriptorFinder.PLUGIN_PROVIDER, "Decebal Suiu");
-
- return PluginJar.createManifest(map);
+ private Manifest createManifestPlugin6() {
+ return new PluginManifest.Builder("test-plugin-6")
+ .pluginClass("org.pf4j.plugin.TestPlugin")
+ .pluginProvider("Decebal Suiu")
+ .build()
+ .manifest();
}
private void storeManifestToPath(Manifest manifest, Path pluginPath) throws IOException {
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
+import org.pf4j.test.PluginProperties;
import org.pf4j.test.PluginZip;
import org.pf4j.util.FileUtils;
pluginDependencyDescriptor.setProvider("Me");
pluginDependencyDescriptor.setRequires("5.0.0");
+ PluginProperties pluginProperties = new PluginProperties.Builder(pluginDependencyDescriptor.getPluginId())
+ .pluginVersion(pluginDependencyDescriptor.getVersion())
+ .build();
Path pluginDependencyPath = pluginsPath.resolve(pluginDependencyDescriptor.getPluginId() + "-" + pluginDependencyDescriptor.getVersion() + ".zip");
- PluginZip pluginDependencyZip = new PluginZip.Builder(pluginDependencyPath, pluginDependencyDescriptor.getPluginId())
- .pluginVersion(pluginDependencyDescriptor.getVersion())
+ PluginZip pluginDependencyZip = new PluginZip.Builder(pluginDependencyPath, pluginProperties)
.addFile(Paths.get("classes/META-INF/dependency-file"), "dependency")
.addFile(Paths.get("classes/META-INF/file-in-both-parent-and-dependency-and-plugin"), "dependency")
.addFile(Paths.get("classes/META-INF/file-in-both-parent-and-dependency"), "dependency")
pluginDescriptor.setRequires("5.0.0");
Path pluginPath = pluginsPath.resolve(pluginDescriptor.getPluginId() + "-" + pluginDescriptor.getVersion() + ".zip");
- PluginZip pluginZip = new PluginZip.Builder(pluginPath, pluginDescriptor.getPluginId())
- .pluginVersion(pluginDescriptor.getVersion())
+ PluginZip pluginZip = new PluginZip.Builder(pluginPath, pluginProperties)
.addFile(Paths.get("classes/META-INF/plugin-file"), "plugin")
.addFile(Paths.get("classes/META-INF/file-in-both-parent-and-dependency-and-plugin"), "plugin")
.addFile(Paths.get("classes/META-INF/file-in-both-parent-and-plugin"), "plugin")
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
+import org.pf4j.test.PluginProperties;
import org.pf4j.test.PluginZip;
import java.nio.file.Path;
@Test
void dependentStop() throws Exception {
// B depends on A
- PluginZip pluginA = new PluginZip.Builder(pluginsPath.resolve("A-plugin-1.2.3.zip"), "plugin.a")
- .pluginVersion("1.2.3").build();
-
- PluginZip pluginB = new PluginZip.Builder(pluginsPath.resolve("B-plugin-1.2.3.zip"), "plugin.b")
- .pluginDependencies("plugin.a")
- .pluginVersion("1.2.3").build();
+ PluginProperties pluginAProperties = new PluginProperties.Builder("plugin.a")
+ .pluginVersion("1.2.3")
+ .build();
+ PluginZip pluginA = new PluginZip.Builder(pluginsPath.resolve("A-plugin-1.2.3.zip"), pluginAProperties)
+ .build();
+
+ PluginProperties pluginBProperties = new PluginProperties.Builder("plugin.b")
+ .pluginVersion("1.2.3")
+ .pluginDependency("plugin.a")
+ .build();
+ PluginZip pluginB = new PluginZip.Builder(pluginsPath.resolve("B-plugin-1.2.3.zip"), pluginBProperties)
+ .build();
pluginManager.loadPlugins();
assertEquals(2, pluginManager.getPlugins().size());
@Test
void dependentUnload() throws Exception {
// B depends on A
- PluginZip pluginA = new PluginZip.Builder(pluginsPath.resolve("A-plugin-1.2.3.zip"), "plugin.a")
- .pluginVersion("1.2.3").build();
-
- PluginZip pluginB = new PluginZip.Builder(pluginsPath.resolve("B-plugin-1.2.3.zip"), "plugin.b")
- .pluginDependencies("plugin.a")
- .pluginVersion("1.2.3").build();
+ PluginProperties pluginAProperties = new PluginProperties.Builder("plugin.a")
+ .pluginVersion("1.2.3")
+ .build();
+ PluginZip pluginA = new PluginZip.Builder(pluginsPath.resolve("A-plugin-1.2.3.zip"), pluginAProperties)
+ .build();
+
+ PluginProperties pluginBProperties = new PluginProperties.Builder("plugin.b")
+ .pluginVersion("1.2.3")
+ .pluginDependency("plugin.a")
+ .build();
+ PluginZip pluginB = new PluginZip.Builder(pluginsPath.resolve("B-plugin-1.2.3.zip"), pluginBProperties)
+ .build();
pluginManager.loadPlugins();
assertEquals(2, pluginManager.getPlugins().size());
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
-import org.pf4j.test.PluginZip;
+import org.pf4j.test.PluginProperties;
import org.pf4j.test.TestPlugin;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
-import java.util.LinkedHashMap;
-import java.util.Map;
+import java.util.Arrays;
import java.util.Properties;
import static org.junit.jupiter.api.Assertions.assertEquals;
@BeforeEach
void setUp() throws IOException {
Path pluginPath = Files.createDirectory(pluginsPath.resolve("test-plugin-1"));
- storePropertiesToPath(getPlugin1Properties(), pluginPath);
+ storePropertiesToPath(createPropertiesPlugin1(), pluginPath);
pluginPath = Files.createDirectory(pluginsPath.resolve("test-plugin-2"));
- storePropertiesToPath(getPlugin2Properties(), pluginPath);
+ storePropertiesToPath(createPropertiesPlugin2(), pluginPath);
// empty plugin
Files.createDirectories(pluginsPath.resolve("test-plugin-3"));
// no plugin class
pluginPath = Files.createDirectory(pluginsPath.resolve("test-plugin-4"));
- storePropertiesToPath(getPlugin4Properties(), pluginPath);
+ storePropertiesToPath(createPropertiesPlugin4(), pluginPath);
// no plugin version
pluginPath = Files.createDirectory(pluginsPath.resolve("test-plugin-5"));
- storePropertiesToPath(getPlugin5Properties(), pluginPath);
+ storePropertiesToPath(createPropertiesPlugin5(), pluginPath);
// no plugin id
pluginPath = Files.createDirectory(pluginsPath.resolve("test-plugin-6"));
- storePropertiesToPath(getPlugin6Properties(), pluginPath);
+ storePropertiesToPath(createPropertiesPlugin6(), pluginPath);
versionManager = new DefaultVersionManager();
}
@Test
- void find() throws Exception {
+ void find() {
PluginDescriptorFinder descriptorFinder = new PropertiesPluginDescriptorFinder();
PluginDescriptor plugin1 = descriptorFinder.find(pluginsPath.resolve("test-plugin-1"));
@Test
void notFound() {
PluginDescriptorFinder descriptorFinder = new PropertiesPluginDescriptorFinder();
- assertThrows(PluginRuntimeException.class, () -> descriptorFinder.find(pluginsPath.resolve("test-plugin-3")));
+ Path pluginPath = pluginsPath.resolve("test-plugin-3");
+ assertThrows(PluginRuntimeException.class, () -> descriptorFinder.find(pluginPath));
}
- private Properties getPlugin1Properties() {
- Map<String, String> map = new LinkedHashMap<>(8);
- map.put(PropertiesPluginDescriptorFinder.PLUGIN_ID, "test-plugin-1");
- map.put(PropertiesPluginDescriptorFinder.PLUGIN_CLASS, TestPlugin.class.getName());
- map.put(PropertiesPluginDescriptorFinder.PLUGIN_VERSION, "0.0.1");
- map.put(PropertiesPluginDescriptorFinder.PLUGIN_DESCRIPTION, "Test Plugin 1");
- map.put(PropertiesPluginDescriptorFinder.PLUGIN_PROVIDER, "Decebal Suiu");
- map.put(PropertiesPluginDescriptorFinder.PLUGIN_DEPENDENCIES, "test-plugin-2,test-plugin-3@~1.0");
- map.put(PropertiesPluginDescriptorFinder.PLUGIN_REQUIRES, ">=1");
- map.put(PropertiesPluginDescriptorFinder.PLUGIN_LICENSE, "Apache-2.0");
-
- return PluginZip.createProperties(map);
+ private Properties createPropertiesPlugin1() {
+ return new PluginProperties.Builder("test-plugin-1")
+ .pluginClass(TestPlugin.class.getName())
+ .pluginVersion("0.0.1")
+ .pluginDescription("Test Plugin 1")
+ .pluginProvider("Decebal Suiu")
+ .pluginDependencies(Arrays.asList("test-plugin-2", "test-plugin-3@~1.0"))
+ .pluginRequires(">=1")
+ .pluginLicense("Apache-2.0")
+ .build()
+ .properties();
}
- private Properties getPlugin2Properties() {
- Map<String, String> map = new LinkedHashMap<>(5);
- map.put(PropertiesPluginDescriptorFinder.PLUGIN_ID, "test-plugin-2");
- map.put(PropertiesPluginDescriptorFinder.PLUGIN_CLASS, TestPlugin.class.getName());
- map.put(PropertiesPluginDescriptorFinder.PLUGIN_VERSION, "0.0.1");
- map.put(PropertiesPluginDescriptorFinder.PLUGIN_PROVIDER, "Decebal Suiu");
- map.put(PropertiesPluginDescriptorFinder.PLUGIN_DEPENDENCIES, "");
-
- return PluginZip.createProperties(map);
+ private Properties createPropertiesPlugin2() {
+ return new PluginProperties.Builder("test-plugin-2")
+ .pluginClass(TestPlugin.class.getName())
+ .pluginVersion("0.0.1")
+ .pluginProvider("Decebal Suiu")
+ .build()
+ .properties();
}
- private Properties getPlugin4Properties() {
- Map<String, String> map = new LinkedHashMap<>(5);
- map.put(PropertiesPluginDescriptorFinder.PLUGIN_ID, "test-plugin-2");
- map.put(PropertiesPluginDescriptorFinder.PLUGIN_VERSION, "0.0.1");
- map.put(PropertiesPluginDescriptorFinder.PLUGIN_PROVIDER, "Decebal Suiu");
- map.put(PropertiesPluginDescriptorFinder.PLUGIN_DEPENDENCIES, "");
- map.put(PropertiesPluginDescriptorFinder.PLUGIN_REQUIRES, "*");
-
- return PluginZip.createProperties(map);
+ private Properties createPropertiesPlugin4() {
+ return new PluginProperties.Builder("test-plugin-4")
+ .pluginClass("org.pf4j.plugin.TestPlugin")
+ .pluginVersion("0.0.1")
+ .pluginProvider("Decebal Suiu")
+ .pluginRequires("*")
+ .build()
+ .properties();
}
- private Properties getPlugin5Properties() {
- Map<String, String> map = new LinkedHashMap<>(5);
- map.put(PropertiesPluginDescriptorFinder.PLUGIN_ID, "test-plugin-2");
- map.put(PropertiesPluginDescriptorFinder.PLUGIN_CLASS, TestPlugin.class.getName());
- map.put(PropertiesPluginDescriptorFinder.PLUGIN_PROVIDER, "Decebal Suiu");
- map.put(PropertiesPluginDescriptorFinder.PLUGIN_DEPENDENCIES, "");
- map.put(PropertiesPluginDescriptorFinder.PLUGIN_REQUIRES, "*");
-
- return PluginZip.createProperties(map);
+ private Properties createPropertiesPlugin5() {
+ return new PluginProperties.Builder("test-plugin-5")
+ .pluginClass(TestPlugin.class.getName())
+ .pluginProvider("Decebal Suiu")
+ .pluginRequires("*")
+ .build()
+ .properties();
}
- private Properties getPlugin6Properties() {
- Map<String, String> map = new LinkedHashMap<>(5);
- map.put(PropertiesPluginDescriptorFinder.PLUGIN_CLASS, TestPlugin.class.getName());
- map.put(PropertiesPluginDescriptorFinder.PLUGIN_VERSION, "0.0.1");
- map.put(PropertiesPluginDescriptorFinder.PLUGIN_PROVIDER, "Decebal Suiu");
- map.put(PropertiesPluginDescriptorFinder.PLUGIN_DEPENDENCIES, "");
- map.put(PropertiesPluginDescriptorFinder.PLUGIN_REQUIRES, "*");
-
- return PluginZip.createProperties(map);
+ private Properties createPropertiesPlugin6() {
+ return new PluginProperties.Builder("test-plugin-6")
+ .pluginClass(TestPlugin.class.getName())
+ .pluginVersion("0.0.1")
+ .pluginProvider("Decebal Suiu")
+ .pluginRequires("*")
+ .build()
+ .properties();
}
private void storePropertiesToPath(Properties properties, Path pluginPath) throws IOException {
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import org.pf4j.test.PluginJar;
+import org.pf4j.test.PluginManifest;
import org.pf4j.test.TestExtension;
import org.pf4j.test.TestExtensionPoint;
import org.pf4j.test.TestPlugin;
void setUp() throws IOException {
pluginManagerEvents = 0;
wrappedPluginManagerEvents = 0;
- thisPlugin = new PluginJar.Builder(pluginsPath.resolve("test-plugin1.jar"), THIS_PLUGIN_ID).pluginClass(TestPlugin.class.getName()).pluginVersion("1.2.3").extension(TestExtension.class.getName()).build();
- otherPlugin = new PluginJar.Builder(pluginsPath.resolve("test-plugin2.jar"), OTHER_PLUGIN_ID).pluginClass(TestPlugin.class.getName()).pluginVersion("1.2.3").extension(TestExtension.class.getName()).build();
+ PluginManifest plugin1Manifest = new PluginManifest.Builder(THIS_PLUGIN_ID)
+ .pluginClass(TestPlugin.class.getName())
+ .pluginVersion("1.2.3")
+ .build();
+
+ PluginManifest plugin2Manifest = new PluginManifest.Builder(OTHER_PLUGIN_ID)
+ .pluginClass(TestPlugin.class.getName())
+ .pluginVersion("1.2.3")
+ .build();
+ thisPlugin = new PluginJar.Builder(pluginsPath.resolve("test-plugin1.jar"), plugin1Manifest)
+ .extension(TestExtension.class.getName())
+ .build();
+ otherPlugin = new PluginJar.Builder(pluginsPath.resolve("test-plugin2.jar"), plugin2Manifest)
+ .extension(TestExtension.class.getName())
+ .build();
pluginManager = new JarPluginManager(pluginsPath);
wrappedPluginManager = new SecurePluginManagerWrapper(pluginManager, THIS_PLUGIN_ID);
*/
package org.pf4j.test;
-import org.pf4j.ManifestPluginDescriptorFinder;
-
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.nio.file.Files;
import java.nio.file.Path;
-import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
-import java.util.Map;
import java.util.Set;
-import java.util.jar.Attributes;
import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
-import java.util.jar.Manifest;
/**
* Represents a plugin {@code jar} file.
public class PluginJar {
private final Path path;
- private final String pluginId;
- private final String pluginClass;
- private final String pluginVersion;
+ private final PluginManifest manifest;
protected PluginJar(Builder builder) {
this.path = builder.path;
- this.pluginId = builder.pluginId;
- this.pluginClass = builder.pluginClass;
- this.pluginVersion = builder.pluginVersion;
+ this.manifest = builder.manifest;
}
public Path path() {
return path;
}
+ public PluginManifest manifest() {
+ return manifest;
+ }
+
public String pluginClass() {
- return pluginClass;
+ return manifest.pluginClass();
}
public String pluginId() {
- return pluginId;
+ return manifest.pluginId();
}
public String pluginVersion() {
- return pluginVersion;
- }
-
- public static Manifest createManifest(Map<String, String> map) {
- Manifest manifest = new Manifest();
- Attributes attributes = manifest.getMainAttributes();
- attributes.put(Attributes.Name.MANIFEST_VERSION, "1.0.0");
- for (Map.Entry<String, String> entry : map.entrySet()) {
- attributes.put(new Attributes.Name(entry.getKey()), entry.getValue());
- }
-
- return manifest;
+ return manifest.pluginVersion();
}
public static class Builder {
private final Path path;
- private final String pluginId;
+ private final PluginManifest manifest;
- private String pluginClass;
- private String pluginVersion;
- private Map<String, String> manifestAttributes = new LinkedHashMap<>();
private Set<String> extensions = new LinkedHashSet<>();
private ClassDataProvider classDataProvider = new DefaultClassDataProvider();
- public Builder(Path path, String pluginId) {
+ public Builder(Path path, PluginManifest manifest) {
this.path = path;
- this.pluginId = pluginId;
- }
-
- public Builder pluginClass(String pluginClass) {
- this.pluginClass = pluginClass;
-
- return this;
- }
-
- public Builder pluginVersion(String pluginVersion) {
- this.pluginVersion = pluginVersion;
-
- return this;
- }
-
- /**
- * Add extra attributes to the {@code manifest} file.
- * As possible attribute name please see {@link ManifestPluginDescriptorFinder}.
- */
- public Builder manifestAttributes(Map<String, String> manifestAttributes) {
- this.manifestAttributes.putAll(manifestAttributes);
-
- return this;
- }
-
- /**
- * Add extra attribute to the {@code manifest} file.
- * As possible attribute name please see {@link ManifestPluginDescriptorFinder}.
- */
- public Builder manifestAttribute(String name, String value) {
- manifestAttributes.put(name, value);
-
- return this;
+ this.manifest = manifest;
}
public Builder extension(String extensionClassName) {
}
public PluginJar build() throws IOException {
- Manifest manifest = createManifest();
try (OutputStream outputStream = Files.newOutputStream(path);
- JarOutputStream jarOutputStream = new JarOutputStream(outputStream, manifest)) {
+ JarOutputStream jarOutputStream = new JarOutputStream(outputStream, manifest.manifest())) {
if (!extensions.isEmpty()) {
// add extensions.idx
JarEntry jarEntry = new JarEntry("META-INF/extensions.idx");
return new PluginJar(this);
}
- private Manifest createManifest() {
- Map<String, String> map = new LinkedHashMap<>();
- map.put(ManifestPluginDescriptorFinder.PLUGIN_ID, pluginId);
- map.put(ManifestPluginDescriptorFinder.PLUGIN_VERSION, pluginVersion);
- if (pluginClass != null) {
- map.put(ManifestPluginDescriptorFinder.PLUGIN_CLASS, pluginClass);
- }
- if (manifestAttributes != null) {
- map.putAll(manifestAttributes);
- }
-
- return PluginJar.createManifest(map);
- }
-
private byte[] extensionsAsByteArray() throws IOException {
try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
PrintWriter writer = new PrintWriter(outputStream);
--- /dev/null
+package org.pf4j.test;
+
+import org.pf4j.ManifestPluginDescriptorFinder;
+import org.pf4j.util.StringUtils;
+
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.jar.Attributes;
+import java.util.jar.Manifest;
+
+/**
+ * @author Decebal Suiu
+ */
+public class PluginManifest {
+
+ private final String pluginId;
+ private final String pluginClass;
+ private final String pluginVersion;
+ private final String pluginDescription;
+ private final String pluginProvider;
+ private final List<String> pluginDependencies;
+ private final String pluginRequires;
+ private final String pluginLicense;
+
+ private Manifest manifest;
+
+ protected PluginManifest(Builder builder) {
+ this.pluginId = builder.pluginId;
+ this.pluginClass = builder.pluginClass;
+ this.pluginVersion = builder.pluginVersion;
+ this.pluginDescription = builder.pluginDescription;
+ this.pluginProvider = builder.pluginProvider;
+ this.pluginDependencies = builder.pluginDependencies;
+ this.pluginRequires = builder.pluginRequires;
+ this.pluginLicense = builder.pluginLicense;
+ }
+
+ public String pluginId() {
+ return pluginId;
+ }
+
+ public String pluginClass() {
+ return pluginClass;
+ }
+
+ public String pluginVersion() {
+ return pluginVersion;
+ }
+
+ public String pluginDescription() {
+ return pluginDescription;
+ }
+
+ public String pluginProvider() {
+ return pluginProvider;
+ }
+
+ public List<String> pluginDependencies() {
+ return pluginDependencies;
+ }
+
+ public String pluginRequires() {
+ return pluginRequires;
+ }
+
+ public String pluginLicense() {
+ return pluginLicense;
+ }
+
+ public Manifest manifest() {
+ if (manifest == null) {
+ Map<String, String> map = new LinkedHashMap<>();
+ map.put(ManifestPluginDescriptorFinder.PLUGIN_ID, pluginId);
+
+ if (StringUtils.isNotNullOrEmpty(pluginVersion)) {
+ map.put(ManifestPluginDescriptorFinder.PLUGIN_VERSION, pluginVersion);
+ }
+
+ if (StringUtils.isNotNullOrEmpty(pluginClass)) {
+ map.put(ManifestPluginDescriptorFinder.PLUGIN_CLASS, pluginClass);
+ }
+
+ if (StringUtils.isNotNullOrEmpty(pluginDescription)) {
+ map.put(ManifestPluginDescriptorFinder.PLUGIN_DESCRIPTION, pluginDescription);
+ }
+
+ if (StringUtils.isNotNullOrEmpty(pluginProvider)) {
+ map.put(ManifestPluginDescriptorFinder.PLUGIN_PROVIDER, pluginProvider);
+ }
+
+ if (StringUtils.isNotNullOrEmpty(pluginProvider)) {
+ map.put(ManifestPluginDescriptorFinder.PLUGIN_PROVIDER, pluginProvider);
+ }
+
+ if (pluginDependencies != null && !pluginDependencies.isEmpty()) {
+ map.put(ManifestPluginDescriptorFinder.PLUGIN_DEPENDENCIES, String.join(",", pluginDependencies));
+ }
+
+ if (StringUtils.isNotNullOrEmpty(pluginRequires)) {
+ map.put(ManifestPluginDescriptorFinder.PLUGIN_REQUIRES, pluginRequires);
+ }
+
+
+ if (StringUtils.isNotNullOrEmpty(pluginLicense)) {
+ map.put(ManifestPluginDescriptorFinder.PLUGIN_LICENSE, pluginLicense);
+ }
+
+ manifest = new Manifest();
+ Attributes attributes = manifest.getMainAttributes();
+ attributes.put(Attributes.Name.MANIFEST_VERSION, "1.0.0");
+ for (Map.Entry<String, String> entry : map.entrySet()) {
+ attributes.put(new Attributes.Name(entry.getKey()), entry.getValue());
+ }
+ }
+
+ return manifest;
+ }
+
+ public static class Builder {
+
+ private final String pluginId;
+
+ private String pluginClass;
+ private String pluginVersion;
+ private String pluginDescription;
+ private String pluginProvider;
+ private List<String> pluginDependencies;
+ private String pluginRequires;
+ private String pluginLicense;
+
+ public Builder(String pluginId) {
+ this.pluginId = pluginId;
+ }
+
+ public Builder pluginClass(String pluginClass) {
+ this.pluginClass = pluginClass;
+
+ return this;
+ }
+
+ public Builder pluginVersion(String pluginVersion) {
+ this.pluginVersion = pluginVersion;
+
+ return this;
+ }
+
+ public Builder pluginDescription(String pluginDescription) {
+ this.pluginDescription = pluginDescription;
+
+ return this;
+ }
+
+ public Builder pluginProvider(String pluginProvider) {
+ this.pluginProvider = pluginProvider;
+
+ return this;
+ }
+
+ public Builder pluginDependencies(List<String> pluginDependencies) {
+ this.pluginDependencies = pluginDependencies;
+
+ return this;
+ }
+
+ public Builder pluginDependency(String pluginDependency) {
+ if (pluginDependencies == null) {
+ pluginDependencies = new LinkedList<>();
+ }
+
+ pluginDependencies.add(pluginDependency);
+
+ return this;
+ }
+
+ public Builder pluginRequires(String pluginRequires) {
+ this.pluginRequires = pluginRequires;
+
+ return this;
+ }
+
+ public Builder pluginLicense(String pluginLicense) {
+ this.pluginLicense = pluginLicense;
+
+ return this;
+ }
+
+ public PluginManifest build() {
+ return new PluginManifest(this);
+ }
+
+ }
+
+}
--- /dev/null
+package org.pf4j.test;
+
+import org.pf4j.PropertiesPluginDescriptorFinder;
+import org.pf4j.util.StringUtils;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Properties;
+
+/**
+ * @author Decebal Suiu
+ */
+public class PluginProperties {
+
+ private final String pluginId;
+ private final String pluginClass;
+ private final String pluginVersion;
+ private final String pluginDescription;
+ private final String pluginProvider;
+ private final List<String> pluginDependencies;
+ private final String pluginRequires;
+ private final String pluginLicense;
+
+ private Properties properties;
+
+ protected PluginProperties(Builder builder) {
+ this.pluginId = builder.pluginId;
+ this.pluginClass = builder.pluginClass;
+ this.pluginVersion = builder.pluginVersion;
+ this.pluginDescription = builder.pluginDescription;
+ this.pluginProvider = builder.pluginProvider;
+ this.pluginDependencies = builder.pluginDependencies;
+ this.pluginRequires = builder.pluginRequires;
+ this.pluginLicense = builder.pluginLicense;
+ }
+
+ public String pluginId() {
+ return pluginId;
+ }
+
+ public String pluginClass() {
+ return pluginClass;
+ }
+
+ public String pluginVersion() {
+ return pluginVersion;
+ }
+
+ public String pluginDescription() {
+ return pluginDescription;
+ }
+
+ public String pluginProvider() {
+ return pluginProvider;
+ }
+
+ public List<String> pluginDependencies() {
+ return pluginDependencies;
+ }
+
+ public String pluginRequires() {
+ return pluginRequires;
+ }
+
+ public String pluginLicense() {
+ return pluginLicense;
+ }
+
+ public Properties properties() {
+ if (properties == null) {
+ properties = new Properties();
+
+ properties.put(PropertiesPluginDescriptorFinder.PLUGIN_ID, pluginId);
+
+ if (StringUtils.isNotNullOrEmpty(pluginVersion)) {
+ properties.put(PropertiesPluginDescriptorFinder.PLUGIN_VERSION, pluginVersion);
+ }
+
+ if (StringUtils.isNotNullOrEmpty(pluginClass)) {
+ properties.put(PropertiesPluginDescriptorFinder.PLUGIN_CLASS, pluginClass);
+ }
+
+ if (StringUtils.isNotNullOrEmpty(pluginDescription)) {
+ properties.put(PropertiesPluginDescriptorFinder.PLUGIN_DESCRIPTION, pluginDescription);
+ }
+
+ if (StringUtils.isNotNullOrEmpty(pluginProvider)) {
+ properties.put(PropertiesPluginDescriptorFinder.PLUGIN_PROVIDER, pluginProvider);
+ }
+
+ if (StringUtils.isNotNullOrEmpty(pluginProvider)) {
+ properties.put(PropertiesPluginDescriptorFinder.PLUGIN_PROVIDER, pluginProvider);
+ }
+
+ if (pluginDependencies != null && !pluginDependencies.isEmpty()) {
+ properties.put(PropertiesPluginDescriptorFinder.PLUGIN_DEPENDENCIES, String.join(",", pluginDependencies));
+ }
+
+ if (StringUtils.isNotNullOrEmpty(pluginRequires)) {
+ properties.put(PropertiesPluginDescriptorFinder.PLUGIN_REQUIRES, pluginRequires);
+ }
+
+
+ if (StringUtils.isNotNullOrEmpty(pluginLicense)) {
+ properties.put(PropertiesPluginDescriptorFinder.PLUGIN_LICENSE, pluginLicense);
+ }
+ }
+
+ return properties;
+ }
+
+ public static class Builder {
+
+ private final String pluginId;
+
+ private String pluginClass;
+ private String pluginVersion;
+ private String pluginDescription;
+ private String pluginProvider;
+ private List<String> pluginDependencies;
+ private String pluginRequires;
+ private String pluginLicense;
+
+ public Builder(String pluginId) {
+ this.pluginId = pluginId;
+ }
+
+ public Builder pluginClass(String pluginClass) {
+ this.pluginClass = pluginClass;
+
+ return this;
+ }
+
+ public Builder pluginVersion(String pluginVersion) {
+ this.pluginVersion = pluginVersion;
+
+ return this;
+ }
+
+ public Builder pluginDescription(String pluginDescription) {
+ this.pluginDescription = pluginDescription;
+
+ return this;
+ }
+
+ public Builder pluginProvider(String pluginProvider) {
+ this.pluginProvider = pluginProvider;
+
+ return this;
+ }
+
+ public Builder pluginDependencies(List<String> pluginDependencies) {
+ this.pluginDependencies = pluginDependencies;
+
+ return this;
+ }
+
+ public Builder pluginDependency(String pluginDependency) {
+ if (pluginDependencies == null) {
+ pluginDependencies = new LinkedList<>();
+ }
+
+ pluginDependencies.add(pluginDependency);
+
+ return this;
+ }
+
+ public Builder pluginRequires(String pluginRequires) {
+ this.pluginRequires = pluginRequires;
+
+ return this;
+ }
+
+ public Builder pluginLicense(String pluginLicense) {
+ this.pluginLicense = pluginLicense;
+
+ return this;
+ }
+
+ public PluginProperties build() {
+ return new PluginProperties(this);
+ }
+
+ }
+
+}
import java.nio.file.Path;
import java.util.LinkedHashMap;
import java.util.Map;
-import java.util.Properties;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class PluginZip {
private final Path path;
- private final String pluginId;
- private final String pluginClass;
- private final String pluginVersion;
- private final String pluginDependencies;
+ private final PluginProperties properties;
protected PluginZip(Builder builder) {
this.path = builder.path;
- this.pluginId = builder.pluginId;
- this.pluginClass = builder.pluginClass;
- this.pluginVersion = builder.pluginVersion;
- this.pluginDependencies = builder.pluginDependencies;
+ this.properties = builder.properties;
}
public Path path() {
}
public String pluginId() {
- return pluginId;
+ return properties.pluginId();
}
public String pluginClass() {
- return pluginClass;
+ return properties.pluginClass();
}
public String pluginVersion() {
- return pluginVersion;
+ return properties.pluginVersion();
}
- public String pluginDependencies() { return pluginDependencies; }
-
public Path unzippedPath() {
Path path = path();
String fileName = path.getFileName().toString();
return path.getParent().resolve(fileName.substring(0, fileName.length() - 4)); // without ".zip" suffix
}
- public static Properties createProperties(Map<String, String> map) {
- Properties properties = new Properties();
- properties.putAll(map);
-
- return properties;
- }
-
public static class Builder {
private final Path path;
- private final String pluginId;
+ private final PluginProperties properties;
- private String pluginClass;
- private String pluginVersion;
- private String pluginDependencies;
- private Map<String, String> properties = new LinkedHashMap<>();
private Map<Path, byte[]> files = new LinkedHashMap<>();
- public Builder(Path path, String pluginId) {
+ public Builder(Path path, PluginProperties properties) {
this.path = path;
- this.pluginId = pluginId;
- }
-
- public Builder pluginClass(String pluginClass) {
- this.pluginClass = pluginClass;
-
- return this;
- }
-
- public Builder pluginVersion(String pluginVersion) {
- this.pluginVersion = pluginVersion;
-
- return this;
- }
-
- public Builder pluginDependencies(String pluginDependencies) {
- this.pluginDependencies = pluginDependencies;
-
- return this;
- }
-
- /**
- * Add extra properties to the {@code properties} file.
- * As possible attribute name please see {@link PropertiesPluginDescriptorFinder}.
- */
- public Builder properties(Map<String, String> properties) {
- this.properties.putAll(properties);
-
- return this;
- }
-
- /**
- * Add extra property to the {@code properties} file.
- * As possible property name please see {@link PropertiesPluginDescriptorFinder}.
- */
- public Builder property(String name, String value) {
- properties.put(name, value);
-
- return this;
+ this.properties = properties;
}
/**
}
protected void createPropertiesFile() throws IOException {
- Map<String, String> map = new LinkedHashMap<>();
- map.put(PropertiesPluginDescriptorFinder.PLUGIN_ID, pluginId);
- map.put(PropertiesPluginDescriptorFinder.PLUGIN_VERSION, pluginVersion);
- if (pluginDependencies != null) {
- map.put(PropertiesPluginDescriptorFinder.PLUGIN_DEPENDENCIES, pluginDependencies);
- }
- if (pluginClass != null) {
- map.put(PropertiesPluginDescriptorFinder.PLUGIN_CLASS, pluginClass);
- }
- if (properties != null) {
- map.putAll(properties);
- }
-
try (ZipOutputStream outputStream = new ZipOutputStream(Files.newOutputStream(path))) {
ZipEntry propertiesFile = new ZipEntry(PropertiesPluginDescriptorFinder.DEFAULT_PROPERTIES_FILE_NAME);
outputStream.putNextEntry(propertiesFile);
- createProperties(map).store(outputStream, "");
+ properties.properties().store(outputStream, "");
outputStream.closeEntry();
for (Map.Entry<Path, byte[]> fileEntry : files.entrySet()) {
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
+import org.pf4j.test.PluginProperties;
import org.pf4j.test.PluginZip;
import org.pf4j.util.io.ZipPathFilter;
@Test
void expandIfZipForZipWithOnlyModuleDescriptor() throws IOException {
- PluginZip pluginZip = new PluginZip.Builder(pluginsPath.resolve("my-plugin-1.2.3.zip"), "myPlugin")
- .pluginVersion("1.2.3")
+ PluginProperties pluginProperties = createPluginProperties();
+ PluginZip pluginZip = new PluginZip.Builder(pluginsPath.resolve("my-plugin-1.2.3.zip"), pluginProperties)
.build();
Path unzipped = FileUtils.expandIfZip(pluginZip.path());
@Test
void expandIfZipForZipWithResourceFile() throws IOException {
- PluginZip pluginZip = new PluginZip.Builder(pluginsPath.resolve("my-second-plugin-1.2.3.zip"), "myPlugin")
- .pluginVersion("1.2.3")
+ PluginProperties pluginProperties = createPluginProperties();
+ PluginZip pluginZip = new PluginZip.Builder(pluginsPath.resolve("my-second-plugin-1.2.3.zip"), pluginProperties)
.addFile(Paths.get("classes/META-INF/plugin-file"), "plugin")
.build();
@Test
void findPaths() throws IOException {
- PluginZip pluginZip = new PluginZip.Builder(pluginsPath.resolve("my-plugin-1.2.3.zip"), "myPlugin")
- .pluginVersion("1.2.3")
+ PluginProperties pluginProperties = createPluginProperties();
+ PluginZip pluginZip = new PluginZip.Builder(pluginsPath.resolve("my-plugin-1.2.3.zip"), pluginProperties)
.build();
Path unzipped = FileUtils.expandIfZip(pluginZip.path());
assertEquals(1, zipPaths.size());
}
+ private PluginProperties createPluginProperties() {
+ return new PluginProperties.Builder("myPlugin")
+ .pluginVersion("1.2.3")
+ .build();
+ }
+
}