jars = FileUtils.getJars(file);
- for (File jar : jars) {
- pluginClassLoader.addFile(jar);
- }
- }
+ return super.isApplicable(pluginPath) && Files.isDirectory(pluginPath);
}
}
diff --git a/pf4j/src/main/java/org/pf4j/DefaultPluginManager.java b/pf4j/src/main/java/org/pf4j/DefaultPluginManager.java
index 96a4104..9cad187 100644
--- a/pf4j/src/main/java/org/pf4j/DefaultPluginManager.java
+++ b/pf4j/src/main/java/org/pf4j/DefaultPluginManager.java
@@ -19,12 +19,13 @@ import org.pf4j.util.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
/**
* Default implementation of the {@link PluginManager} interface.
+ * In essence it is a {@link ZipPluginManager} plus a {@link JarPluginManager}.
+ * So, it can load plugins from jar and zip, simultaneous.
*
* This class is not thread-safe.
*
@@ -34,22 +35,12 @@ public class DefaultPluginManager extends AbstractPluginManager {
private static final Logger log = LoggerFactory.getLogger(DefaultPluginManager.class);
- protected PluginClasspath pluginClasspath;
+ public static final String PLUGINS_DIR_CONFIG_PROPERTY_NAME = "pf4j.pluginsConfigDir";
public DefaultPluginManager() {
super();
}
- /**
- * Use {@link DefaultPluginManager#DefaultPluginManager(Path)}.
- *
- * @param pluginsDir
- */
- @Deprecated
- public DefaultPluginManager(File pluginsDir) {
- this(pluginsDir.toPath());
- }
-
public DefaultPluginManager(Path pluginsRoot) {
super(pluginsRoot);
}
@@ -81,23 +72,26 @@ public class DefaultPluginManager extends AbstractPluginManager {
@Override
protected PluginStatusProvider createPluginStatusProvider() {
- String configDir = System.getProperty("pf4j.pluginsConfigDir");
+ String configDir = System.getProperty(PLUGINS_DIR_CONFIG_PROPERTY_NAME);
Path configPath = configDir != null ? Paths.get(configDir) : getPluginsRoot();
+
return new DefaultPluginStatusProvider(configPath);
}
@Override
protected PluginRepository createPluginRepository() {
return new CompoundPluginRepository()
- .add(new DefaultPluginRepository(getPluginsRoot(), isDevelopment()))
- .add(new JarPluginRepository(getPluginsRoot()));
+ .add(new DevelopmentPluginRepository(getPluginsRoot()), this::isDevelopment)
+ .add(new JarPluginRepository(getPluginsRoot()), this::isNotDevelopment)
+ .add(new DefaultPluginRepository(getPluginsRoot()), this::isNotDevelopment);
}
@Override
protected PluginLoader createPluginLoader() {
return new CompoundPluginLoader()
- .add(new DefaultPluginLoader(this, pluginClasspath))
- .add(new JarPluginLoader(this));
+ .add(new DevelopmentPluginLoader(this), this::isDevelopment)
+ .add(new JarPluginLoader(this), this::isNotDevelopment)
+ .add(new DefaultPluginLoader(this), this::isNotDevelopment);
}
@Override
@@ -105,19 +99,8 @@ public class DefaultPluginManager extends AbstractPluginManager {
return new DefaultVersionManager();
}
- /**
- * By default if {@link DefaultPluginManager#isDevelopment()} returns true
- * than a {@link DevelopmentPluginClasspath} is returned
- * else this method returns {@link DefaultPluginClasspath}.
- */
- protected PluginClasspath createPluginClasspath() {
- return isDevelopment() ? new DevelopmentPluginClasspath() : new DefaultPluginClasspath();
- }
-
@Override
protected void initialize() {
- pluginClasspath = createPluginClasspath();
-
super.initialize();
if (isDevelopment()) {
@@ -128,13 +111,14 @@ public class DefaultPluginManager extends AbstractPluginManager {
}
/**
- * Load a plugin from disk. If the path is a zip file, first unpack
+ * Load a plugin from disk. If the path is a zip file, first unpack.
+ *
* @param pluginPath plugin location on disk
* @return PluginWrapper for the loaded plugin or null if not loaded
- * @throws PluginException if problems during load
+ * @throws PluginRuntimeException if problems during load
*/
@Override
- protected PluginWrapper loadPluginFromPath(Path pluginPath) throws PluginException {
+ protected PluginWrapper loadPluginFromPath(Path pluginPath) {
// First unzip any ZIP files
try {
pluginPath = FileUtils.expandIfZip(pluginPath);
diff --git a/pf4j/src/main/java/org/pf4j/DefaultPluginRepository.java b/pf4j/src/main/java/org/pf4j/DefaultPluginRepository.java
index 78ea43c..2fafbc7 100644
--- a/pf4j/src/main/java/org/pf4j/DefaultPluginRepository.java
+++ b/pf4j/src/main/java/org/pf4j/DefaultPluginRepository.java
@@ -24,7 +24,6 @@ import org.pf4j.util.OrFileFilter;
import org.pf4j.util.ZipFileFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.pf4j.util.NameFileFilter;
import java.io.File;
import java.io.FileFilter;
@@ -39,29 +38,17 @@ public class DefaultPluginRepository extends BasePluginRepository {
private static final Logger log = LoggerFactory.getLogger(DefaultPluginRepository.class);
- public DefaultPluginRepository(Path pluginsRoot, boolean development) {
+ public DefaultPluginRepository(Path pluginsRoot) {
super(pluginsRoot);
AndFileFilter pluginsFilter = new AndFileFilter(new DirectoryFileFilter());
- pluginsFilter.addFileFilter(new NotFileFilter(createHiddenPluginFilter(development)));
+ pluginsFilter.addFileFilter(new NotFileFilter(createHiddenPluginFilter()));
setFilter(pluginsFilter);
}
@Override
public List getPluginPaths() {
- // expand plugins zip files
- File[] pluginZips = pluginsRoot.toFile().listFiles(new ZipFileFilter());
- if ((pluginZips != null) && pluginZips.length > 0) {
- for (File pluginZip : pluginZips) {
- try {
- FileUtils.expandIfZip(pluginZip.toPath());
- } catch (IOException e) {
- log.error("Cannot expand plugin zip '{}'", pluginZip);
- log.error(e.getMessage(), e);
- }
- }
- }
-
+ extractZipFiles();
return super.getPluginPaths();
}
@@ -71,16 +58,23 @@ public class DefaultPluginRepository extends BasePluginRepository {
return super.deletePluginPath(pluginPath);
}
- protected FileFilter createHiddenPluginFilter(boolean development) {
- OrFileFilter hiddenPluginFilter = new OrFileFilter(new HiddenFilter());
+ protected FileFilter createHiddenPluginFilter() {
+ return new OrFileFilter(new HiddenFilter());
+ }
- if (development) {
- // skip default build output folders since these will cause errors in the logs
- hiddenPluginFilter
- .addFileFilter(new NameFileFilter("target")) // MAVEN
- .addFileFilter(new NameFileFilter("build")); // GRADLE
+ 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);
+ }
+ }
}
-
- return hiddenPluginFilter;
}
+
}
diff --git a/pf4j/src/main/java/org/pf4j/DefaultPluginStatusProvider.java b/pf4j/src/main/java/org/pf4j/DefaultPluginStatusProvider.java
index ca85407..0b88fe8 100644
--- a/pf4j/src/main/java/org/pf4j/DefaultPluginStatusProvider.java
+++ b/pf4j/src/main/java/org/pf4j/DefaultPluginStatusProvider.java
@@ -66,31 +66,23 @@ public class DefaultPluginStatusProvider implements PluginStatusProvider {
}
@Override
- public boolean disablePlugin(String pluginId) {
- if (disabledPlugins.add(pluginId)) {
- try {
- FileUtils.writeLines(disabledPlugins, pluginsRoot.resolve("disabled.txt").toFile());
- } catch (IOException e) {
- log.error("Failed to disable plugin {}", pluginId, e);
- return false;
- }
+ public void disablePlugin(String pluginId) {
+ disabledPlugins.add(pluginId);
+ try {
+ FileUtils.writeLines(disabledPlugins, pluginsRoot.resolve("disabled.txt").toFile());
+ } catch (IOException e) {
+ throw new PluginRuntimeException(e);
}
-
- return true;
}
@Override
- public boolean enablePlugin(String pluginId) {
- if (disabledPlugins.remove(pluginId)) {
- try {
- FileUtils.writeLines(disabledPlugins, pluginsRoot.resolve("disabled.txt").toFile());
- } catch (IOException e) {
- log.error("Failed to enable plugin {}", pluginId, e);
- return false;
- }
+ public void enablePlugin(String pluginId) {
+ disabledPlugins.remove(pluginId);
+ try {
+ FileUtils.writeLines(disabledPlugins, pluginsRoot.resolve("disabled.txt").toFile());
+ } catch (IOException e) {
+ throw new PluginRuntimeException(e);
}
-
- return true;
}
}
diff --git a/pf4j/src/main/java/org/pf4j/DependencyResolver.java b/pf4j/src/main/java/org/pf4j/DependencyResolver.java
index a3aa9f6..45005e2 100644
--- a/pf4j/src/main/java/org/pf4j/DependencyResolver.java
+++ b/pf4j/src/main/java/org/pf4j/DependencyResolver.java
@@ -272,7 +272,7 @@ public class DependencyResolver {
/**
* It will be thrown if a cyclic dependency is detected.
*/
- public static class CyclicDependencyException extends PluginException {
+ public static class CyclicDependencyException extends PluginRuntimeException {
public CyclicDependencyException() {
super("Cyclic dependencies");
@@ -283,7 +283,7 @@ public class DependencyResolver {
/**
* Indicates that the dependencies required were not found.
*/
- public static class DependenciesNotFoundException extends PluginException {
+ public static class DependenciesNotFoundException extends PluginRuntimeException {
private List dependencies;
@@ -302,7 +302,7 @@ public class DependencyResolver {
/**
* Indicates that some dependencies have wrong version.
*/
- public static class DependenciesWrongVersionException extends PluginException {
+ public static class DependenciesWrongVersionException extends PluginRuntimeException {
private List dependencies;
diff --git a/pf4j/src/main/java/org/pf4j/DevelopmentPluginClasspath.java b/pf4j/src/main/java/org/pf4j/DevelopmentPluginClasspath.java
index 15da659..4d7727d 100644
--- a/pf4j/src/main/java/org/pf4j/DevelopmentPluginClasspath.java
+++ b/pf4j/src/main/java/org/pf4j/DevelopmentPluginClasspath.java
@@ -27,7 +27,7 @@ public class DevelopmentPluginClasspath extends PluginClasspath {
* The development plugin classpath for Maven.
* The classes directory is {@code target/classes} and the lib directory is {@code target/lib}.
*/
- public static final PluginClasspath MAVEN = new PluginClasspath().addClassesDirectories("target/classes").addLibDirectories("target/lib");
+ public static final PluginClasspath MAVEN = new PluginClasspath().addClassesDirectories("target/classes").addJarsDirectories("target/lib");
/**
* The development plugin classpath for Gradle.
@@ -46,9 +46,9 @@ public class DevelopmentPluginClasspath extends PluginClasspath {
addClassesDirectories(GRADLE.getClassesDirectories());
addClassesDirectories(KOTLIN.getClassesDirectories());
- addLibDirectories(MAVEN.getLibDirectories());
- addLibDirectories(GRADLE.getLibDirectories());
- addLibDirectories(KOTLIN.getLibDirectories());
+ addJarsDirectories(MAVEN.getJarsDirectories());
+ addJarsDirectories(GRADLE.getJarsDirectories());
+ addJarsDirectories(KOTLIN.getJarsDirectories());
}
}
diff --git a/pf4j/src/main/java/org/pf4j/DevelopmentPluginLoader.java b/pf4j/src/main/java/org/pf4j/DevelopmentPluginLoader.java
new file mode 100644
index 0000000..58c9473
--- /dev/null
+++ b/pf4j/src/main/java/org/pf4j/DevelopmentPluginLoader.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2012-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.pf4j;
+
+/**
+ * Load all information needed by a plugin from {@link DevelopmentPluginClasspath}.
+ *
+ * @author Decebal Suiu
+ */
+public class DevelopmentPluginLoader extends BasePluginLoader {
+
+ public DevelopmentPluginLoader(PluginManager pluginManager) {
+ super(pluginManager, new DevelopmentPluginClasspath());
+ }
+
+}
diff --git a/pf4j/src/main/java/org/pf4j/DevelopmentPluginRepository.java b/pf4j/src/main/java/org/pf4j/DevelopmentPluginRepository.java
new file mode 100644
index 0000000..e8f2c69
--- /dev/null
+++ b/pf4j/src/main/java/org/pf4j/DevelopmentPluginRepository.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2012-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.pf4j;
+
+import org.pf4j.util.AndFileFilter;
+import org.pf4j.util.DirectoryFileFilter;
+import org.pf4j.util.HiddenFilter;
+import org.pf4j.util.NameFileFilter;
+import org.pf4j.util.NotFileFilter;
+import org.pf4j.util.OrFileFilter;
+
+import java.io.FileFilter;
+import java.nio.file.Path;
+
+/**
+ * @author Decebal Suiu
+ */
+public class DevelopmentPluginRepository extends BasePluginRepository {
+
+ public static final String MAVEN_BUILD_DIR = "target";
+ public static final String GRADLE_BUILD_DIR = "build";
+
+ public DevelopmentPluginRepository(Path pluginsRoot) {
+ super(pluginsRoot);
+
+ AndFileFilter pluginsFilter = new AndFileFilter(new DirectoryFileFilter());
+ pluginsFilter.addFileFilter(new NotFileFilter(createHiddenPluginFilter()));
+ setFilter(pluginsFilter);
+ }
+
+ protected FileFilter createHiddenPluginFilter() {
+ OrFileFilter hiddenPluginFilter = new OrFileFilter(new HiddenFilter());
+
+ // skip default build output folders since these will cause errors in the logs
+ hiddenPluginFilter
+ .addFileFilter(new NameFileFilter(MAVEN_BUILD_DIR))
+ .addFileFilter(new NameFileFilter(GRADLE_BUILD_DIR));
+
+ return hiddenPluginFilter;
+ }
+
+}
diff --git a/pf4j/src/main/java/org/pf4j/ExtensionFactory.java b/pf4j/src/main/java/org/pf4j/ExtensionFactory.java
index 177d489..176c6ff 100644
--- a/pf4j/src/main/java/org/pf4j/ExtensionFactory.java
+++ b/pf4j/src/main/java/org/pf4j/ExtensionFactory.java
@@ -20,6 +20,6 @@ package org.pf4j;
*/
public interface ExtensionFactory {
- Object create(Class> extensionClass);
+ T create(Class extensionClass);
}
diff --git a/pf4j/src/main/java/org/pf4j/JarPluginManager.java b/pf4j/src/main/java/org/pf4j/JarPluginManager.java
new file mode 100644
index 0000000..f280466
--- /dev/null
+++ b/pf4j/src/main/java/org/pf4j/JarPluginManager.java
@@ -0,0 +1,56 @@
+/*
+ * 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 java.nio.file.Path;
+
+/**
+ * It's a {@link PluginManager} that loads each plugin from a {@code jar} file.
+ * Actually, a plugin is a fat jar, a jar which contains classes from all the libraries,
+ * on which your project depends and, of course, the classes of current project.
+ *
+ * @author Decebal Suiu
+ */
+public class JarPluginManager extends DefaultPluginManager {
+
+ public JarPluginManager() {
+ super();
+ }
+
+ public JarPluginManager(Path pluginsRoot) {
+ super(pluginsRoot);
+ }
+
+ @Override
+ protected PluginDescriptorFinder createPluginDescriptorFinder() {
+ return new ManifestPluginDescriptorFinder();
+ }
+
+ @Override
+ protected PluginLoader createPluginLoader() {
+ return new CompoundPluginLoader()
+ .add(new DevelopmentPluginLoader(this), this::isDevelopment)
+ .add(new JarPluginLoader(this), this::isNotDevelopment);
+ }
+
+ @Override
+ protected PluginRepository createPluginRepository() {
+ return new CompoundPluginRepository()
+ .add(new DevelopmentPluginRepository(getPluginsRoot()), this::isDevelopment)
+ .add(new JarPluginRepository(getPluginsRoot()), this::isNotDevelopment);
+ }
+
+}
diff --git a/pf4j/src/main/java/org/pf4j/LegacyExtensionFinder.java b/pf4j/src/main/java/org/pf4j/LegacyExtensionFinder.java
index 99e1313..33adc27 100644
--- a/pf4j/src/main/java/org/pf4j/LegacyExtensionFinder.java
+++ b/pf4j/src/main/java/org/pf4j/LegacyExtensionFinder.java
@@ -20,6 +20,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
+import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL;
@@ -81,11 +82,14 @@ public class LegacyExtensionFinder extends AbstractExtensionFinder {
Set bucket = new HashSet<>();
try {
- Enumeration urls = ((PluginClassLoader) plugin.getPluginClassLoader()).findResources(getExtensionsResource());
- if (urls.hasMoreElements()) {
- collectExtensions(urls, bucket);
- } else {
- log.debug("Cannot find '{}'", getExtensionsResource());
+ log.debug("Read '{}'", getExtensionsResource());
+ ClassLoader pluginClassLoader = plugin.getPluginClassLoader();
+ try (InputStream resourceStream = pluginClassLoader.getResourceAsStream(getExtensionsResource())) {
+ if (resourceStream == null) {
+ log.debug("Cannot find '{}'", getExtensionsResource());
+ } else {
+ collectExtensions(resourceStream, bucket);
+ }
}
debugExtensions(bucket);
@@ -103,9 +107,13 @@ public class LegacyExtensionFinder extends AbstractExtensionFinder {
while (urls.hasMoreElements()) {
URL url = urls.nextElement();
log.debug("Read '{}'", url.getFile());
- try (Reader reader = new InputStreamReader(url.openStream(), StandardCharsets.UTF_8)) {
- LegacyExtensionStorage.read(reader, bucket);
- }
+ collectExtensions(url.openStream(), bucket);
+ }
+ }
+
+ private void collectExtensions(InputStream inputStream, Set bucket) throws IOException {
+ try (Reader reader = new InputStreamReader(inputStream, StandardCharsets.UTF_8)) {
+ LegacyExtensionStorage.read(reader, bucket);
}
}
diff --git a/pf4j/src/main/java/org/pf4j/ManifestPluginDescriptorFinder.java b/pf4j/src/main/java/org/pf4j/ManifestPluginDescriptorFinder.java
index 74cd0f3..650b2d7 100644
--- a/pf4j/src/main/java/org/pf4j/ManifestPluginDescriptorFinder.java
+++ b/pf4j/src/main/java/org/pf4j/ManifestPluginDescriptorFinder.java
@@ -37,19 +37,28 @@ public class ManifestPluginDescriptorFinder implements PluginDescriptorFinder {
private static final Logger log = LoggerFactory.getLogger(ManifestPluginDescriptorFinder.class);
+ public static final String PLUGIN_ID = "Plugin-Id";
+ public static final String PLUGIN_DESCRIPTION = "Plugin-Description";
+ public static final String PLUGIN_CLASS = "Plugin-Class";
+ public static final String PLUGIN_VERSION = "Plugin-Version";
+ public static final String PLUGIN_PROVIDER = "Plugin-Provider";
+ public static final String PLUGIN_DEPENDENCIES = "Plugin-Dependencies";
+ public static final String PLUGIN_REQUIRES = "Plugin-Requires";
+ public static final String PLUGIN_LICENSE = "Plugin-License";
+
@Override
public boolean isApplicable(Path pluginPath) {
return Files.exists(pluginPath) && (Files.isDirectory(pluginPath) || FileUtils.isJarFile(pluginPath));
}
@Override
- public PluginDescriptor find(Path pluginPath) throws PluginException {
+ public PluginDescriptor find(Path pluginPath) {
Manifest manifest = readManifest(pluginPath);
return createPluginDescriptor(manifest);
}
- protected Manifest readManifest(Path pluginPath) throws PluginException {
+ protected Manifest readManifest(Path pluginPath) {
if (FileUtils.isJarFile(pluginPath)) {
try (JarFile jar = new JarFile(pluginPath.toFile())) {
Manifest manifest = jar.getManifest();
@@ -57,28 +66,28 @@ public class ManifestPluginDescriptorFinder implements PluginDescriptorFinder {
return manifest;
}
} catch (IOException e) {
- throw new PluginException(e);
+ throw new PluginRuntimeException(e);
}
}
Path manifestPath = getManifestPath(pluginPath);
if (manifestPath == null) {
- throw new PluginException("Cannot find the manifest path");
+ throw new PluginRuntimeException("Cannot find the manifest path");
}
log.debug("Lookup plugin descriptor in '{}'", manifestPath);
if (Files.notExists(manifestPath)) {
- throw new PluginException("Cannot find '{}' path", manifestPath);
+ throw new PluginRuntimeException("Cannot find '{}' path", manifestPath);
}
try (InputStream input = Files.newInputStream(manifestPath)) {
return new Manifest(input);
} catch (IOException e) {
- throw new PluginException(e);
+ throw new PluginRuntimeException(e);
}
}
- protected Path getManifestPath(Path pluginPath) throws PluginException {
+ protected Path getManifestPath(Path pluginPath) {
if (Files.isDirectory(pluginPath)) {
// legacy (the path is something like "classes/META-INF/MANIFEST.MF")
return FileUtils.findFile(pluginPath,"MANIFEST.MF");
@@ -92,37 +101,37 @@ public class ManifestPluginDescriptorFinder implements PluginDescriptorFinder {
// TODO validate !!!
Attributes attributes = manifest.getMainAttributes();
- String id = attributes.getValue("Plugin-Id");
+ String id = attributes.getValue(PLUGIN_ID);
pluginDescriptor.setPluginId(id);
- String description = attributes.getValue("Plugin-Description");
+ String description = attributes.getValue(PLUGIN_DESCRIPTION);
if (StringUtils.isNullOrEmpty(description)) {
pluginDescriptor.setPluginDescription("");
} else {
pluginDescriptor.setPluginDescription(description);
}
- String clazz = attributes.getValue("Plugin-Class");
+ String clazz = attributes.getValue(PLUGIN_CLASS);
if (StringUtils.isNotNullOrEmpty(clazz)) {
pluginDescriptor.setPluginClass(clazz);
}
- String version = attributes.getValue("Plugin-Version");
+ String version = attributes.getValue(PLUGIN_VERSION);
if (StringUtils.isNotNullOrEmpty(version)) {
pluginDescriptor.setPluginVersion(version);
}
- String provider = attributes.getValue("Plugin-Provider");
+ String provider = attributes.getValue(PLUGIN_PROVIDER);
pluginDescriptor.setProvider(provider);
- String dependencies = attributes.getValue("Plugin-Dependencies");
+ String dependencies = attributes.getValue(PLUGIN_DEPENDENCIES);
pluginDescriptor.setDependencies(dependencies);
- String requires = attributes.getValue("Plugin-Requires");
+ String requires = attributes.getValue(PLUGIN_REQUIRES);
if (StringUtils.isNotNullOrEmpty(requires)) {
pluginDescriptor.setRequires(requires);
}
- pluginDescriptor.setLicense(attributes.getValue("Plugin-License"));
+ pluginDescriptor.setLicense(attributes.getValue(PLUGIN_LICENSE));
return pluginDescriptor;
}
diff --git a/pf4j/src/main/java/org/pf4j/Plugin.java b/pf4j/src/main/java/org/pf4j/Plugin.java
index b648b64..e3dd449 100644
--- a/pf4j/src/main/java/org/pf4j/Plugin.java
+++ b/pf4j/src/main/java/org/pf4j/Plugin.java
@@ -60,21 +60,21 @@ public class Plugin {
* This method is called by the application when the plugin is started.
* See {@link PluginManager#startPlugin(String)}.
*/
- public void start() throws PluginException {
+ public void start() {
}
/**
* This method is called by the application when the plugin is stopped.
* See {@link PluginManager#stopPlugin(String)}.
*/
- public void stop() throws PluginException {
+ public void stop() {
}
/**
* This method is called by the application when the plugin is deleted.
* See {@link PluginManager#deletePlugin(String)}.
*/
- public void delete() throws PluginException {
+ public void delete() {
}
}
diff --git a/pf4j/src/main/java/org/pf4j/PluginAlreadyLoadedException.java b/pf4j/src/main/java/org/pf4j/PluginAlreadyLoadedException.java
index adfd90b..411756c 100644
--- a/pf4j/src/main/java/org/pf4j/PluginAlreadyLoadedException.java
+++ b/pf4j/src/main/java/org/pf4j/PluginAlreadyLoadedException.java
@@ -20,7 +20,7 @@ import java.nio.file.Path;
/**
* @author Decebal Suiu
*/
-public class PluginAlreadyLoadedException extends PluginException {
+public class PluginAlreadyLoadedException extends PluginRuntimeException {
private final String pluginId;
private final Path pluginPath;
diff --git a/pf4j/src/main/java/org/pf4j/PluginClasspath.java b/pf4j/src/main/java/org/pf4j/PluginClasspath.java
index 57ff9bf..757740c 100644
--- a/pf4j/src/main/java/org/pf4j/PluginClasspath.java
+++ b/pf4j/src/main/java/org/pf4j/PluginClasspath.java
@@ -22,14 +22,15 @@ import java.util.Set;
/**
* The classpath of the plugin.
- * It contains {@code classes} directories and {@code lib} directories (directories that contains jars).
+ * It contains {@code classes} directories (directories that contain classes files)
+ * and {@code jars} directories (directories that contain jars files).
*
* @author Decebal Suiu
*/
public class PluginClasspath {
private Set classesDirectories = new HashSet<>();
- private Set libDirectories = new HashSet<>();
+ private Set jarsDirectories = new HashSet<>();
public Set getClassesDirectories() {
return classesDirectories;
@@ -45,16 +46,16 @@ public class PluginClasspath {
return this;
}
- public Set getLibDirectories() {
- return libDirectories;
+ public Set getJarsDirectories() {
+ return jarsDirectories;
}
- public PluginClasspath addLibDirectories(String... libDirectories) {
- return addLibDirectories(Arrays.asList(libDirectories));
+ public PluginClasspath addJarsDirectories(String... jarsDirectories) {
+ return addJarsDirectories(Arrays.asList(jarsDirectories));
}
- public PluginClasspath addLibDirectories(Collection libDirectories) {
- this.libDirectories.addAll(libDirectories);
+ public PluginClasspath addJarsDirectories(Collection jarsDirectories) {
+ this.jarsDirectories.addAll(jarsDirectories);
return this;
}
diff --git a/pf4j/src/main/java/org/pf4j/PluginDescriptorFinder.java b/pf4j/src/main/java/org/pf4j/PluginDescriptorFinder.java
index 3b9f600..35185af 100644
--- a/pf4j/src/main/java/org/pf4j/PluginDescriptorFinder.java
+++ b/pf4j/src/main/java/org/pf4j/PluginDescriptorFinder.java
@@ -29,12 +29,9 @@ public interface PluginDescriptorFinder {
/**
* Returns true if this finder is applicable to the given {@link Path}.
- *
- * @param pluginPath
- * @return
*/
boolean isApplicable(Path pluginPath);
- PluginDescriptor find(Path pluginPath) throws PluginException;
+ PluginDescriptor find(Path pluginPath);
}
diff --git a/pf4j/src/main/java/org/pf4j/PluginManager.java b/pf4j/src/main/java/org/pf4j/PluginManager.java
index 6bb6085..a937f22 100644
--- a/pf4j/src/main/java/org/pf4j/PluginManager.java
+++ b/pf4j/src/main/java/org/pf4j/PluginManager.java
@@ -69,8 +69,8 @@ public interface PluginManager {
* Load a plugin.
*
* @param pluginPath the plugin location
- * @return the pluginId of the installed plugin as specified in
- * its {@linkplain PluginDescriptor metadata}; or {@code null}
+ * @return the pluginId of the installed plugin as specified in its {@linkplain PluginDescriptor metadata}
+ * @throws PluginRuntimeException if something goes wrong
*/
String loadPlugin(Path pluginPath);
@@ -83,6 +83,7 @@ public interface PluginManager {
* Start the specified plugin and its dependencies.
*
* @return the plugin state
+ * @throws PluginRuntimeException if something goes wrong
*/
PluginState startPlugin(String pluginId);
@@ -95,6 +96,7 @@ public interface PluginManager {
* Stop the specified plugin and its dependencies.
*
* @return the plugin state
+ * @throws PluginRuntimeException if something goes wrong
*/
PluginState stopPlugin(String pluginId);
@@ -103,6 +105,7 @@ public interface PluginManager {
*
* @param pluginId the unique plugin identifier, specified in its metadata
* @return true if the plugin was unloaded
+ * @throws PluginRuntimeException if something goes wrong
*/
boolean unloadPlugin(String pluginId);
@@ -111,6 +114,7 @@ public interface PluginManager {
*
* @param pluginId the unique plugin identifier, specified in its metadata
* @return true if plugin is disabled
+ * @throws PluginRuntimeException if something goes wrong
*/
boolean disablePlugin(String pluginId);
@@ -119,6 +123,7 @@ public interface PluginManager {
*
* @param pluginId the unique plugin identifier, specified in its metadata
* @return true if plugin is enabled
+ * @throws PluginRuntimeException if something goes wrong
*/
boolean enablePlugin(String pluginId);
@@ -127,6 +132,7 @@ public interface PluginManager {
*
* @param pluginId the unique plugin identifier, specified in its metadata
* @return true if the plugin was deleted
+ * @throws PluginRuntimeException if something goes wrong
*/
boolean deletePlugin(String pluginId);
@@ -134,9 +140,9 @@ public interface PluginManager {
List> getExtensionClasses(String pluginId);
- List> getExtensionClasses(Class type);
+ List> getExtensionClasses(Class type);
- List> getExtensionClasses(Class type, String pluginId);
+ List> getExtensionClasses(Class type, String pluginId);
List getExtensions(Class type);
@@ -153,6 +159,20 @@ public interface PluginManager {
*/
RuntimeMode getRuntimeMode();
+ /**
+ * Returns {@code true} if the runtime mode is {@code RuntimeMode.DEVELOPMENT}.
+ */
+ default boolean isDevelopment() {
+ return RuntimeMode.DEVELOPMENT.equals(getRuntimeMode());
+ }
+
+ /**
+ * Returns {@code true} if the runtime mode is not {@code RuntimeMode.DEVELOPMENT}.
+ */
+ default boolean isNotDevelopment() {
+ return !isDevelopment();
+ }
+
/**
* Retrieves the {@link PluginWrapper} that loaded the given class 'clazz'.
*/
@@ -180,7 +200,8 @@ public interface PluginManager {
String getSystemVersion();
/**
- * Gets the path of the folder where plugins are installed
+ * Gets the path of the folder where plugins are installed.
+ *
* @return Path of plugins root
*/
Path getPluginsRoot();
diff --git a/pf4j/src/main/java/org/pf4j/PluginRepository.java b/pf4j/src/main/java/org/pf4j/PluginRepository.java
index f3617cd..6bc2356 100644
--- a/pf4j/src/main/java/org/pf4j/PluginRepository.java
+++ b/pf4j/src/main/java/org/pf4j/PluginRepository.java
@@ -19,7 +19,7 @@ import java.nio.file.Path;
import java.util.List;
/**
- * Directory that contains plugins. A plugin could be a zip file.
+ * Directory that contains plugins. A plugin could be a {@code directory}, @code zip} or {@code jar} file.
*
* @author Decebal Suiu
* @author Mário Franco
@@ -29,7 +29,7 @@ public interface PluginRepository {
/**
* List all plugin paths.
*
- * @return a list of files
+ * @return a list with paths
*/
List getPluginPaths();
@@ -38,6 +38,7 @@ public interface PluginRepository {
*
* @param pluginPath the plugin path
* @return true if deleted
+ * @throws PluginRuntimeException if something goes wrong
*/
boolean deletePluginPath(Path pluginPath);
diff --git a/pf4j/src/main/java/org/pf4j/PluginException.java b/pf4j/src/main/java/org/pf4j/PluginRuntimeException.java
similarity index 72%
rename from pf4j/src/main/java/org/pf4j/PluginException.java
rename to pf4j/src/main/java/org/pf4j/PluginRuntimeException.java
index d1ba6f2..5d5ede9 100644
--- a/pf4j/src/main/java/org/pf4j/PluginException.java
+++ b/pf4j/src/main/java/org/pf4j/PluginRuntimeException.java
@@ -23,29 +23,25 @@ import org.pf4j.util.StringUtils;
*
* @author Decebal Suiu
*/
-public class PluginException extends Exception {
+public class PluginRuntimeException extends RuntimeException {
- public PluginException() {
+ public PluginRuntimeException() {
super();
}
- public PluginException(String message) {
+ public PluginRuntimeException(String message) {
super(message);
}
- public PluginException(Throwable cause) {
+ public PluginRuntimeException(Throwable cause) {
super(cause);
}
- public PluginException(String message, Throwable cause) {
- super(message, cause);
- }
-
- public PluginException(Throwable cause, String message, Object... args) {
+ public PluginRuntimeException(Throwable cause, String message, Object... args) {
super(StringUtils.format(message, args), cause);
}
- public PluginException(String message, Object... args) {
+ public PluginRuntimeException(String message, Object... args) {
super(StringUtils.format(message, args));
}
diff --git a/pf4j/src/main/java/org/pf4j/PluginStatusProvider.java b/pf4j/src/main/java/org/pf4j/PluginStatusProvider.java
index dda5f82..46967b2 100644
--- a/pf4j/src/main/java/org/pf4j/PluginStatusProvider.java
+++ b/pf4j/src/main/java/org/pf4j/PluginStatusProvider.java
@@ -33,16 +33,16 @@ public interface PluginStatusProvider {
* Disables a plugin from being loaded.
*
* @param pluginId the unique plugin identifier, specified in its metadata
- * @return true if plugin is disabled
+ * @throws PluginRuntimeException if something goes wrong
*/
- boolean disablePlugin(String pluginId);
+ void disablePlugin(String pluginId);
/**
* Enables a plugin that has previously been disabled.
*
* @param pluginId the unique plugin identifier, specified in its metadata
- * @return true if plugin is enabled
+ * @throws PluginRuntimeException if something goes wrong
*/
- boolean enablePlugin(String pluginId);
+ void enablePlugin(String pluginId);
}
diff --git a/pf4j/src/main/java/org/pf4j/PluginWrapper.java b/pf4j/src/main/java/org/pf4j/PluginWrapper.java
index c7d93ca..a9aa147 100644
--- a/pf4j/src/main/java/org/pf4j/PluginWrapper.java
+++ b/pf4j/src/main/java/org/pf4j/PluginWrapper.java
@@ -41,6 +41,7 @@ public class PluginWrapper {
this.pluginClassLoader = pluginClassLoader;
pluginState = PluginState.CREATED;
+ runtimeMode = pluginManager.getRuntimeMode();
}
/**
@@ -120,11 +121,9 @@ public class PluginWrapper {
}
PluginWrapper other = (PluginWrapper) obj;
- if (!descriptor.getPluginId().equals(other.descriptor.getPluginId())) {
- return false;
- }
- return true;
+ return descriptor.getPluginId().equals(other.descriptor.getPluginId());
+
}
@Override
@@ -136,10 +135,6 @@ public class PluginWrapper {
this.pluginState = pluginState;
}
- void setRuntimeMode(RuntimeMode runtimeMode) {
- this.runtimeMode = runtimeMode;
- }
-
void setPluginFactory(PluginFactory pluginFactory) {
this.pluginFactory = pluginFactory;
}
diff --git a/pf4j/src/main/java/org/pf4j/PropertiesPluginDescriptorFinder.java b/pf4j/src/main/java/org/pf4j/PropertiesPluginDescriptorFinder.java
index 3e9e1c1..6789a5f 100644
--- a/pf4j/src/main/java/org/pf4j/PropertiesPluginDescriptorFinder.java
+++ b/pf4j/src/main/java/org/pf4j/PropertiesPluginDescriptorFinder.java
@@ -36,7 +36,16 @@ public class PropertiesPluginDescriptorFinder implements PluginDescriptorFinder
private static final Logger log = LoggerFactory.getLogger(PropertiesPluginDescriptorFinder.class);
- private static final String DEFAULT_PROPERTIES_FILE_NAME = "plugin.properties";
+ public static final String DEFAULT_PROPERTIES_FILE_NAME = "plugin.properties";
+
+ public static final String PLUGIN_ID = "plugin.id";
+ public static final String PLUGIN_DESCRIPTION = "plugin.description";
+ public static final String PLUGIN_CLASS = "plugin.class";
+ public static final String PLUGIN_VERSION = "plugin.version";
+ public static final String PLUGIN_PROVIDER = "plugin.provider";
+ public static final String PLUGIN_DEPENDENCIES = "plugin.dependencies";
+ public static final String PLUGIN_REQUIRES = "plugin.requires";
+ public static final String PLUGIN_LICENSE = "plugin.license";
protected String propertiesFileName;
@@ -54,34 +63,34 @@ public class PropertiesPluginDescriptorFinder implements PluginDescriptorFinder
}
@Override
- public PluginDescriptor find(Path pluginPath) throws PluginException {
+ public PluginDescriptor find(Path pluginPath) {
Properties properties = readProperties(pluginPath);
return createPluginDescriptor(properties);
}
- protected Properties readProperties(Path pluginPath) throws PluginException {
+ protected Properties readProperties(Path pluginPath) {
Path propertiesPath = getPropertiesPath(pluginPath, propertiesFileName);
if (propertiesPath == null) {
- throw new PluginException("Cannot find the properties path");
+ throw new PluginRuntimeException("Cannot find the properties path");
}
log.debug("Lookup plugin descriptor in '{}'", propertiesPath);
if (Files.notExists(propertiesPath)) {
- throw new PluginException("Cannot find '{}' path", propertiesPath);
+ throw new PluginRuntimeException("Cannot find '{}' path", propertiesPath);
}
Properties properties = new Properties();
try (InputStream input = Files.newInputStream(propertiesPath)) {
properties.load(input);
} catch (IOException e) {
- throw new PluginException(e);
+ throw new PluginRuntimeException(e);
}
return properties;
}
- protected Path getPropertiesPath(Path pluginPath, String propertiesFileName) throws PluginException {
+ protected Path getPropertiesPath(Path pluginPath, String propertiesFileName) {
if (Files.isDirectory(pluginPath)) {
return pluginPath.resolve(Paths.get(propertiesFileName));
} else {
@@ -89,7 +98,7 @@ public class PropertiesPluginDescriptorFinder implements PluginDescriptorFinder
try {
return FileUtils.getPath(pluginPath, propertiesFileName);
} catch (IOException e) {
- throw new PluginException(e);
+ throw new PluginRuntimeException(e);
}
}
}
@@ -98,38 +107,38 @@ public class PropertiesPluginDescriptorFinder implements PluginDescriptorFinder
DefaultPluginDescriptor pluginDescriptor = createPluginDescriptorInstance();
// TODO validate !!!
- String id = properties.getProperty("plugin.id");
+ String id = properties.getProperty(PLUGIN_ID);
pluginDescriptor.setPluginId(id);
- String description = properties.getProperty("plugin.description");
+ String description = properties.getProperty(PLUGIN_DESCRIPTION);
if (StringUtils.isNullOrEmpty(description)) {
pluginDescriptor.setPluginDescription("");
} else {
pluginDescriptor.setPluginDescription(description);
}
- String clazz = properties.getProperty("plugin.class");
+ String clazz = properties.getProperty(PLUGIN_CLASS);
if (StringUtils.isNotNullOrEmpty(clazz)) {
pluginDescriptor.setPluginClass(clazz);
}
- String version = properties.getProperty("plugin.version");
+ String version = properties.getProperty(PLUGIN_VERSION);
if (StringUtils.isNotNullOrEmpty(version)) {
pluginDescriptor.setPluginVersion(version);
}
- String provider = properties.getProperty("plugin.provider");
+ String provider = properties.getProperty(PLUGIN_PROVIDER);
pluginDescriptor.setProvider(provider);
- String dependencies = properties.getProperty("plugin.dependencies");
+ String dependencies = properties.getProperty(PLUGIN_DEPENDENCIES);
pluginDescriptor.setDependencies(dependencies);
- String requires = properties.getProperty("plugin.requires");
+ String requires = properties.getProperty(PLUGIN_REQUIRES);
if (StringUtils.isNotNullOrEmpty(requires)) {
pluginDescriptor.setRequires(requires);
}
- pluginDescriptor.setLicense(properties.getProperty("plugin.license"));
+ pluginDescriptor.setLicense(properties.getProperty(PLUGIN_LICENSE));
return pluginDescriptor;
}
diff --git a/pf4j/src/main/java/org/pf4j/RuntimeMode.java b/pf4j/src/main/java/org/pf4j/RuntimeMode.java
index 1fa9cbd..909cc38 100644
--- a/pf4j/src/main/java/org/pf4j/RuntimeMode.java
+++ b/pf4j/src/main/java/org/pf4j/RuntimeMode.java
@@ -41,7 +41,7 @@ public enum RuntimeMode {
}
}
- private RuntimeMode(final String name, final String... aliases) {
+ RuntimeMode(final String name, final String... aliases) {
this.name = name;
this.aliases = aliases;
}
diff --git a/pf4j/src/main/java/org/pf4j/SingletonExtensionFactory.java b/pf4j/src/main/java/org/pf4j/SingletonExtensionFactory.java
index d339921..725b9a7 100644
--- a/pf4j/src/main/java/org/pf4j/SingletonExtensionFactory.java
+++ b/pf4j/src/main/java/org/pf4j/SingletonExtensionFactory.java
@@ -39,13 +39,14 @@ public class SingletonExtensionFactory extends DefaultExtensionFactory {
}
@Override
- public Object create(Class> extensionClass) {
+ @SuppressWarnings("unchecked")
+ public T create(Class extensionClass) {
String extensionClassName = extensionClass.getName();
if (cache.containsKey(extensionClassName)) {
- return cache.get(extensionClassName);
+ return (T) cache.get(extensionClassName);
}
- Object extension = super.create(extensionClass);
+ T extension = super.create(extensionClass);
if (extensionClassNames.isEmpty() || extensionClassNames.contains(extensionClassName)) {
cache.put(extensionClassName, extension);
}
diff --git a/pf4j/src/main/java/org/pf4j/ZipPluginManager.java b/pf4j/src/main/java/org/pf4j/ZipPluginManager.java
new file mode 100644
index 0000000..a32d156
--- /dev/null
+++ b/pf4j/src/main/java/org/pf4j/ZipPluginManager.java
@@ -0,0 +1,49 @@
+/*
+ * 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;
+
+/**
+ * It's a {@link PluginManager} that loads each plugin from a {@code zip} file.
+ * The structure of the zip file is:
+ *
+ * - {@code lib} directory that contains all dependencies (as jar files); it's optional (no dependencies)
+ *
- {@code classes} directory that contains all plugin's classes
+ *
+ *
+ * @author Decebal Suiu
+ */
+public class ZipPluginManager extends DefaultPluginManager {
+
+ @Override
+ protected PluginDescriptorFinder createPluginDescriptorFinder() {
+ return new PropertiesPluginDescriptorFinder();
+ }
+
+ @Override
+ protected PluginLoader createPluginLoader() {
+ return new CompoundPluginLoader()
+ .add(new DevelopmentPluginLoader(this), this::isDevelopment)
+ .add(new DefaultPluginLoader(this), this::isNotDevelopment);
+ }
+
+ @Override
+ protected PluginRepository createPluginRepository() {
+ return new CompoundPluginRepository()
+ .add(new DevelopmentPluginRepository(getPluginsRoot()), this::isDevelopment)
+ .add(new DefaultPluginRepository(getPluginsRoot()), this::isNotDevelopment);
+ }
+
+}
diff --git a/pf4j/src/main/java/org/pf4j/processor/ExtensionAnnotationProcessor.java b/pf4j/src/main/java/org/pf4j/processor/ExtensionAnnotationProcessor.java
index e0f3513..55bbbc2 100644
--- a/pf4j/src/main/java/org/pf4j/processor/ExtensionAnnotationProcessor.java
+++ b/pf4j/src/main/java/org/pf4j/processor/ExtensionAnnotationProcessor.java
@@ -109,11 +109,7 @@ public class ExtensionAnnotationProcessor extends AbstractProcessor {
String extension = getBinaryName(extensionElement);
for (TypeElement extensionPointElement : extensionPointElements) {
String extensionPoint = getBinaryName(extensionPointElement);
- Set extensionPoints = extensions.get(extensionPoint);
- if (extensionPoints == null) {
- extensionPoints = new TreeSet<>();
- extensions.put(extensionPoint, extensionPoints);
- }
+ Set extensionPoints = extensions.computeIfAbsent(extensionPoint, k -> new TreeSet<>());
extensionPoints.add(extension);
}
}
diff --git a/pf4j/src/main/java/org/pf4j/util/AndFileFilter.java b/pf4j/src/main/java/org/pf4j/util/AndFileFilter.java
index cc74da4..76a17ec 100644
--- a/pf4j/src/main/java/org/pf4j/util/AndFileFilter.java
+++ b/pf4j/src/main/java/org/pf4j/util/AndFileFilter.java
@@ -23,11 +23,9 @@ import java.util.Collections;
import java.util.List;
/**
- * This filter providing conditional AND logic across a list of
- * file filters. This filter returns true
if all filters in the
- * list return true
. Otherwise, it returns false
.
- * Checking of the file filter list stops when the first filter returns
- * false
.
+ * This filter providing conditional AND logic across a list of file filters.
+ * This filter returns {@code true} if all filters in the list return {@code true}. Otherwise, it returns {@code false}.
+ * Checking of the file filter list stops when the first filter returns {@code false}.
*
* @author Decebal Suiu
*/
@@ -37,7 +35,7 @@ public class AndFileFilter implements FileFilter {
private List fileFilters;
public AndFileFilter() {
- this(new ArrayList());
+ this(new ArrayList<>());
}
public AndFileFilter(FileFilter... fileFilters) {
@@ -68,7 +66,7 @@ public class AndFileFilter implements FileFilter {
@Override
public boolean accept(File file) {
- if (this.fileFilters.size() == 0) {
+ if (this.fileFilters.isEmpty()) {
return false;
}
diff --git a/pf4j/src/main/java/org/pf4j/util/DirectedGraph.java b/pf4j/src/main/java/org/pf4j/util/DirectedGraph.java
index 076d67c..1163f91 100644
--- a/pf4j/src/main/java/org/pf4j/util/DirectedGraph.java
+++ b/pf4j/src/main/java/org/pf4j/util/DirectedGraph.java
@@ -44,7 +44,7 @@ public class DirectedGraph {
return;
}
- neighbors.put(vertex, new ArrayList());
+ neighbors.put(vertex, new ArrayList<>());
}
/**
@@ -85,7 +85,7 @@ public class DirectedGraph {
}
public List getNeighbors(V vertex) {
- return containsVertex(vertex) ? neighbors.get(vertex) : new ArrayList();
+ return containsVertex(vertex) ? neighbors.get(vertex) : new ArrayList<>();
}
/**
@@ -101,7 +101,7 @@ public class DirectedGraph {
}
/**
- * Report (as a Map) the in-degree (the number of head ends adjacent to a vertex) of each vertex.
+ * Report (as a {@link Map}) the in-degree (the number of head ends adjacent to a vertex) of each vertex.
*/
public Map inDegree() {
Map result = new HashMap<>();
@@ -181,9 +181,9 @@ public class DirectedGraph {
*/
@Override
public String toString() {
- StringBuffer sb = new StringBuffer();
+ StringBuilder sb = new StringBuilder();
for (V vertex : neighbors.keySet()) {
- sb.append("\n " + vertex + " -> " + neighbors.get(vertex));
+ sb.append("\n ").append(vertex).append(" -> ").append(neighbors.get(vertex));
}
return sb.toString();
diff --git a/pf4j/src/main/java/org/pf4j/util/FileUtils.java b/pf4j/src/main/java/org/pf4j/util/FileUtils.java
index a3e955e..0cb8784 100644
--- a/pf4j/src/main/java/org/pf4j/util/FileUtils.java
+++ b/pf4j/src/main/java/org/pf4j/util/FileUtils.java
@@ -172,17 +172,10 @@ public class FileUtils {
FileTime pluginZipDate = Files.getLastModifiedTime(filePath);
String fileName = filePath.getFileName().toString();
- Path pluginDirectory = filePath.resolveSibling(fileName.substring(0, fileName.lastIndexOf(".")));
+ String directoryName = fileName.substring(0, fileName.lastIndexOf("."));
+ Path pluginDirectory = filePath.resolveSibling(directoryName);
if (!Files.exists(pluginDirectory) || pluginZipDate.compareTo(Files.getLastModifiedTime(pluginDirectory)) > 0) {
- // do not overwrite an old version, remove it
- if (Files.exists(pluginDirectory)) {
- FileUtils.delete(pluginDirectory);
- }
-
- // create root for plugin
- Files.createDirectories(pluginDirectory);
-
// expand '.zip' file
Unzip unzip = new Unzip();
unzip.setSource(filePath.toFile());
diff --git a/pf4j/src/main/java/org/pf4j/util/OrFileFilter.java b/pf4j/src/main/java/org/pf4j/util/OrFileFilter.java
index fccfb7b..5798249 100644
--- a/pf4j/src/main/java/org/pf4j/util/OrFileFilter.java
+++ b/pf4j/src/main/java/org/pf4j/util/OrFileFilter.java
@@ -23,11 +23,9 @@ import java.util.Collections;
import java.util.List;
/**
- * This filter providing conditional OR logic across a list of
- * file filters. This filter returns true
if one filter in the
- * list return true
. Otherwise, it returns false
.
- * Checking of the file filter list stops when the first filter returns
- * true
.
+ * This filter providing conditional OR logic across a list of file filters.
+ * This filter returns {@code true} if one filter in the list return {@code true}. Otherwise, it returns {@code false}.
+ * Checking of the file filter list stops when the first filter returns {@code true}.
*
* @author Decebal Suiu
*/
@@ -37,7 +35,7 @@ public class OrFileFilter implements FileFilter {
private List fileFilters;
public OrFileFilter() {
- this(new ArrayList());
+ this(new ArrayList<>());
}
public OrFileFilter(FileFilter... fileFilters) {
@@ -68,7 +66,7 @@ public class OrFileFilter implements FileFilter {
@Override
public boolean accept(File file) {
- if (this.fileFilters.size() == 0) {
+ if (this.fileFilters.isEmpty()) {
return true;
}
diff --git a/pf4j/src/main/java/org/pf4j/util/Unzip.java b/pf4j/src/main/java/org/pf4j/util/Unzip.java
index 7762e47..afde37a 100644
--- a/pf4j/src/main/java/org/pf4j/util/Unzip.java
+++ b/pf4j/src/main/java/org/pf4j/util/Unzip.java
@@ -63,10 +63,14 @@ public class Unzip {
this.destination = destination;
}
+ /**
+ * Extract the content of zip file ({@code source}) to destination directory.
+ * If destination directory already exists it will be deleted before.
+ */
public void extract() throws IOException {
log.debug("Extract content of '{}' to '{}'", source, destination);
- // delete destination file if exists
+ // delete destination directory if exists
if (destination.exists() && destination.isDirectory()) {
FileUtils.delete(destination.toPath());
}
diff --git a/pf4j/src/test/java/org/pf4j/AbstractExtensionFinderTest.java b/pf4j/src/test/java/org/pf4j/AbstractExtensionFinderTest.java
index 2acabee..6383756 100644
--- a/pf4j/src/test/java/org/pf4j/AbstractExtensionFinderTest.java
+++ b/pf4j/src/test/java/org/pf4j/AbstractExtensionFinderTest.java
@@ -15,9 +15,9 @@
*/
package org.pf4j;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
import org.pf4j.plugin.FailTestPlugin;
import org.pf4j.plugin.TestExtensionPoint;
@@ -28,7 +28,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
-import static org.junit.Assert.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -40,7 +40,7 @@ public class AbstractExtensionFinderTest {
private PluginManager pluginManager;
- @Before
+ @BeforeEach
public void setUp() {
PluginWrapper pluginStarted = mock(PluginWrapper.class);
when(pluginStarted.getPluginClassLoader()).thenReturn(getClass().getClassLoader());
@@ -57,7 +57,7 @@ public class AbstractExtensionFinderTest {
when(pluginManager.getExtensionFactory()).thenReturn(new DefaultExtensionFactory());
}
- @After
+ @AfterEach
public void tearDown() {
pluginManager = null;
}
diff --git a/pf4j/src/test/java/org/pf4j/AbstractPluginManagerTest.java b/pf4j/src/test/java/org/pf4j/AbstractPluginManagerTest.java
new file mode 100644
index 0000000..784d1f9
--- /dev/null
+++ b/pf4j/src/test/java/org/pf4j/AbstractPluginManagerTest.java
@@ -0,0 +1,49 @@
+/*
+ * 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.Test;
+import org.pf4j.plugin.TestExtension;
+import org.pf4j.plugin.TestExtensionPoint;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.Mockito.CALLS_REAL_METHODS;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+/**
+ * @author Decebal Suiu
+ */
+public class AbstractPluginManagerTest {
+
+ @Test
+ public void getExtensionsByType() {
+ AbstractPluginManager pluginManager = mock(AbstractPluginManager.class, CALLS_REAL_METHODS);
+
+ ExtensionFinder extensionFinder = mock(ExtensionFinder.class);
+ List> extensionList = new ArrayList<>(1);
+ extensionList.add(new ExtensionWrapper<>(new ExtensionDescriptor(0, TestExtension.class), new DefaultExtensionFactory()));
+ when(extensionFinder.find(TestExtensionPoint.class)).thenReturn(extensionList);
+
+ pluginManager.extensionFinder = extensionFinder;
+ List extensions = pluginManager.getExtensions(TestExtensionPoint.class);
+ assertEquals(1, extensions.size());
+ }
+
+}
diff --git a/pf4j/src/test/java/org/pf4j/CompoundPluginDescriptorFinderTest.java b/pf4j/src/test/java/org/pf4j/CompoundPluginDescriptorFinderTest.java
index a30a4ff..c16839e 100644
--- a/pf4j/src/test/java/org/pf4j/CompoundPluginDescriptorFinderTest.java
+++ b/pf4j/src/test/java/org/pf4j/CompoundPluginDescriptorFinderTest.java
@@ -15,28 +15,34 @@
*/
package org.pf4j;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
+import org.pf4j.plugin.PluginJar;
import org.pf4j.plugin.PluginZip;
+import org.pf4j.plugin.TestPlugin;
-import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
-import java.util.Arrays;
-import java.util.List;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Properties;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
/**
* @author Decebal Suiu
*/
public class CompoundPluginDescriptorFinderTest {
- @Rule
- public TemporaryFolder pluginsFolder = new TemporaryFolder();
+ @TempDir
+ Path pluginsPath;
@Test
public void add() {
@@ -49,8 +55,8 @@ public class CompoundPluginDescriptorFinderTest {
@Test
public void find() throws Exception {
- Path pluginPath = pluginsFolder.newFolder("test-plugin-1").toPath();
- Files.write(pluginPath.resolve("plugin.properties"), getPlugin1Properties(), StandardCharsets.UTF_8);
+ Path pluginPath = Files.createDirectories(pluginsPath.resolve("test-plugin-1"));
+ storePropertiesToPath(getPlugin1Properties(), pluginPath);
PluginDescriptorFinder descriptorFinder = new CompoundPluginDescriptorFinder()
.add(new PropertiesPluginDescriptorFinder());
@@ -64,31 +70,32 @@ public class CompoundPluginDescriptorFinderTest {
@Test
public void findInJar() throws Exception {
PluginDescriptorFinder descriptorFinder = new CompoundPluginDescriptorFinder()
- .add(new PropertiesPluginDescriptorFinder());
+ .add(new ManifestPluginDescriptorFinder());
- PluginZip pluginJar = new PluginZip.Builder(pluginsFolder.newFile("my-plugin-1.2.3.jar"), "myPlugin")
+ PluginJar pluginJar = new PluginJar.Builder(pluginsPath.resolve("my-plugin-1.2.3.jar"), "myPlugin")
+ .pluginClass(TestPlugin.class.getName())
.pluginVersion("1.2.3")
.build();
PluginDescriptor pluginDescriptor = descriptorFinder.find(pluginJar.path());
assertNotNull(pluginDescriptor);
assertEquals("myPlugin", pluginJar.pluginId());
+ assertEquals(TestPlugin.class.getName(), pluginJar.pluginClass());
assertEquals("1.2.3", pluginJar.pluginVersion());
}
- @Test(expected = PluginException.class)
- public void testNotFound() throws Exception {
+ @Test
+ public void testNotFound() {
PluginDescriptorFinder descriptorFinder = new CompoundPluginDescriptorFinder();
- Path pluginsPath = pluginsFolder.getRoot().toPath();
- descriptorFinder.find(pluginsPath.resolve("test-plugin-3"));
+ assertThrows(PluginRuntimeException.class, () -> descriptorFinder.find(pluginsPath.resolve("test-plugin-3")));
}
@Test
public void testSpaceCharacterInFileName() throws Exception {
- PluginDescriptorFinder descriptorFinder = new PropertiesPluginDescriptorFinder();
- File jar = pluginsFolder.newFile("my plugin-1.2.3.jar");
+ PluginDescriptorFinder descriptorFinder = new CompoundPluginDescriptorFinder()
+ .add(new ManifestPluginDescriptorFinder());
- PluginZip pluginJar = new PluginZip.Builder(jar, "myPlugin")
+ PluginJar pluginJar = new PluginJar.Builder(pluginsPath.resolve("my plugin-1.2.3.jar"), "myPlugin")
.pluginVersion("1.2.3")
.build();
@@ -96,21 +103,24 @@ public class CompoundPluginDescriptorFinderTest {
assertNotNull(pluginDescriptor);
}
- private List getPlugin1Properties() {
- String[] lines = new String[] {
- "plugin.id=test-plugin-1\n"
- + "plugin.version=0.0.1\n"
- + "plugin.description=Test Plugin 1\n"
- + "plugin.provider=Decebal Suiu\n"
- + "plugin.class=org.pf4j.plugin.TestPlugin\n"
- + "plugin.dependencies=test-plugin-2,test-plugin-3@~1.0\n"
- + "plugin.requires=>=1\n"
- + "plugin.license=Apache-2.0\n"
- + "\n"
- + ""
- };
-
- return Arrays.asList(lines);
+ private Properties getPlugin1Properties() {
+ Map 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 void storePropertiesToPath(Properties properties, Path pluginPath) throws IOException {
+ Path path = pluginPath.resolve(PropertiesPluginDescriptorFinder.DEFAULT_PROPERTIES_FILE_NAME);
+ try (Writer writer = new OutputStreamWriter(new FileOutputStream(path.toFile()), StandardCharsets.UTF_8)) {
+ properties.store(writer, "");
+ }
}
}
diff --git a/pf4j/src/test/java/org/pf4j/DefaultExtensionFactoryTest.java b/pf4j/src/test/java/org/pf4j/DefaultExtensionFactoryTest.java
index 71ffa93..150828f 100644
--- a/pf4j/src/test/java/org/pf4j/DefaultExtensionFactoryTest.java
+++ b/pf4j/src/test/java/org/pf4j/DefaultExtensionFactoryTest.java
@@ -15,26 +15,38 @@
*/
package org.pf4j;
-import org.junit.Test;
-import org.pf4j.plugin.TestExtension;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
import org.pf4j.plugin.FailTestExtension;
+import org.pf4j.plugin.TestExtension;
-import static org.junit.Assert.*;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
/**
- *
* @author Mario Franco
*/
public class DefaultExtensionFactoryTest {
+ private ExtensionFactory extensionFactory;
+
+ @BeforeEach
+ public void setUp() {
+ extensionFactory = new DefaultExtensionFactory();
+ }
+
+ @AfterEach
+ public void tearDown() {
+ extensionFactory = null;
+ }
+
/**
* Test of create method, of class DefaultExtensionFactory.
*/
@Test
public void testCreate() {
- DefaultExtensionFactory instance = new DefaultExtensionFactory();
- Object result = instance.create(TestExtension.class);
- assertNotNull(result);
+ assertNotNull(extensionFactory.create(TestExtension.class));
}
/**
@@ -42,9 +54,7 @@ public class DefaultExtensionFactoryTest {
*/
@Test
public void testCreateFailConstructor() {
- DefaultExtensionFactory instance = new DefaultExtensionFactory();
- Object result = instance.create(FailTestExtension.class);
- assertNull(result);
+ assertThrows(PluginRuntimeException.class, () -> extensionFactory.create(FailTestExtension.class));
}
}
diff --git a/pf4j/src/test/java/org/pf4j/DefaultPluginFactoryTest.java b/pf4j/src/test/java/org/pf4j/DefaultPluginFactoryTest.java
index f105aa8..eccfca2 100644
--- a/pf4j/src/test/java/org/pf4j/DefaultPluginFactoryTest.java
+++ b/pf4j/src/test/java/org/pf4j/DefaultPluginFactoryTest.java
@@ -15,15 +15,15 @@
*/
package org.pf4j;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
import org.pf4j.plugin.AnotherFailTestPlugin;
import org.pf4j.plugin.FailTestPlugin;
import org.pf4j.plugin.TestPlugin;
import static org.hamcrest.CoreMatchers.instanceOf;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertThat;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
diff --git a/pf4j/src/test/java/org/pf4j/DefaultPluginManagerTest.java b/pf4j/src/test/java/org/pf4j/DefaultPluginManagerTest.java
index 3e6fd04..8cb9b27 100644
--- a/pf4j/src/test/java/org/pf4j/DefaultPluginManagerTest.java
+++ b/pf4j/src/test/java/org/pf4j/DefaultPluginManagerTest.java
@@ -15,21 +15,21 @@
*/
package org.pf4j;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
+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 java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -38,14 +38,12 @@ public class DefaultPluginManagerTest {
private DefaultPluginManager pluginManager;
private DefaultPluginDescriptor pluginDescriptor;
private PluginWrapper pluginWrapper;
- private Path pluginsPath;
- @Rule
- public TemporaryFolder pluginsFolder = new TemporaryFolder();
+ @TempDir
+ Path pluginsPath;
- @Before
+ @BeforeEach
public void setUp() throws IOException {
- pluginsPath = pluginsFolder.getRoot().toPath();
pluginManager = new DefaultPluginManager(pluginsPath);
pluginDescriptor = new DefaultPluginDescriptor();
@@ -59,7 +57,7 @@ public class DefaultPluginManagerTest {
pluginWrapper = new PluginWrapper(pluginManager, pluginDescriptor, Files.createTempDirectory("test"), getClass().getClassLoader());
}
- @After
+ @AfterEach
public void tearDown() {
pluginManager = null;
pluginDescriptor = null;
@@ -67,24 +65,24 @@ public class DefaultPluginManagerTest {
}
@Test
- public void validateOK() throws PluginException {
+ public void validateOK() {
pluginManager.validatePluginDescriptor(pluginDescriptor);
}
- @Test(expected = PluginException.class)
- public void validateFailsOnId() throws PluginException {
+ @Test
+ public void validateFailsOnId() {
pluginDescriptor.setPluginId("");
- pluginManager.validatePluginDescriptor(pluginDescriptor);
+ assertThrows(PluginRuntimeException.class, () -> pluginManager.validatePluginDescriptor(pluginDescriptor));
}
- @Test(expected = PluginException.class)
- public void validateFailsOnVersion() throws PluginException {
+ @Test
+ public void validateFailsOnVersion() {
pluginDescriptor.setPluginVersion(null);
- pluginManager.validatePluginDescriptor(pluginDescriptor);
+ assertThrows(PluginRuntimeException.class, () -> pluginManager.validatePluginDescriptor(pluginDescriptor));
}
@Test
- public void validateNoPluginClass() throws PluginException {
+ public void validateNoPluginClass() {
pluginManager.validatePluginDescriptor(pluginDescriptor);
assertEquals(Plugin.class.getName(), pluginDescriptor.getPluginClass());
}
@@ -132,7 +130,7 @@ public class DefaultPluginManagerTest {
*/
@Test
public void testPluginDisabledNoStart() throws IOException {
- new PluginZip.Builder(pluginsFolder.newFile("my-plugin-1.2.3.zip"), "myPlugin")
+ new PluginZip.Builder(pluginsPath.resolve("my-plugin-1.2.3.zip"), "myPlugin")
.pluginVersion("1.2.3")
.build();
diff --git a/pf4j/src/test/java/org/pf4j/DefaultPluginRepositoryTest.java b/pf4j/src/test/java/org/pf4j/DefaultPluginRepositoryTest.java
index 4f39f24..c564543 100644
--- a/pf4j/src/test/java/org/pf4j/DefaultPluginRepositoryTest.java
+++ b/pf4j/src/test/java/org/pf4j/DefaultPluginRepositoryTest.java
@@ -15,20 +15,18 @@
*/
package org.pf4j;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
-import java.nio.file.Paths;
import java.util.List;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* @author Mario Franco
@@ -36,25 +34,18 @@ import static org.junit.Assert.assertTrue;
*/
public class DefaultPluginRepositoryTest {
- private Path pluginsPath;
+ @TempDir
+ Path pluginsPath;
- @Rule
- public TemporaryFolder pluginsFolder = new TemporaryFolder();
-
- @Before
+ @BeforeEach
public void setUp() throws IOException {
- pluginsPath = pluginsFolder.getRoot().toPath();
-
- pluginsFolder.newFolder("plugin-1");
+ Path plugin1Path = Files.createDirectory(pluginsPath.resolve("plugin-1"));
// Prove that we can delete a folder with a file inside
- Files.createFile(Paths.get(pluginsFolder.getRoot().getAbsolutePath()).resolve("plugin-1").resolve("myfile"));
+ Files.createFile(plugin1Path.resolve("myfile"));
// Create a zip file for plugin-1 to test that it is deleted when plugin is deleted
- Files.createFile(Paths.get(pluginsFolder.getRoot().getAbsolutePath()).resolve("plugin-1.zip"));
- pluginsFolder.newFolder("plugin-2");
- pluginsFolder.newFolder("plugin-3");
- // standard maven/gradle bin folder - these should be skipped in development mode because the cause errors
- pluginsFolder.newFolder("target");
- pluginsFolder.newFolder("build");
+ Files.createFile(pluginsPath.resolve("plugin-1.zip"));
+ Files.createDirectory(pluginsPath.resolve("plugin-2"));
+ Files.createDirectory(pluginsPath.resolve("plugin-3"));
}
/**
@@ -62,29 +53,14 @@ public class DefaultPluginRepositoryTest {
*/
@Test
public void testGetPluginArchives() {
- PluginRepository repository = new DefaultPluginRepository(pluginsPath, false);
+ PluginRepository repository = new DefaultPluginRepository(pluginsPath);
List pluginPaths = repository.getPluginPaths();
- assertEquals(5, pluginPaths.size());
+ assertEquals(3, pluginPaths.size());
assertPathExists(pluginPaths, pluginsPath.resolve("plugin-1"));
assertPathExists(pluginPaths, pluginsPath.resolve("plugin-2"));
assertPathExists(pluginPaths, pluginsPath.resolve("plugin-3"));
- // when not in development mode we will honor these folders
- assertPathExists(pluginPaths, pluginsPath.resolve("target"));
- assertPathExists(pluginPaths, pluginsPath.resolve("build"));
- }
-
- @Test
- public void testGetPluginArchivesInDevelopmentMode() {
- PluginRepository repository = new DefaultPluginRepository(pluginsPath, true);
-
- List pluginPaths = repository.getPluginPaths();
-
- // target and build should be ignored
- assertEquals(3, pluginPaths.size());
- assertPathDoesNotExists(pluginPaths, pluginsPath.resolve("target"));
- assertPathDoesNotExists(pluginPaths, pluginsPath.resolve("build"));
}
/**
@@ -92,15 +68,13 @@ public class DefaultPluginRepositoryTest {
*/
@Test
public void testDeletePluginPath() {
- PluginRepository repository = new DefaultPluginRepository(pluginsPath, false);
+ PluginRepository repository = new DefaultPluginRepository(pluginsPath);
assertTrue(Files.exists(pluginsPath.resolve("plugin-1.zip")));
assertTrue(repository.deletePluginPath(pluginsPath.resolve("plugin-1")));
assertFalse(Files.exists(pluginsPath.resolve("plugin-1.zip")));
assertTrue(repository.deletePluginPath(pluginsPath.resolve("plugin-3")));
assertFalse(repository.deletePluginPath(pluginsPath.resolve("plugin-4")));
- assertTrue(repository.deletePluginPath(pluginsPath.resolve("target")));
- assertTrue(repository.deletePluginPath(pluginsPath.resolve("build")));
List pluginPaths = repository.getPluginPaths();
@@ -109,11 +83,7 @@ public class DefaultPluginRepositoryTest {
}
private void assertPathExists(List paths, Path path) {
- assertTrue("The directory must contain the file " + path, paths.contains(path));
- }
-
- private void assertPathDoesNotExists(List paths, Path path) {
- assertFalse("The directory must not contain the file " + path, paths.contains(path));
+ assertTrue(paths.contains(path), "The directory must contain the file " + path);
}
}
diff --git a/pf4j/src/test/java/org/pf4j/DefaultPluginStatusProviderTest.java b/pf4j/src/test/java/org/pf4j/DefaultPluginStatusProviderTest.java
index b3f8d2b..e766735 100644
--- a/pf4j/src/test/java/org/pf4j/DefaultPluginStatusProviderTest.java
+++ b/pf4j/src/test/java/org/pf4j/DefaultPluginStatusProviderTest.java
@@ -15,20 +15,17 @@
*/
package org.pf4j;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
import org.pf4j.util.FileUtils;
-import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* @author Mario Franco
@@ -36,15 +33,8 @@ import static org.junit.Assert.assertTrue;
*/
public class DefaultPluginStatusProviderTest {
- private Path pluginsPath;
-
- @Rule
- public TemporaryFolder pluginsFolder = new TemporaryFolder();
-
- @Before
- public void setUp() {
- pluginsPath = pluginsFolder.getRoot().toPath();
- }
+ @TempDir
+ Path pluginsPath;
@Test
public void testIsPluginDisabled() throws IOException {
@@ -70,58 +60,59 @@ public class DefaultPluginStatusProviderTest {
}
@Test
- public void testDisablePlugin() throws IOException {
+ public void testDisablePlugin() throws Exception {
createEnabledFile();
createDisabledFile();
PluginStatusProvider statusProvider = new DefaultPluginStatusProvider(pluginsPath);
+ statusProvider.disablePlugin("plugin-1");
- assertTrue(statusProvider.disablePlugin("plugin-1"));
assertTrue(statusProvider.isPluginDisabled("plugin-1"));
assertTrue(statusProvider.isPluginDisabled("plugin-2"));
assertTrue(statusProvider.isPluginDisabled("plugin-3"));
}
@Test
- public void testDisablePluginWithEnableEmpty() throws IOException {
+ public void testDisablePluginWithEnableEmpty() throws Exception {
createDisabledFile();
PluginStatusProvider statusProvider = new DefaultPluginStatusProvider(pluginsPath);
+ statusProvider.disablePlugin("plugin-1");
- assertTrue(statusProvider.disablePlugin("plugin-1"));
assertTrue(statusProvider.isPluginDisabled("plugin-1"));
assertTrue(statusProvider.isPluginDisabled("plugin-2"));
assertFalse(statusProvider.isPluginDisabled("plugin-3"));
}
@Test
- public void testEnablePlugin() throws IOException {
+ public void testEnablePlugin() throws Exception {
createEnabledFile();
PluginStatusProvider statusProvider = new DefaultPluginStatusProvider(pluginsPath);
+ statusProvider.enablePlugin("plugin-2");
- assertTrue(statusProvider.enablePlugin("plugin-2"));
assertFalse(statusProvider.isPluginDisabled("plugin-1"));
assertFalse(statusProvider.isPluginDisabled("plugin-2"));
assertTrue(statusProvider.isPluginDisabled("plugin-3"));
}
@Test
- public void testEnablePluginWithEnableEmpty() {
+ public void testEnablePluginWithEnableEmpty() throws Exception{
PluginStatusProvider statusProvider = new DefaultPluginStatusProvider(pluginsPath);
+ statusProvider.enablePlugin("plugin-2");
- assertTrue(statusProvider.enablePlugin("plugin-2"));
assertFalse(statusProvider.isPluginDisabled("plugin-1"));
assertFalse(statusProvider.isPluginDisabled("plugin-2"));
assertFalse(statusProvider.isPluginDisabled("plugin-3"));
}
@Test
- public void testDisablePluginWithoutDisabledFile() {
+ public void testDisablePluginWithoutDisabledFile() throws Exception {
PluginStatusProvider statusProvider = new DefaultPluginStatusProvider(pluginsPath);
assertFalse(statusProvider.isPluginDisabled("plugin-1"));
- assertTrue(statusProvider.disablePlugin("plugin-1"));
+
+ statusProvider.disablePlugin("plugin-1");
assertTrue(statusProvider.isPluginDisabled("plugin-1"));
}
@@ -129,8 +120,8 @@ public class DefaultPluginStatusProviderTest {
List disabledPlugins = new ArrayList<>();
disabledPlugins.add("plugin-2");
- File disabledFile = pluginsFolder.newFile("disabled.txt");
- FileUtils.writeLines(disabledPlugins, disabledFile);
+ Path disabledPath = pluginsPath.resolve("disabled.txt");
+ FileUtils.writeLines(disabledPlugins, disabledPath.toFile());
}
private void createEnabledFile() throws IOException {
@@ -138,8 +129,8 @@ public class DefaultPluginStatusProviderTest {
enabledPlugins.add("plugin-1");
enabledPlugins.add("plugin-2");
- File enabledFile = pluginsFolder.newFile("enabled.txt");
- FileUtils.writeLines(enabledPlugins, enabledFile);
+ Path enabledPath = pluginsPath.resolve("enabled.txt");
+ FileUtils.writeLines(enabledPlugins, enabledPath.toFile());
}
}
diff --git a/pf4j/src/test/java/org/pf4j/DefaultVersionManagerTest.java b/pf4j/src/test/java/org/pf4j/DefaultVersionManagerTest.java
index 795d3cf..3a277db 100644
--- a/pf4j/src/test/java/org/pf4j/DefaultVersionManagerTest.java
+++ b/pf4j/src/test/java/org/pf4j/DefaultVersionManagerTest.java
@@ -16,10 +16,12 @@
package org.pf4j;
import com.github.zafarkhaja.semver.ParseException;
-import org.junit.Before;
-import org.junit.Test;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
-import static org.junit.Assert.*;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* @author Decebal Suiu
@@ -28,7 +30,7 @@ public class DefaultVersionManagerTest {
private VersionManager versionManager;
- @Before
+ @BeforeEach
public void init() {
versionManager = new DefaultVersionManager();
}
@@ -39,14 +41,14 @@ public class DefaultVersionManagerTest {
assertTrue(versionManager.checkVersionConstraint("1.4.3", ">=1.4.0 & <1.6.0")); // range
}
- @Test(expected = IllegalArgumentException.class)
+ @Test
public void nullOrEmptyVersion() {
- assertFalse(versionManager.checkVersionConstraint(null, ">2.0.0"));
+ assertThrows(IllegalArgumentException.class, () -> versionManager.checkVersionConstraint(null, ">2.0.0"));
}
- @Test(expected = ParseException.class)
+ @Test
public void invalidVersion() {
- assertFalse(versionManager.checkVersionConstraint("1.0", ">2.0.0"));
+ assertThrows(ParseException.class, () -> versionManager.checkVersionConstraint("1.0", ">2.0.0"));
}
@Test
diff --git a/pf4j/src/test/java/org/pf4j/DependencyResolverTest.java b/pf4j/src/test/java/org/pf4j/DependencyResolverTest.java
index f7752d4..6e35780 100644
--- a/pf4j/src/test/java/org/pf4j/DependencyResolverTest.java
+++ b/pf4j/src/test/java/org/pf4j/DependencyResolverTest.java
@@ -15,14 +15,16 @@
*/
package org.pf4j;
-import org.junit.Before;
-import org.junit.Test;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
-import static org.junit.Assert.*;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* @author Decebal Suiu
@@ -31,7 +33,7 @@ public class DependencyResolverTest {
private DependencyResolver resolver;
- @Before
+ @BeforeEach
public void init() {
VersionManager versionManager = new DefaultVersionManager();
resolver = new DependencyResolver(versionManager);
diff --git a/pf4j/src/test/java/org/pf4j/DevelopmentPluginRepositoryTest.java b/pf4j/src/test/java/org/pf4j/DevelopmentPluginRepositoryTest.java
new file mode 100644
index 0000000..20d9129
--- /dev/null
+++ b/pf4j/src/test/java/org/pf4j/DevelopmentPluginRepositoryTest.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2012-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.pf4j;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+
+/**
+ * @author Decebal Suiu
+ */
+public class DevelopmentPluginRepositoryTest {
+
+ @TempDir
+ Path pluginsPath;
+
+ @BeforeEach
+ public void setUp() throws IOException {
+ // standard maven/gradle bin folder - these should be skipped in development mode because the cause errors
+ Files.createDirectory(pluginsPath.resolve(DevelopmentPluginRepository.MAVEN_BUILD_DIR));
+ Files.createDirectory(pluginsPath.resolve(DevelopmentPluginRepository.GRADLE_BUILD_DIR));
+ }
+
+ @Test
+ public void testGetPluginArchivesInDevelopmentMode() {
+ PluginRepository repository = new DevelopmentPluginRepository(pluginsPath);
+
+ List pluginPaths = repository.getPluginPaths();
+
+ // target and build should be ignored
+ assertEquals(0, pluginPaths.size());
+ assertPathDoesNotExists(pluginPaths, pluginsPath.resolve(DevelopmentPluginRepository.MAVEN_BUILD_DIR));
+ assertPathDoesNotExists(pluginPaths, pluginsPath.resolve(DevelopmentPluginRepository.GRADLE_BUILD_DIR));
+ }
+
+ private void assertPathDoesNotExists(List paths, Path path) {
+ assertFalse(paths.contains(path), "The directory must not contain the file " + path);
+ }
+
+}
diff --git a/pf4j/src/test/java/org/pf4j/ExtensionAnnotationProcessorTest.java b/pf4j/src/test/java/org/pf4j/ExtensionAnnotationProcessorTest.java
index 9edd6b9..47efca8 100644
--- a/pf4j/src/test/java/org/pf4j/ExtensionAnnotationProcessorTest.java
+++ b/pf4j/src/test/java/org/pf4j/ExtensionAnnotationProcessorTest.java
@@ -15,13 +15,13 @@
*/
package org.pf4j;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
import org.pf4j.processor.ExtensionAnnotationProcessor;
import java.util.Set;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* @author Mario Franco
diff --git a/pf4j/src/test/java/org/pf4j/JarPluginManagerTest.java b/pf4j/src/test/java/org/pf4j/JarPluginManagerTest.java
new file mode 100644
index 0000000..d9ca90a
--- /dev/null
+++ b/pf4j/src/test/java/org/pf4j/JarPluginManagerTest.java
@@ -0,0 +1,96 @@
+/*
+ * 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.junit.jupiter.api.io.TempDir;
+import org.pf4j.plugin.PluginJar;
+import org.pf4j.plugin.TestExtension;
+import org.pf4j.plugin.TestExtensionPoint;
+import org.pf4j.plugin.TestPlugin;
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+public class JarPluginManagerTest {
+
+ private PluginJar pluginJar;
+ private JarPluginManager pluginManager;
+
+ @TempDir
+ Path pluginsPath;
+
+ @BeforeEach
+ public void setUp() throws IOException {
+ pluginJar = new PluginJar.Builder(pluginsPath.resolve("test-plugin.jar"), "test-plugin")
+ .pluginClass(TestPlugin.class.getName())
+ .pluginVersion("1.2.3")
+ .extension(TestExtension.class.getName())
+ .build();
+
+ pluginManager = new JarPluginManager(pluginsPath);
+ }
+
+ @AfterEach
+ public void tearDown() {
+ pluginJar = null;
+ pluginManager = null;
+ }
+
+ @Test
+ public void getExtensions() {
+ pluginManager.loadPlugins();
+ pluginManager.startPlugins();
+
+ List extensions = pluginManager.getExtensions(TestExtensionPoint.class);
+ assertEquals(1, extensions.size());
+
+ String something = extensions.get(0).saySomething();
+ assertEquals(new TestExtension().saySomething(), something);
+ }
+
+ @Test
+ public void unloadPlugin() throws Exception {
+ pluginManager.loadPlugins();
+
+ assertEquals(1, pluginManager.getPlugins().size());
+
+ boolean unloaded = pluginManager.unloadPlugin(pluginJar.pluginId());
+ assertTrue(unloaded);
+
+ assertTrue(pluginJar.file().exists());
+ }
+
+ @Test
+ public void deletePlugin() throws Exception {
+ pluginManager.loadPlugins();
+
+ assertEquals(1, pluginManager.getPlugins().size());
+
+ boolean deleted = pluginManager.deletePlugin(pluginJar.pluginId());
+ assertTrue(deleted);
+
+ assertFalse(pluginJar.file().exists());
+ }
+
+}
diff --git a/pf4j/src/test/java/org/pf4j/JarPluginRepositoryTest.java b/pf4j/src/test/java/org/pf4j/JarPluginRepositoryTest.java
new file mode 100644
index 0000000..4501223
--- /dev/null
+++ b/pf4j/src/test/java/org/pf4j/JarPluginRepositoryTest.java
@@ -0,0 +1,58 @@
+/*
+ * 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.Test;
+import org.junit.jupiter.api.io.TempDir;
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * @author Decebal Suiu
+ */
+public class JarPluginRepositoryTest {
+
+ @TempDir
+ Path pluginsPath;
+
+ /**
+ * Test of {@link JarPluginRepository#deletePluginPath(Path)} method.
+ */
+ @Test
+ public void testDeletePluginPath() throws Exception {
+ PluginRepository repository = new JarPluginRepository(pluginsPath);
+
+ Path plugin1Path = Files.createDirectory(pluginsPath.resolve("plugin-1"));
+ Path plugin1JarPath = Files.createFile(pluginsPath.resolve("plugin-1.jar"));
+
+ assertFalse(repository.deletePluginPath(plugin1Path));
+
+ List pluginPaths = repository.getPluginPaths();
+ assertEquals(1, pluginPaths.size());
+
+ assertTrue(repository.deletePluginPath(plugin1JarPath));
+
+ pluginPaths = repository.getPluginPaths();
+ assertEquals(0, pluginPaths.size());
+ }
+
+}
diff --git a/pf4j/src/test/java/org/pf4j/LegacyExtensionFinderTest.java b/pf4j/src/test/java/org/pf4j/LegacyExtensionFinderTest.java
new file mode 100644
index 0000000..8f5a727
--- /dev/null
+++ b/pf4j/src/test/java/org/pf4j/LegacyExtensionFinderTest.java
@@ -0,0 +1,73 @@
+/*
+ * 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.Test;
+import org.junit.jupiter.api.condition.EnabledOnOs;
+import org.junit.jupiter.api.io.TempDir;
+import org.pf4j.plugin.PluginJar;
+import org.pf4j.plugin.TestExtension;
+import org.pf4j.plugin.TestPlugin;
+
+import java.nio.file.Path;
+import java.util.Map;
+import java.util.Set;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.contains;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.condition.OS.WINDOWS;
+
+public class LegacyExtensionFinderTest {
+
+ @TempDir
+ Path pluginsPath;
+
+ @Test
+ @EnabledOnOs(WINDOWS)
+ public void shouldUnlockFileAfterReadingExtensionsFromPlugin() throws Exception {
+ PluginJar pluginJar = new PluginJar.Builder(pluginsPath.resolve("test-plugin.jar"), "test-plugin")
+ .pluginClass(TestPlugin.class.getName())
+ .pluginVersion("1.2.3")
+ .extension(TestExtension.class.getName())
+ .build();
+
+ assertTrue(pluginJar.file().exists());
+
+ PluginManager pluginManager = new JarPluginManager(pluginsPath);
+ pluginManager.loadPlugins();
+
+ assertEquals(1, pluginManager.getPlugins().size());
+
+ LegacyExtensionFinder extensionFinder = new LegacyExtensionFinder(pluginManager);
+ Map> pluginsStorages = extensionFinder.readPluginsStorages();
+ assertNotNull(pluginsStorages);
+
+ pluginManager.unloadPlugin(pluginJar.pluginId());
+ boolean fileDeleted = pluginJar.file().delete();
+
+ Set pluginStorages = pluginsStorages.get(pluginJar.pluginId());
+ assertNotNull(pluginStorages);
+ assertEquals(1, pluginStorages.size());
+ assertThat(pluginStorages, contains(TestExtension.class.getName()));
+ assertTrue(fileDeleted);
+ assertFalse(pluginJar.file().exists());
+ }
+
+}
diff --git a/pf4j/src/test/java/org/pf4j/LegacyExtensionStorageTest.java b/pf4j/src/test/java/org/pf4j/LegacyExtensionStorageTest.java
index 57125bd..1acc567 100644
--- a/pf4j/src/test/java/org/pf4j/LegacyExtensionStorageTest.java
+++ b/pf4j/src/test/java/org/pf4j/LegacyExtensionStorageTest.java
@@ -15,7 +15,7 @@
*/
package org.pf4j;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
import org.pf4j.processor.LegacyExtensionStorage;
import java.io.IOException;
@@ -24,7 +24,7 @@ import java.io.StringReader;
import java.util.HashSet;
import java.util.Set;
-import static org.junit.Assert.*;
+import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* @author Decebal Suiu
diff --git a/pf4j/src/test/java/org/pf4j/LoadPluginsTest.java b/pf4j/src/test/java/org/pf4j/LoadPluginsTest.java
index c2917e8..e3dac02 100644
--- a/pf4j/src/test/java/org/pf4j/LoadPluginsTest.java
+++ b/pf4j/src/test/java/org/pf4j/LoadPluginsTest.java
@@ -15,42 +15,42 @@
*/
package org.pf4j;
-import static org.hamcrest.CoreMatchers.containsString;
-import static org.hamcrest.CoreMatchers.equalTo;
-import static org.hamcrest.CoreMatchers.startsWith;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.io.File;
+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 java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-import org.pf4j.plugin.PluginZip;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.startsWith;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
public class LoadPluginsTest {
private DefaultPluginManager pluginManager;
- @Rule
- public TemporaryFolder pluginsFolder = new TemporaryFolder();
+ @TempDir
+ Path pluginsPath;
- @Before
+ @BeforeEach
public void setUp() {
- pluginManager = new DefaultPluginManager(pluginsFolder.getRoot().toPath());
+ pluginManager = new DefaultPluginManager(pluginsPath);
}
@Test
public void load() throws Exception {
- PluginZip pluginZip = new PluginZip.Builder(pluginsFolder.newFile("my-plugin-1.2.3.zip"), "myPlugin")
+ PluginZip pluginZip = new PluginZip.Builder(pluginsPath.resolve("my-plugin-1.2.3.zip"), "myPlugin")
.pluginVersion("1.2.3")
.build();
@@ -64,31 +64,32 @@ public class LoadPluginsTest {
assertEquals(pluginZip.pluginId(), pluginManager.idForPath(pluginZip.unzippedPath()));
}
- @Test(expected = IllegalArgumentException.class)
+ @Test
public void loadNonExisting() {
- pluginManager.loadPlugin(Paths.get("nonexisting"));
+ assertThrows(IllegalArgumentException.class, () -> pluginManager.loadPlugin(Paths.get("nonexisting")));
}
- @Test(expected = PluginAlreadyLoadedException.class)
+ @Test
public void loadTwiceFails() throws Exception {
- PluginZip pluginZip = new PluginZip.Builder(pluginsFolder.newFile("my-plugin-1.2.3.zip"), "myPlugin")
+ PluginZip pluginZip = new PluginZip.Builder(pluginsPath.resolve("my-plugin-1.2.3.zip"), "myPlugin")
.pluginVersion("1.2.3")
.build();
assertNotNull(pluginManager.loadPluginFromPath(pluginZip.path()));
- assertNull(pluginManager.loadPluginFromPath(pluginZip.path()));
+
+ assertThrows(PluginAlreadyLoadedException.class, () -> pluginManager.loadPluginFromPath(pluginZip.path()));
}
@Test
public void loadPluginWithSameIdDifferentPathFails() throws Exception {
String pluginId = "myPlugin";
String pluginVersion = "1.2.3";
- File plugin1Path = pluginsFolder.newFile("my-plugin-1.2.3.zip");
+ Path plugin1Path = pluginsPath.resolve("my-plugin-1.2.3.zip");
PluginZip plugin1 = new PluginZip.Builder(plugin1Path, pluginId)
.pluginVersion(pluginVersion)
.build();
- File plugin2Path = pluginsFolder.newFile("my-plugin-1.2.3-renamed.zip");
+ Path plugin2Path = pluginsPath.resolve("my-plugin-1.2.3-renamed.zip");
PluginZip plugin2 = new PluginZip.Builder(plugin2Path, pluginId)
.pluginVersion(pluginVersion)
.build();
@@ -101,7 +102,7 @@ public class LoadPluginsTest {
// Verify the second plugin is not loaded as it has the same metadata
pluginManager.loadPluginFromPath(plugin2.path());
fail("Expected loadPluginFromPath to fail");
- } catch (PluginException e) {
+ } catch (PluginRuntimeException e) {
// Check the path of the loaded plugin remains the same
PluginWrapper loadedPlugin = pluginManager.getPlugin(pluginId);
assertThat(loadedPlugin.getPluginPath(), equalTo(loadedPlugin1Path));
@@ -122,13 +123,13 @@ public class LoadPluginsTest {
public void loadPluginWithSameIdDifferentVersionsFails() throws Exception {
String pluginId = "myPlugin";
String plugin1Version = "1.2.3";
- File plugin1Path = pluginsFolder.newFile("my-plugin-1.2.3.zip");
+ Path plugin1Path = pluginsPath.resolve("my-plugin-1.2.3.zip");
PluginZip plugin1 = new PluginZip.Builder(plugin1Path, pluginId)
.pluginVersion(plugin1Version)
.build();
String plugin2Version = "2.0.0";
- File plugin2Path = pluginsFolder.newFile("my-plugin-2.0.0.zip");
+ Path plugin2Path = pluginsPath.resolve("my-plugin-2.0.0.zip");
PluginZip plugin2 = new PluginZip.Builder(plugin2Path, pluginId)
.pluginVersion(plugin2Version)
.build();
@@ -140,7 +141,7 @@ public class LoadPluginsTest {
// Verify the second plugin is not loaded as it has the same pluginId
pluginManager.loadPluginFromPath(plugin2.path());
fail("Expected loadPluginFromPath to fail");
- } catch (PluginException e) {
+ } catch (PluginRuntimeException e) {
// Check the path and version of the loaded plugin remain the same
PluginWrapper loadedPlugin = pluginManager.getPlugin(pluginId);
assertThat(loadedPlugin.getPluginPath(), equalTo(loadedPlugin1Path));
@@ -150,7 +151,7 @@ public class LoadPluginsTest {
@Test
public void loadUnloadLoad() throws Exception {
- PluginZip pluginZip = new PluginZip.Builder(pluginsFolder.newFile("my-plugin-1.2.3.zip"), "myPlugin")
+ PluginZip pluginZip = new PluginZip.Builder(pluginsPath.resolve("my-plugin-1.2.3.zip"), "myPlugin")
.pluginVersion("1.2.3")
.build();
@@ -169,7 +170,7 @@ public class LoadPluginsTest {
public void upgrade() throws Exception {
String pluginId = "myPlugin";
- new PluginZip.Builder(pluginsFolder.newFile("my-plugin-1.2.3.zip"), pluginId)
+ new PluginZip.Builder(pluginsPath.resolve("my-plugin-1.2.3.zip"), pluginId)
.pluginVersion("1.2.3")
.build();
@@ -179,7 +180,7 @@ public class LoadPluginsTest {
assertEquals(1, pluginManager.getPlugins().size());
assertEquals(1, pluginManager.getStartedPlugins().size());
- PluginZip pluginZip2 = new PluginZip.Builder(pluginsFolder.newFile("my-plugin-2.0.0.ZIP"), pluginId)
+ PluginZip pluginZip2 = new PluginZip.Builder(pluginsPath.resolve("my-plugin-2.0.0.ZIP"), pluginId)
.pluginVersion("2.0.0")
.build();
@@ -196,12 +197,12 @@ public class LoadPluginsTest {
@Test
public void getRoot() {
- assertEquals(pluginsFolder.getRoot().toPath(), pluginManager.getPluginsRoot());
+ assertEquals(pluginsPath, pluginManager.getPluginsRoot());
}
@Test
- public void notAPlugin() throws Exception {
- pluginsFolder.newFile("not-a-zip");
+ public void notAPlugin() {
+ pluginsPath.resolve("not-a-zip");
pluginManager.loadPlugins();
@@ -210,11 +211,11 @@ public class LoadPluginsTest {
@Test
public void deletePlugin() throws Exception {
- PluginZip pluginZip1 = new PluginZip.Builder(pluginsFolder.newFile("my-plugin-1.2.3.zip"), "myPlugin")
+ PluginZip pluginZip1 = new PluginZip.Builder(pluginsPath.resolve("my-plugin-1.2.3.zip"), "myPlugin")
.pluginVersion("1.2.3")
.build();
- PluginZip pluginZip3 = new PluginZip.Builder(pluginsFolder.newFile("other-3.0.0.Zip"), "other")
+ PluginZip pluginZip3 = new PluginZip.Builder(pluginsPath.resolve("other-3.0.0.Zip"), "other")
.pluginVersion("3.0.0")
.build();
diff --git a/pf4j/src/test/java/org/pf4j/ManifestPluginDescriptorFinderTest.java b/pf4j/src/test/java/org/pf4j/ManifestPluginDescriptorFinderTest.java
index bc4eb5f..468f2fb 100644
--- a/pf4j/src/test/java/org/pf4j/ManifestPluginDescriptorFinderTest.java
+++ b/pf4j/src/test/java/org/pf4j/ManifestPluginDescriptorFinderTest.java
@@ -15,19 +15,23 @@
*/
package org.pf4j;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
+import org.pf4j.plugin.PluginJar;
+import java.io.FileOutputStream;
import java.io.IOException;
-import java.nio.charset.Charset;
+import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
-import java.util.Arrays;
-import java.util.List;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.jar.Manifest;
-import static org.junit.Assert.*;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* @author Mario Franco
@@ -36,42 +40,32 @@ import static org.junit.Assert.*;
public class ManifestPluginDescriptorFinderTest {
private VersionManager versionManager;
- private Path pluginsPath;
- @Rule
- public TemporaryFolder pluginsFolder = new TemporaryFolder();
+ @TempDir
+ Path pluginsPath;
- @Before
+ @BeforeEach
public void setUp() throws IOException {
- pluginsPath = pluginsFolder.getRoot().toPath();
+ Path pluginPath = Files.createDirectories(pluginsPath.resolve("test-plugin-1"));
+ storeManifestToPath(getPlugin1Manifest(), pluginPath);
- Charset charset = Charset.forName("UTF-8");
-
- Path pluginPath = pluginsFolder.newFolder("test-plugin-1", "classes", "META-INF").toPath();
- Files.write(pluginPath.resolve("extensions.idx"), "org.pf4j.demo.hello.HelloPlugin$HelloGreeting".getBytes());
- Files.write(pluginPath.resolve("MANIFEST.MF"), getPlugin1Manifest(), charset);
-
- pluginPath = pluginsFolder.newFolder("test-plugin-2", "classes", "META-INF").toPath();
- Files.write(pluginPath.resolve("extensions.idx"), "org.pf4j.demo.hello.HelloPlugin$HelloGreeting".getBytes());
- Files.write(pluginPath.resolve("MANIFEST.MF"), getPlugin2Manifest(), charset);
+ pluginPath = Files.createDirectories(pluginsPath.resolve("test-plugin-2"));
+ storeManifestToPath(getPlugin2Manifest(), pluginPath);
// empty plugin
- pluginsFolder.newFolder("test-plugin-3");
+ Files.createDirectories(pluginsPath.resolve("test-plugin-3"));
// no plugin class
- pluginPath = pluginsFolder.newFolder("test-plugin-4", "classes", "META-INF").toPath();
- Files.write(pluginPath.resolve("extensions.idx"), "org.pf4j.demo.hello.HelloPlugin$HelloGreeting".getBytes());
- Files.write(pluginPath.resolve("MANIFEST.MF"), getPlugin4Manifest(), charset);
+ pluginPath = Files.createDirectories(pluginsPath.resolve("test-plugin-4"));
+ storeManifestToPath(getPlugin4Manifest(), pluginPath);
// no plugin version
- pluginPath = pluginsFolder.newFolder("test-plugin-5", "classes", "META-INF").toPath();
- Files.write(pluginPath.resolve("extensions.idx"), "org.pf4j.demo.hello.HelloPlugin$HelloGreeting".getBytes());
- Files.write(pluginPath.resolve("MANIFEST.MF"), getPlugin5Manifest(), charset);
+ pluginPath = Files.createDirectories(pluginsPath.resolve("test-plugin-5"));
+ storeManifestToPath(getPlugin5Manifest(), pluginPath);
// no plugin id
- pluginPath = pluginsFolder.newFolder("test-plugin-6", "classes", "META-INF").toPath();
- Files.write(pluginPath.resolve("extensions.idx"), "org.pf4j.demo.hello.HelloPlugin$HelloGreeting".getBytes());
- Files.write(pluginPath.resolve("MANIFEST.MF"), getPlugin6Manifest(), charset);
+ pluginPath = Files.createDirectories(pluginsPath.resolve("test-plugin-6"));
+ storeManifestToPath(getPlugin6Manifest(), pluginPath);
versionManager = new DefaultVersionManager();
}
@@ -110,126 +104,68 @@ public class ManifestPluginDescriptorFinderTest {
/**
* Test of {@link ManifestPluginDescriptorFinder#find(Path)} method.
*/
- @Test(expected = PluginException.class)
- public void testFindNotFound() throws Exception {
+ @Test
+ public void testFindNotFound() {
PluginDescriptorFinder descriptorFinder = new ManifestPluginDescriptorFinder();
- descriptorFinder.find(pluginsPath.resolve("test-plugin-3"));
+ assertThrows(PluginRuntimeException.class, () -> descriptorFinder.find(pluginsPath.resolve("test-plugin-3")));
}
- private List getPlugin1Manifest() {
- String[] lines = new String[] {
- "Manifest-Version: 1.0\n"
- + "Implementation-Title: Test Plugin #1\n"
- + "Implementation-Version: 0.10.0-SNAPSHOT\n"
- + "Archiver-Version: Plexus Archiver\n"
- + "Built-By: Mario Franco\n"
- + "Specification-Title: Test Plugin #1\n"
- + "Implementation-Vendor-Id: org.pf4j.demo\n"
- + "Plugin-Version: 0.0.1\n"
- + "Plugin-Id: test-plugin-1\n"
- + "Plugin-Description: Test Plugin 1\n"
- + "Plugin-Provider: Decebal Suiu\n"
- + "Plugin-Class: org.pf4j.plugin.TestPlugin\n"
- + "Plugin-Dependencies: test-plugin-2,test-plugin-3@~1.0\n"
- + "Plugin-Requires: *\n"
- + "Plugin-License: Apache-2.0\n"
- + "Created-By: Apache Maven 3.0.5\n"
- + "Build-Jdk: 1.8.0_45\n"
- + "Specification-Version: 0.10.0-SNAPSHOT\n"
- + "\n"
- + ""
- };
-
- return Arrays.asList(lines);
+ private Manifest getPlugin1Manifest() {
+ Map 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 List getPlugin2Manifest() {
- String[] lines = new String[] {
- "Manifest-Version: 1.0\n"
- + "Plugin-Dependencies: \n"
- + "Implementation-Title: Test Plugin #2\n"
- + "Implementation-Version: 0.10.0-SNAPSHOT\n"
- + "Archiver-Version: Plexus Archiver\n"
- + "Built-By: Mario Franco\n"
- + "Specification-Title: Test Plugin #2\n"
- + "Implementation-Vendor-Id: org.pf4j.demo\n"
- + "Plugin-Version: 0.0.1\n"
- + "Plugin-Id: test-plugin-2\n"
- + "Plugin-Provider: Decebal Suiu\n"
- + "Plugin-Class: org.pf4j.plugin.TestPlugin\n"
- + "Created-By: Apache Maven 3.0.5\n"
- + "Build-Jdk: 1.8.0_45\n"
- + "Specification-Version: 0.10.0-SNAPSHOT\n"
- + "\n"
- + ""
- };
-
- return Arrays.asList(lines);
+ private Manifest getPlugin2Manifest() {
+ Map 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 List getPlugin4Manifest() {
- String[] lines = new String[] {
- "Manifest-Version: 1.0\n"
- + "Implementation-Title: Test Plugin #4\n"
- + "Implementation-Version: 0.10.0-SNAPSHOT\n"
- + "Archiver-Version: Plexus Archiver\n"
- + "Built-By: Mario Franco\n"
- + "Specification-Title: Test Plugin #4\n"
- + "Implementation-Vendor-Id: org.pf4j.demo\n"
- + "Plugin-Version: 0.0.1\n"
- + "Plugin-Id: test-plugin-2\n"
- + "Plugin-Provider: Decebal Suiu\n"
- + "Created-By: Apache Maven 3.0.5\n"
- + "Build-Jdk: 1.8.0_45\n"
- + "Specification-Version: 0.10.0-SNAPSHOT\n"
- + "\n"
- + ""
- };
-
- return Arrays.asList(lines);
+ private Manifest getPlugin4Manifest() {
+ Map 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 List getPlugin5Manifest() {
- String[] lines = new String[] {
- "Manifest-Version: 1.0\n"
- + "Implementation-Title: Test Plugin #5\n"
- + "Implementation-Version: 0.10.0-SNAPSHOT\n"
- + "Archiver-Version: Plexus Archiver\n"
- + "Built-By: Mario Franco\n"
- + "Specification-Title: Test Plugin #5\n"
- + "Implementation-Vendor-Id: org.pf4j.demo\n"
- + "Plugin-Id: test-plugin-2\n"
- + "Plugin-Provider: Decebal Suiu\n"
- + "Plugin-Class: org.pf4j.plugin.TestPlugin\n"
- + "Created-By: Apache Maven 3.0.5\n"
- + "Build-Jdk: 1.8.0_45\n"
- + "Specification-Version: 0.10.0-SNAPSHOT\n"
- + "\n"
- + ""
- };
-
- return Arrays.asList(lines);
+ private Manifest getPlugin5Manifest() {
+ Map 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 getPlugin6Manifest() {
+ Map 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 List getPlugin6Manifest() {
- String[] lines = new String[] {
- "Manifest-Version: 1.0\n"
- + "Implementation-Title: Test Plugin #6\n"
- + "Implementation-Version: 0.10.0-SNAPSHOT\n"
- + "Archiver-Version: Plexus Archiver\n"
- + "Built-By: Mario Franco\n"
- + "Specification-Title: Test Plugin #6\n"
- + "Implementation-Vendor-Id: org.pf4j.demo\n"
- + "Plugin-Provider: Decebal Suiu\n"
- + "Plugin-Class: org.pf4j.plugin.TestPlugin\n"
- + "Created-By: Apache Maven 3.0.5\n"
- + "Build-Jdk: 1.8.0_45\n"
- + "Specification-Version: 0.10.0-SNAPSHOT\n"
- + "\n"
- + ""
- };
-
- return Arrays.asList(lines);
+ private void storeManifestToPath(Manifest manifest, Path pluginPath) throws IOException {
+ Path path = Files.createDirectory(pluginPath.resolve("META-INF"));
+ try (OutputStream output = new FileOutputStream(path.resolve("MANIFEST.MF").toFile())) {
+ manifest.write(output);
+ }
}
}
diff --git a/pf4j/src/test/java/org/pf4j/PluginDependencyTest.java b/pf4j/src/test/java/org/pf4j/PluginDependencyTest.java
index dbd5fd9..a351c4b 100644
--- a/pf4j/src/test/java/org/pf4j/PluginDependencyTest.java
+++ b/pf4j/src/test/java/org/pf4j/PluginDependencyTest.java
@@ -15,9 +15,12 @@
*/
package org.pf4j;
-import org.junit.Test;
-import static org.junit.Assert.*;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* @author Mario Franco
@@ -32,33 +35,33 @@ public class PluginDependencyTest {
PluginDependency instance = new PluginDependency("test");
assertEquals("test", instance.getPluginId());
assertEquals("*", instance.getPluginVersionSupport());
- assertEquals(false, instance.isOptional());
+ assertFalse(instance.isOptional());
instance = new PluginDependency("test@");
assertEquals("test", instance.getPluginId());
assertEquals("*", instance.getPluginVersionSupport());
- assertEquals(false, instance.isOptional());
+ assertFalse(instance.isOptional());
instance = new PluginDependency("test?");
assertEquals("test", instance.getPluginId());
assertEquals("*", instance.getPluginVersionSupport());
- assertEquals(true, instance.isOptional());
+ assertTrue(instance.isOptional());
instance = new PluginDependency("test?@");
assertEquals("test", instance.getPluginId());
assertEquals("*", instance.getPluginVersionSupport());
- assertEquals(true, instance.isOptional());
+ assertTrue(instance.isOptional());
instance = new PluginDependency("test@1.0");
assertEquals("test", instance.getPluginId());
assertEquals("1.0", instance.getPluginVersionSupport());
- assertEquals(false, instance.isOptional());
+ assertFalse(instance.isOptional());
assertEquals("PluginDependency [pluginId=test, pluginVersionSupport=1.0, optional=false]", instance.toString());
instance = new PluginDependency("test?@1.0");
assertEquals("test", instance.getPluginId());
assertEquals("1.0", instance.getPluginVersionSupport());
- assertEquals(true, instance.isOptional());
+ assertTrue(instance.isOptional());
assertEquals("PluginDependency [pluginId=test, pluginVersionSupport=1.0, optional=true]", instance.toString());
}
diff --git a/pf4j/src/test/java/org/pf4j/PropertiesPluginDescriptorFinderTest.java b/pf4j/src/test/java/org/pf4j/PropertiesPluginDescriptorFinderTest.java
index 377d5ca..bc91a7f 100644
--- a/pf4j/src/test/java/org/pf4j/PropertiesPluginDescriptorFinderTest.java
+++ b/pf4j/src/test/java/org/pf4j/PropertiesPluginDescriptorFinderTest.java
@@ -15,55 +15,57 @@
*/
package org.pf4j;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
+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.plugin.TestPlugin;
+import java.io.FileOutputStream;
import java.io.IOException;
-import java.nio.charset.Charset;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
-import java.util.Arrays;
-import java.util.List;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Properties;
-import static org.junit.Assert.*;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
public class PropertiesPluginDescriptorFinderTest {
private VersionManager versionManager;
- private Path pluginsPath;
- @Rule
- public TemporaryFolder pluginsFolder = new TemporaryFolder();
+ @TempDir
+ Path pluginsPath;
- @Before
+ @BeforeEach
public void setUp() throws IOException {
- pluginsPath = pluginsFolder.getRoot().toPath();
+ Path pluginPath = Files.createDirectory(pluginsPath.resolve("test-plugin-1"));
+ storePropertiesToPath(getPlugin1Properties(), pluginPath);
- Charset charset = Charset.forName("UTF-8");
-
- Path pluginPath = pluginsFolder.newFolder("test-plugin-1").toPath();
- Files.write(pluginPath.resolve("plugin.properties"), getPlugin1Properties(), charset);
-
- pluginPath = pluginsFolder.newFolder("test-plugin-2").toPath();
- Files.write(pluginPath.resolve("plugin.properties"), getPlugin2Properties(), charset);
+ pluginPath = Files.createDirectory(pluginsPath.resolve("test-plugin-2"));
+ storePropertiesToPath(getPlugin2Properties(), pluginPath);
// empty plugin
- pluginsFolder.newFolder("test-plugin-3");
+ Files.createDirectories(pluginsPath.resolve("test-plugin-3"));
// no plugin class
- pluginPath = pluginsFolder.newFolder("test-plugin-4").toPath();
- Files.write(pluginPath.resolve("plugin.properties"), getPlugin4Properties(), charset);
+ pluginPath = Files.createDirectory(pluginsPath.resolve("test-plugin-4"));
+ storePropertiesToPath(getPlugin4Properties(), pluginPath);
// no plugin version
- pluginPath = pluginsFolder.newFolder("test-plugin-5").toPath();
- Files.write(pluginPath.resolve("plugin.properties"), getPlugin5Properties(), charset);
+ pluginPath = Files.createDirectory(pluginsPath.resolve("test-plugin-5"));
+ storePropertiesToPath(getPlugin5Properties(), pluginPath);
// no plugin id
- pluginPath = pluginsFolder.newFolder("test-plugin-6").toPath();
- Files.write(pluginPath.resolve("plugin.properties"), getPlugin6Properties(), charset);
+ pluginPath = Files.createDirectory(pluginsPath.resolve("test-plugin-6"));
+ storePropertiesToPath(getPlugin6Properties(), pluginPath);
versionManager = new DefaultVersionManager();
}
@@ -77,7 +79,7 @@ public class PropertiesPluginDescriptorFinderTest {
assertEquals("test-plugin-1", plugin1.getPluginId());
assertEquals("Test Plugin 1", plugin1.getPluginDescription());
- assertEquals("org.pf4j.plugin.TestPlugin", plugin1.getPluginClass());
+ assertEquals(TestPlugin.class.getName(), plugin1.getPluginClass());
assertEquals("0.0.1", plugin1.getVersion());
assertEquals("Decebal Suiu", plugin1.getProvider());
assertEquals(2, plugin1.getDependencies().size());
@@ -91,7 +93,7 @@ public class PropertiesPluginDescriptorFinderTest {
assertEquals("test-plugin-2", plugin2.getPluginId());
assertEquals("", plugin2.getPluginDescription());
- assertEquals("org.pf4j.plugin.TestPlugin", plugin2.getPluginClass());
+ assertEquals(TestPlugin.class.getName(), plugin2.getPluginClass());
assertEquals("0.0.1", plugin2.getVersion());
assertEquals("Decebal Suiu", plugin2.getProvider());
assertEquals(0, plugin2.getDependencies().size());
@@ -99,98 +101,75 @@ public class PropertiesPluginDescriptorFinderTest {
assertTrue(versionManager.checkVersionConstraint("1.0.0", plugin2.getRequires()));
}
- @Test(expected = PluginException.class)
- public void testNotFound() throws Exception {
+ @Test
+ public void testNotFound() {
PluginDescriptorFinder descriptorFinder = new PropertiesPluginDescriptorFinder();
- descriptorFinder.find(pluginsPath.resolve("test-plugin-3"));
+ assertThrows(PluginRuntimeException.class, () -> descriptorFinder.find(pluginsPath.resolve("test-plugin-3")));
}
- @Test
- public void findInJar() throws Exception {
- PluginZip pluginJar = new PluginZip.Builder(pluginsFolder.newFile("my-plugin-1.2.3.jar"), "myPlugin")
- .pluginVersion("1.2.3")
- .build();
+ private Properties getPlugin1Properties() {
+ Map 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);
+ }
- assertTrue(Files.exists(pluginJar.path()));
+ private Properties getPlugin2Properties() {
+ Map 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, "");
- PluginDescriptorFinder descriptorFinder = new PropertiesPluginDescriptorFinder();
- PluginDescriptor pluginDescriptor = descriptorFinder.find(pluginJar.path());
- assertNotNull(pluginDescriptor);
- assertEquals("myPlugin", pluginJar.pluginId());
- assertEquals("1.2.3", pluginJar.pluginVersion());
+ return PluginZip.createProperties(map);
}
- private List getPlugin1Properties() {
- String[] lines = new String[] {
- "plugin.id=test-plugin-1\n"
- + "plugin.version=0.0.1\n"
- + "plugin.description=Test Plugin 1\n"
- + "plugin.provider=Decebal Suiu\n"
- + "plugin.class=org.pf4j.plugin.TestPlugin\n"
- + "plugin.dependencies=test-plugin-2,test-plugin-3@~1.0\n"
- + "plugin.requires=>=1\n"
- + "plugin.license=Apache-2.0\n"
- + "\n"
- + ""
- };
-
- return Arrays.asList(lines);
- }
+ private Properties getPlugin4Properties() {
+ Map 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, "*");
- private List getPlugin2Properties() {
- String[] lines = new String[] {
- "plugin.id=test-plugin-2\n"
- + "plugin.version=0.0.1\n"
- + "plugin.provider=Decebal Suiu\n"
- + "plugin.class=org.pf4j.plugin.TestPlugin\n"
- + "plugin.dependencies=\n"
- + "\n"
- + ""
- };
-
- return Arrays.asList(lines);
+ return PluginZip.createProperties(map);
}
- private List getPlugin4Properties() {
- String[] lines = new String[] {
- "plugin.id=test-plugin-2\n"
- + "plugin.version=0.0.1\n"
- + "plugin.provider=Decebal Suiu\n"
- + "plugin.dependencies=\n"
- + "plugin.requires=*\n"
- + "\n"
- + ""
- };
-
- return Arrays.asList(lines);
+ private Properties getPlugin5Properties() {
+ Map 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 List getPlugin5Properties() {
- String[] lines = new String[] {
- "plugin.id=test-plugin-2\n"
- + "plugin.provider=Decebal Suiu\n"
- + "plugin.class=org.pf4j.plugin.TestPlugin\n"
- + "plugin.dependencies=\n"
- + "plugin.requires=*\n"
- + "\n"
- + ""
- };
-
- return Arrays.asList(lines);
+ private Properties getPlugin6Properties() {
+ Map 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 List getPlugin6Properties() {
- String[] lines = new String[] {
- "plugin.version=0.0.1\n"
- + "plugin.provider=Decebal Suiu\n"
- + "plugin.class=org.pf4j.plugin.TestPlugin\n"
- + "plugin.dependencies=\n"
- + "plugin.requires=*\n"
- + "\n"
- + ""
- };
-
- return Arrays.asList(lines);
+ private void storePropertiesToPath(Properties properties, Path pluginPath) throws IOException {
+ Path path = pluginPath.resolve(PropertiesPluginDescriptorFinder.DEFAULT_PROPERTIES_FILE_NAME);
+ try (Writer writer = new OutputStreamWriter(new FileOutputStream(path.toFile()), StandardCharsets.UTF_8)) {
+ properties.store(writer, "");
+ }
}
}
diff --git a/pf4j/src/test/java/org/pf4j/SingletonExtensionFactoryTest.java b/pf4j/src/test/java/org/pf4j/SingletonExtensionFactoryTest.java
index 500dd84..80e7ab0 100644
--- a/pf4j/src/test/java/org/pf4j/SingletonExtensionFactoryTest.java
+++ b/pf4j/src/test/java/org/pf4j/SingletonExtensionFactoryTest.java
@@ -15,11 +15,12 @@
*/
package org.pf4j;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
import org.pf4j.plugin.FailTestExtension;
import org.pf4j.plugin.TestExtension;
-import static org.junit.Assert.*;
+import static org.junit.jupiter.api.Assertions.assertNotSame;
+import static org.junit.jupiter.api.Assertions.assertSame;
/**
* @author Decebal Suiu
diff --git a/pf4j/src/test/java/org/pf4j/plugin/ClassDataProvider.java b/pf4j/src/test/java/org/pf4j/plugin/ClassDataProvider.java
new file mode 100644
index 0000000..ff55967
--- /dev/null
+++ b/pf4j/src/test/java/org/pf4j/plugin/ClassDataProvider.java
@@ -0,0 +1,33 @@
+/*
+ * 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.plugin;
+
+/**
+ * Defines the interface for classes that know to supply class data for a class name.
+ * The idea is to have the possibility to retrieve the data for a class from different sources:
+ *
+ * - Class path - the class is already loaded by the class loader
+ * - String - the string (the source code) is compiled dynamically via {@link javax.tools.JavaCompiler}>
+ *
- Generate the source code programmatically using something like {@code https://github.com/square/javapoet}
+ *
+ *
+ * @author Decebal Suiu
+ */
+public interface ClassDataProvider {
+
+ byte[] getClassData(String className);
+
+}
diff --git a/pf4j/src/test/java/org/pf4j/plugin/DefaultClassDataProvider.java b/pf4j/src/test/java/org/pf4j/plugin/DefaultClassDataProvider.java
new file mode 100644
index 0000000..ef0eaf9
--- /dev/null
+++ b/pf4j/src/test/java/org/pf4j/plugin/DefaultClassDataProvider.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2012-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.pf4j.plugin;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * Get class data from the class path.
+ *
+ * @author Decebal Suiu
+ */
+public class DefaultClassDataProvider implements ClassDataProvider {
+
+ @Override
+ public byte[] getClassData(String className) {
+ String path = className.replace('.', '/') + ".class";
+ InputStream classDataStream = getClass().getClassLoader().getResourceAsStream(path);
+ if (classDataStream == null) {
+ throw new RuntimeException("Cannot find class data");
+ }
+
+ try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
+ copyStream(classDataStream, outputStream);
+ return outputStream.toByteArray();
+ } catch (IOException e) {
+ throw new RuntimeException(e.getMessage(), e);
+ }
+ }
+
+ private void copyStream(InputStream in, OutputStream out) throws IOException {
+ byte[] buffer = new byte[1024];
+
+ int bytesRead;
+ while ((bytesRead = in.read(buffer)) != -1) {
+ out.write(buffer, 0, bytesRead);
+ }
+ }
+
+}
diff --git a/pf4j/src/test/java/org/pf4j/plugin/FailTestExtension.java b/pf4j/src/test/java/org/pf4j/plugin/FailTestExtension.java
index 9cc37e0..13b51ee 100644
--- a/pf4j/src/test/java/org/pf4j/plugin/FailTestExtension.java
+++ b/pf4j/src/test/java/org/pf4j/plugin/FailTestExtension.java
@@ -26,4 +26,9 @@ public class FailTestExtension implements TestExtensionPoint {
public FailTestExtension(String name) {
}
+ @Override
+ public String saySomething() {
+ return "I am a fail test extension";
+ }
+
}
diff --git a/pf4j/src/test/java/org/pf4j/plugin/PluginJar.java b/pf4j/src/test/java/org/pf4j/plugin/PluginJar.java
new file mode 100644
index 0000000..a75b68f
--- /dev/null
+++ b/pf4j/src/test/java/org/pf4j/plugin/PluginJar.java
@@ -0,0 +1,200 @@
+/*
+ * 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.plugin;
+
+import org.pf4j.ManifestPluginDescriptorFinder;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+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.
+ * The {@code MANIFEST.MF} file is created on the fly from the information supplied in {@link Builder}.
+ *
+ * @author Decebal Suiu
+ */
+public class PluginJar {
+
+ private final Path path;
+ private final String pluginId;
+ private final String pluginClass;
+ private final String pluginVersion;
+
+ protected PluginJar(Builder builder) {
+ this.path = builder.path;
+ this.pluginId = builder.pluginId;
+ this.pluginClass = builder.pluginClass;
+ this.pluginVersion = builder.pluginVersion;
+ }
+
+ public Path path() {
+ return path;
+ }
+
+ public File file() {
+ return path.toFile();
+ }
+
+ public String pluginClass() {
+ return pluginClass;
+ }
+
+ public String pluginId() {
+ return pluginId;
+ }
+
+ public String pluginVersion() {
+ return pluginVersion;
+ }
+
+ public static Manifest createManifest(Map map) {
+ Manifest manifest = new Manifest();
+ Attributes attributes = manifest.getMainAttributes();
+ attributes.put(Attributes.Name.MANIFEST_VERSION, "1.0.0");
+ for (Map.Entry entry : map.entrySet()) {
+ attributes.put(new Attributes.Name(entry.getKey()), entry.getValue());
+ }
+
+ return manifest;
+ }
+
+ public static class Builder {
+
+ private final Path path;
+ private final String pluginId;
+
+ private String pluginClass;
+ private String pluginVersion;
+ private Map manifestAttributes = new LinkedHashMap<>();
+ private Set extensions = new LinkedHashSet<>();
+ private ClassDataProvider classDataProvider = new DefaultClassDataProvider();
+
+ public Builder(Path path, String pluginId) {
+ 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 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;
+ }
+
+ public Builder extension(String extensionClassName) {
+ extensions.add(extensionClassName);
+
+ return this;
+ }
+
+ public Builder classDataProvider(ClassDataProvider classDataProvider) {
+ this.classDataProvider = classDataProvider;
+
+ return this;
+ }
+
+ public PluginJar build() throws IOException {
+ Manifest manifest = createManifest();
+ try (OutputStream outputStream = new FileOutputStream(path.toFile())) {
+ JarOutputStream jarOutputStream = new JarOutputStream(outputStream, manifest);
+ if (!extensions.isEmpty()) {
+ // add extensions.idx
+ JarEntry jarEntry = new JarEntry("META-INF/extensions.idx");
+ jarOutputStream.putNextEntry(jarEntry);
+ jarOutputStream.write(extensionsAsByteArray());
+ jarOutputStream.closeEntry();
+ // add extensions classes
+ for (String extension : extensions) {
+ String extensionPath = extension.replace('.', '/') + ".class";
+ JarEntry classEntry = new JarEntry(extensionPath);
+ jarOutputStream.putNextEntry(classEntry);
+ jarOutputStream.write(classDataProvider.getClassData(extension));
+ jarOutputStream.closeEntry();
+ }
+ }
+ jarOutputStream.close();
+ }
+
+ return new PluginJar(this);
+ }
+
+ private Manifest createManifest() {
+ Map 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);
+ for (String extension : extensions) {
+ writer.println(extension);
+ }
+ writer.flush();
+
+ return outputStream.toByteArray();
+ }
+ }
+
+ }
+
+}
diff --git a/pf4j/src/test/java/org/pf4j/plugin/PluginZip.java b/pf4j/src/test/java/org/pf4j/plugin/PluginZip.java
index f069365..f34d84a 100644
--- a/pf4j/src/test/java/org/pf4j/plugin/PluginZip.java
+++ b/pf4j/src/test/java/org/pf4j/plugin/PluginZip.java
@@ -15,44 +15,54 @@
*/
package org.pf4j.plugin;
+import org.pf4j.PropertiesPluginDescriptorFinder;
+
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
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;
/**
- * Represents a plugin zip/jar file.
- * The "plugin.properties" file is created on the fly from the information supplied in Builder.
+ * Represents a plugin {@code zip} file.
+ * The {@code plugin.properties} file is created on the fly from the information supplied in {@link Builder}.
*
* @author Decebal Suiu
*/
public class PluginZip {
- private final File file;
+ private final Path path;
private final String pluginId;
+ private final String pluginClass;
private final String pluginVersion;
protected PluginZip(Builder builder) {
- this.file = builder.file;
+ this.path = builder.path;
this.pluginId = builder.pluginId;
+ this.pluginClass = builder.pluginClass;
this.pluginVersion = builder.pluginVersion;
}
- public File file() {
- return file;
+ public Path path() {
+ return path;
}
- public Path path() {
- return file.toPath();
+ public File file() {
+ return path.toFile();
}
public String pluginId() {
return pluginId;
}
+ public String pluginClass() {
+ return pluginClass;
+ }
+
public String pluginVersion() {
return pluginVersion;
}
@@ -64,24 +74,59 @@ public class PluginZip {
return path.getParent().resolve(fileName.substring(0, fileName.length() - 4)); // without ".zip" suffix
}
+ public static Properties createProperties(Map map) {
+ Properties properties = new Properties();
+ properties.putAll(map);
+
+ return properties;
+ }
+
public static class Builder {
- private final File file;
+ private final Path path;
private final String pluginId;
+ private String pluginClass;
private String pluginVersion;
+ private Map properties = new LinkedHashMap<>();
- public Builder(File file, String pluginId) {
- this.file = file;
+ public Builder(Path path, String pluginId) {
+ 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 properties to the {@code properties} file.
+ * As possible attribute name please see {@link PropertiesPluginDescriptorFinder}.
+ */
+ public Builder properties(Map 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;
+ }
+
public PluginZip build() throws IOException {
createPropertiesFile();
@@ -89,15 +134,20 @@ public class PluginZip {
}
protected void createPropertiesFile() throws IOException {
- Properties properties = new Properties();
- properties.setProperty("plugin.id", pluginId);
- properties.setProperty("plugin.version", pluginVersion);
- properties.setProperty("plugin.class", "org.pf4j.plugin.TestPlugin");
-
- ZipOutputStream outputStream = new ZipOutputStream(new FileOutputStream(file));
- ZipEntry propertiesFile = new ZipEntry("plugin.properties");
+ Map map = new LinkedHashMap<>();
+ map.put(PropertiesPluginDescriptorFinder.PLUGIN_ID, pluginId);
+ map.put(PropertiesPluginDescriptorFinder.PLUGIN_VERSION, pluginVersion);
+ if (pluginClass != null) {
+ map.put(PropertiesPluginDescriptorFinder.PLUGIN_CLASS, pluginClass);
+ }
+ if (properties != null) {
+ map.putAll(properties);
+ }
+
+ ZipOutputStream outputStream = new ZipOutputStream(new FileOutputStream(path.toFile()));
+ ZipEntry propertiesFile = new ZipEntry(PropertiesPluginDescriptorFinder.DEFAULT_PROPERTIES_FILE_NAME);
outputStream.putNextEntry(propertiesFile);
- properties.store(outputStream, "");
+ createProperties(map).store(outputStream, "");
outputStream.closeEntry();
outputStream.close();
}
diff --git a/pf4j/src/test/java/org/pf4j/plugin/TestExtension.java b/pf4j/src/test/java/org/pf4j/plugin/TestExtension.java
index 5f48c9a..83bc0b5 100644
--- a/pf4j/src/test/java/org/pf4j/plugin/TestExtension.java
+++ b/pf4j/src/test/java/org/pf4j/plugin/TestExtension.java
@@ -23,4 +23,9 @@ import org.pf4j.Extension;
@Extension
public class TestExtension implements TestExtensionPoint {
+ @Override
+ public String saySomething() {
+ return "I am a test extension";
+ }
+
}
diff --git a/pf4j/src/test/java/org/pf4j/plugin/TestExtensionPoint.java b/pf4j/src/test/java/org/pf4j/plugin/TestExtensionPoint.java
index a33ac40..d29a7ab 100644
--- a/pf4j/src/test/java/org/pf4j/plugin/TestExtensionPoint.java
+++ b/pf4j/src/test/java/org/pf4j/plugin/TestExtensionPoint.java
@@ -22,4 +22,6 @@ import org.pf4j.ExtensionPoint;
*/
public interface TestExtensionPoint extends ExtensionPoint {
+ String saySomething();
+
}
diff --git a/pf4j/src/test/java/org/pf4j/processor/ServiceProviderExtensionStorageTest.java b/pf4j/src/test/java/org/pf4j/processor/ServiceProviderExtensionStorageTest.java
index 2c450a0..ac16b23 100644
--- a/pf4j/src/test/java/org/pf4j/processor/ServiceProviderExtensionStorageTest.java
+++ b/pf4j/src/test/java/org/pf4j/processor/ServiceProviderExtensionStorageTest.java
@@ -16,19 +16,23 @@
package org.pf4j.processor;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
import javax.annotation.processing.Filer;
import javax.tools.FileObject;
import javax.tools.StandardLocation;
import java.io.IOException;
import java.io.StringReader;
-import java.util.*;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;
-import static org.junit.Assert.*;
+import static org.mockito.ArgumentMatchers.any;
import static org.mockito.BDDMockito.given;
-import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
/**
@@ -46,7 +50,6 @@ public class ServiceProviderExtensionStorageTest {
assertThat(entries.contains("World"), is(true));
}
-
@Test
public void ensureReadingExtensionsProducesCorrectListOfExtensions() {
final StringReader file = new StringReader("#hello\n World");
@@ -56,6 +59,7 @@ public class ServiceProviderExtensionStorageTest {
given(processor.getExtensions()).willReturn(extensions);
ServiceProviderExtensionStorage extensionStorage = new ServiceProviderExtensionStorage(processor) {
+
@Override
protected Filer getFiler() {
try {
@@ -72,6 +76,7 @@ public class ServiceProviderExtensionStorageTest {
throw new IllegalStateException("Shouldn't have gotten here");
}
}
+
};
Map> read = extensionStorage.read();
diff --git a/pf4j/src/test/java/org/pf4j/util/DirectedGraphTest.java b/pf4j/src/test/java/org/pf4j/util/DirectedGraphTest.java
new file mode 100644
index 0000000..44b8c54
--- /dev/null
+++ b/pf4j/src/test/java/org/pf4j/util/DirectedGraphTest.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2015 Decebal Suiu
+ *
+ * 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.util;
+
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+/**
+ * @author Decebal Suiu
+ */
+public class DirectedGraphTest {
+
+ private static DirectedGraph graph;
+
+ @BeforeAll
+ public static void setUp() {
+ graph = new DirectedGraph<>();
+
+ // add vertex
+ graph.addVertex('A');
+ graph.addVertex('B');
+ graph.addVertex('C');
+ graph.addVertex('D');
+ graph.addVertex('E');
+ graph.addVertex('F');
+ graph.addVertex('G');
+
+ // add edges
+ graph.addEdge('A', 'B');
+ graph.addEdge('B', 'C');
+ graph.addEdge('B', 'F');
+ graph.addEdge('D', 'E');
+ graph.addEdge('F', 'G');
+ }
+
+ @Test
+ public void reverseTopologicalSort() {
+ List result = graph.reverseTopologicalSort();
+ List expected = Arrays.asList('C', 'G', 'F', 'B', 'A', 'E', 'D');
+ assertEquals(expected, result);
+ }
+
+ @Test
+ public void topologicalSort() {
+ List result = graph.topologicalSort();
+ List expected = Arrays.asList('D', 'E', 'A', 'B', 'F', 'G', 'C');
+ assertEquals(expected, result);
+ }
+
+ @Test
+ public void inDegree() {
+ Map result = graph.inDegree();
+ Map expected = new HashMap<>(7);
+ expected.put('A', 0);
+ expected.put('B', 1);
+ expected.put('C', 1);
+ expected.put('D', 0);
+ expected.put('E', 1);
+ expected.put('F', 1);
+ expected.put('G', 1);
+ assertEquals(expected, result);
+ }
+
+ @Test
+ public void outDegree() {
+ Map result = graph.outDegree();
+ Map expected = new HashMap<>(7);
+ expected.put('A', 1);
+ expected.put('B', 2);
+ expected.put('C', 0);
+ expected.put('D', 1);
+ expected.put('E', 0);
+ expected.put('F', 1);
+ expected.put('G', 0);
+ assertEquals(expected, result);
+ }
+
+}
diff --git a/pf4j/src/test/java/org/pf4j/util/FileUtilsTest.java b/pf4j/src/test/java/org/pf4j/util/FileUtilsTest.java
index 76d0c2e..5f9a3a7 100644
--- a/pf4j/src/test/java/org/pf4j/util/FileUtilsTest.java
+++ b/pf4j/src/test/java/org/pf4j/util/FileUtilsTest.java
@@ -15,24 +15,24 @@
*/
package org.pf4j.util;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
import org.pf4j.plugin.PluginZip;
import java.nio.file.Files;
import java.nio.file.Path;
-import static org.junit.Assert.*;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
public class FileUtilsTest {
- @Rule
- public TemporaryFolder testFolder = new TemporaryFolder();
+ @TempDir
+ Path pluginsPath;
@Test
public void expandIfZip() throws Exception {
- PluginZip pluginZip = new PluginZip.Builder(testFolder.newFile("my-plugin-1.2.3.zip"), "myPlugin")
+ PluginZip pluginZip = new PluginZip.Builder(pluginsPath.resolve("my-plugin-1.2.3.zip"), "myPlugin")
.pluginVersion("1.2.3")
.build();
@@ -41,10 +41,10 @@ public class FileUtilsTest {
assertTrue(Files.exists(unzipped.resolve("plugin.properties")));
// File without .suffix
- Path extra = testFolder.newFile("extra").toPath();
+ Path extra = pluginsPath.resolve("extra");
assertEquals(extra, FileUtils.expandIfZip(extra));
// Folder
- Path folder = testFolder.newFile("folder").toPath();
+ Path folder = pluginsPath.resolve("folder");
assertEquals(folder, FileUtils.expandIfZip(folder));
}
diff --git a/pom.xml b/pom.xml
index d4540d7..add6723 100644
--- a/pom.xml
+++ b/pom.xml
@@ -10,7 +10,7 @@
4.0.0
org.pf4j
pf4j-parent
- 2.7.0-SNAPSHOT
+ 3.0.0-SNAPSHOT
pom
PF4J Parent
Plugin Framework for Java
@@ -43,11 +43,12 @@
UTF-8
- 1.7
+ 8
+
1.7.25
7.1
- 4.12
+ 5.4.0
2.1
2.24.0
2.7
@@ -66,8 +67,6 @@
3.8.0
true
-
- ${java.version}