@@ -15,15 +15,19 @@ | |||
*/ | |||
package org.pf4j; | |||
import static java.lang.annotation.ElementType.TYPE; | |||
import static java.lang.annotation.RetentionPolicy.RUNTIME; | |||
import java.lang.annotation.Documented; | |||
import java.lang.annotation.Inherited; | |||
import java.lang.annotation.Retention; | |||
import java.lang.annotation.Target; | |||
import static java.lang.annotation.ElementType.TYPE; | |||
import static java.lang.annotation.RetentionPolicy.RUNTIME; | |||
/** | |||
* An extension is a class that extends an extension point. | |||
* Use this annotation to mark a class as an extension. | |||
* The extension class must implement the extension point interface or extend the extension point abstract class. | |||
* | |||
* @author Decebal Suiu | |||
*/ | |||
@Retention(RUNTIME) | |||
@@ -32,6 +36,12 @@ import java.lang.annotation.Target; | |||
@Documented | |||
public @interface Extension { | |||
/** | |||
* The order of the extension. | |||
* The ordinal is used to sort the extensions. | |||
* | |||
* @return the order of the extension | |||
*/ | |||
int ordinal() default 0; | |||
/** |
@@ -16,6 +16,10 @@ | |||
package org.pf4j; | |||
/** | |||
* Describes an extension. | |||
* The extension is described by the class and the ordinal (the order of the extension). | |||
* | |||
* @author Decebal Suiu | |||
*/ | |||
public class ExtensionDescriptor { |
@@ -20,6 +20,12 @@ package org.pf4j; | |||
*/ | |||
public interface ExtensionFactory { | |||
/** | |||
* Creates an extension instance. | |||
* | |||
* @param extensionClass the extension class | |||
* @return the extension instance | |||
*/ | |||
<T> T create(Class<T> extensionClass); | |||
} |
@@ -19,6 +19,8 @@ import java.util.List; | |||
import java.util.Set; | |||
/** | |||
* Provides the functionality for finding extensions. | |||
* | |||
* @author Decebal Suiu | |||
*/ | |||
public interface ExtensionFinder { | |||
@@ -34,7 +36,7 @@ public interface ExtensionFinder { | |||
<T> List<ExtensionWrapper<T>> find(Class<T> type, String pluginId); | |||
/** | |||
* Retrieves a list with all extensions found for a plugin | |||
* Retrieves a list with all extensions found for a plugin. | |||
*/ | |||
List<ExtensionWrapper> find(String pluginId); | |||
@@ -17,6 +17,10 @@ package org.pf4j; | |||
/** | |||
* An extension point is a formal declaration in a plugin (or in application API) where customization is allowed. | |||
* It's a place where custom code can be "plugged in". | |||
* <p> | |||
* An extension point is defined by an interface or an abstract class. | |||
* The extension point is used by the application to discover and use the custom implementations. | |||
* | |||
* @author Decebal Suiu | |||
*/ |
@@ -17,6 +17,7 @@ package org.pf4j; | |||
/** | |||
* A wrapper over extension instance. | |||
* It contains the extension descriptor and the extension instance. | |||
* | |||
* @author Decebal Suiu | |||
*/ |
@@ -21,6 +21,9 @@ import org.slf4j.LoggerFactory; | |||
/** | |||
* This class will be extended by all plugins and | |||
* serve as the common class between a plugin and the application. | |||
* <p> | |||
* Create (it's optional) a Plugin class if you are interested in plugin's lifecycle events (start, stop, ...) | |||
* or you want to pass some context to the plugin. | |||
* | |||
* @author Decebal Suiu | |||
*/ |
@@ -18,6 +18,8 @@ package org.pf4j; | |||
import java.nio.file.Path; | |||
/** | |||
* Thrown when a plugin is already loaded. | |||
* | |||
* @author Decebal Suiu | |||
*/ | |||
public class PluginAlreadyLoadedException extends PluginRuntimeException { | |||
@@ -26,7 +28,7 @@ public class PluginAlreadyLoadedException extends PluginRuntimeException { | |||
private final Path pluginPath; | |||
public PluginAlreadyLoadedException(String pluginId, Path pluginPath) { | |||
super("Plugin '{}' already loaded with id '{}'", pluginPath, pluginId); | |||
super("Plugin '{}' already loaded with id '{}'", pluginPath, pluginId); | |||
this.pluginId = pluginId; | |||
this.pluginPath = pluginPath; |
@@ -30,8 +30,10 @@ import java.util.List; | |||
import java.util.Objects; | |||
/** | |||
* One instance of this class should be created by plugin manager for every available plug-in. | |||
* By default, this class loader is a Parent Last ClassLoader - it loads the classes from the plugin's jars | |||
* One instance of this class should be created for every available plug-in. | |||
* It's responsible for loading classes and resources from the plug-in. | |||
* <p> | |||
* By default, this {@link ClassLoader} is a Parent Last ClassLoader - it loads the classes from the plugin's jars | |||
* before delegating to the parent class loader. | |||
* Use {@link #classLoadingStrategy} to change the loading strategy. | |||
* | |||
@@ -44,18 +46,20 @@ public class PluginClassLoader extends URLClassLoader { | |||
private static final String JAVA_PACKAGE_PREFIX = "java."; | |||
private static final String PLUGIN_PACKAGE_PREFIX = "org.pf4j."; | |||
private PluginManager pluginManager; | |||
private PluginDescriptor pluginDescriptor; | |||
private ClassLoadingStrategy classLoadingStrategy; | |||
private final PluginManager pluginManager; | |||
private final PluginDescriptor pluginDescriptor; | |||
private final ClassLoadingStrategy classLoadingStrategy; | |||
public PluginClassLoader(PluginManager pluginManager, PluginDescriptor pluginDescriptor, ClassLoader parent) { | |||
this(pluginManager, pluginDescriptor, parent, ClassLoadingStrategy.PDA); | |||
} | |||
/** | |||
* Creates a new {@link PluginClassLoader} for the given plugin using parent first strategy. | |||
* | |||
* @deprecated Replaced by {@link #PluginClassLoader(PluginManager, PluginDescriptor, ClassLoader, ClassLoadingStrategy)}. | |||
* If {@code parentFirst} is {@code true}, indicates that the parent {@link ClassLoader} should be consulted | |||
* before trying to load the a class through this loader. | |||
* before trying to load a class through this loader. | |||
*/ | |||
@Deprecated | |||
public PluginClassLoader(PluginManager pluginManager, PluginDescriptor pluginDescriptor, ClassLoader parent, boolean parentFirst) { | |||
@@ -63,7 +67,12 @@ public class PluginClassLoader extends URLClassLoader { | |||
} | |||
/** | |||
* classloading according to {@code classLoadingStrategy} | |||
* Creates a new {@link PluginClassLoader} for the given plugin using the specified class loading strategy. | |||
* | |||
* @param pluginManager the plugin manager | |||
* @param pluginDescriptor the plugin descriptor | |||
* @param parent the parent class loader | |||
* @param classLoadingStrategy the strategy to use for loading classes and resources | |||
*/ | |||
public PluginClassLoader(PluginManager pluginManager, PluginDescriptor pluginDescriptor, ClassLoader parent, ClassLoadingStrategy classLoadingStrategy) { | |||
super(new URL[0], parent); | |||
@@ -73,12 +82,22 @@ public class PluginClassLoader extends URLClassLoader { | |||
this.classLoadingStrategy = classLoadingStrategy; | |||
} | |||
/** | |||
* Adds the specified URL to the search path for classes and resources. | |||
* | |||
* @param url the URL to be added to the search path of URLs | |||
*/ | |||
@Override | |||
public void addURL(URL url) { | |||
log.debug("Add '{}'", url); | |||
super.addURL(url); | |||
} | |||
/** | |||
* Adds the specified file to the search path for classes and resources. | |||
* | |||
* @param file the file to be added to the search path of URLs | |||
*/ | |||
public void addFile(File file) { | |||
try { | |||
addURL(file.getCanonicalFile().toURI().toURL()); | |||
@@ -89,10 +108,15 @@ public class PluginClassLoader extends URLClassLoader { | |||
} | |||
/** | |||
* Loads the class with the specified name. | |||
* <p> | |||
* By default, it uses a child first delegation model rather than the standard parent first. | |||
* If the requested class cannot be found in this class loader, the parent class loader will be consulted | |||
* via the standard {@link ClassLoader#loadClass(String)} mechanism. | |||
* Use {@link #classLoadingStrategy} to change the loading strategy. | |||
* | |||
* @param className the name of the class | |||
* @return the loaded class | |||
*/ | |||
@Override | |||
public Class<?> loadClass(String className) throws ClassNotFoundException { | |||
@@ -146,7 +170,8 @@ public class PluginClassLoader extends URLClassLoader { | |||
} | |||
/** | |||
* Load the named resource from this plugin. | |||
* Loads the named resource from this plugin. | |||
* <p> | |||
* By default, this implementation checks the plugin's classpath first then delegates to the parent. | |||
* Use {@link #classLoadingStrategy} to change the loading strategy. | |||
* | |||
@@ -181,6 +206,7 @@ public class PluginClassLoader extends URLClassLoader { | |||
return null; | |||
} | |||
@Override | |||
public Enumeration<URL> getResources(String name) throws IOException { | |||
List<URL> resources = new ArrayList<>(); | |||
@@ -205,6 +231,12 @@ public class PluginClassLoader extends URLClassLoader { | |||
return Collections.enumeration(resources); | |||
} | |||
/** | |||
* Loads the class with the specified name from the dependencies of the plugin. | |||
* | |||
* @param className the name of the class | |||
* @return the loaded class | |||
*/ | |||
protected Class<?> loadClassFromDependencies(String className) { | |||
log.trace("Search in dependencies for class '{}'", className); | |||
List<PluginDependency> dependencies = pluginDescriptor.getDependencies(); | |||
@@ -226,6 +258,12 @@ public class PluginClassLoader extends URLClassLoader { | |||
return null; | |||
} | |||
/** | |||
* Finds the resource with the given name in the dependencies of the plugin. | |||
* | |||
* @param name the name of the resource | |||
* @return the URL to the resource, {@code null} if the resource was not found | |||
*/ | |||
protected URL findResourceFromDependencies(String name) { | |||
log.trace("Search in dependencies for resource '{}'", name); | |||
List<PluginDependency> dependencies = pluginDescriptor.getDependencies(); | |||
@@ -246,6 +284,13 @@ public class PluginClassLoader extends URLClassLoader { | |||
return null; | |||
} | |||
/** | |||
* Finds all resources with the given name in the dependencies of the plugin. | |||
* | |||
* @param name the name of the resource | |||
* @return an enumeration of {@link URL} objects for the resource | |||
* @throws IOException if I/O errors occur | |||
*/ | |||
protected Collection<URL> findResourcesFromDependencies(String name) throws IOException { | |||
log.trace("Search in dependencies for resources '{}'", name); | |||
List<URL> results = new ArrayList<>(); |
@@ -23,38 +23,75 @@ import java.util.Set; | |||
/** | |||
* The classpath of the plugin. | |||
* <p> | |||
* It contains {@code classes} directories (directories that contain classes files) | |||
* and {@code jars} directories (directories that contain jars files). | |||
* <p> | |||
* The classpath is used to create the {@link ClassLoader} for the plugin. | |||
* | |||
* @author Decebal Suiu | |||
*/ | |||
public class PluginClasspath { | |||
private Set<String> classesDirectories = new HashSet<>(); | |||
private Set<String> jarsDirectories = new HashSet<>(); | |||
private final Set<String> classesDirectories = new HashSet<>(); | |||
private final Set<String> jarsDirectories = new HashSet<>(); | |||
/** | |||
* Get the classes directories. | |||
* | |||
* @return a set of directories that contain classes files | |||
*/ | |||
public Set<String> getClassesDirectories() { | |||
return classesDirectories; | |||
} | |||
/** | |||
* Add classes directories. | |||
* | |||
* @param classesDirectories a set of directories that contain classes files | |||
* @return this object for chaining | |||
*/ | |||
public PluginClasspath addClassesDirectories(String... classesDirectories) { | |||
return addClassesDirectories(Arrays.asList(classesDirectories)); | |||
} | |||
/** | |||
* Add classes directories. | |||
* | |||
* @param classesDirectories a collection of directories that contain classes files | |||
* @return this object for chaining | |||
*/ | |||
public PluginClasspath addClassesDirectories(Collection<String> classesDirectories) { | |||
this.classesDirectories.addAll(classesDirectories); | |||
return this; | |||
} | |||
/** | |||
* Get the jars directories. | |||
* | |||
* @return a set of directories that contain jars files | |||
*/ | |||
public Set<String> getJarsDirectories() { | |||
return jarsDirectories; | |||
} | |||
/** | |||
* Add jars directories. | |||
* | |||
* @param jarsDirectories a set of directories that contain jars files | |||
* @return this object for chaining | |||
*/ | |||
public PluginClasspath addJarsDirectories(String... jarsDirectories) { | |||
return addJarsDirectories(Arrays.asList(jarsDirectories)); | |||
} | |||
/** | |||
* Add jars directories. | |||
* | |||
* @param jarsDirectories a collection of directories that contain jars files | |||
* @return this object for chaining | |||
*/ | |||
public PluginClasspath addJarsDirectories(Collection<String> jarsDirectories) { | |||
this.jarsDirectories.addAll(jarsDirectories); | |||
@@ -74,4 +111,5 @@ public class PluginClasspath { | |||
public int hashCode() { | |||
return Objects.hash(classesDirectories, jarsDirectories); | |||
} | |||
} |
@@ -18,13 +18,26 @@ package org.pf4j; | |||
import java.util.Objects; | |||
/** | |||
* A plugin dependency is a dependency that the plugin has on another plugin. | |||
* <p> | |||
* The dependency is defined by the plugin id and the version of the plugin that is required. | |||
* <p> | |||
* A dependency is considered as optional, if the plugin id ends with a question mark. | |||
* For example, the plugin id "my-plugin?" is considered as optional. | |||
* <p> | |||
* The plugin id and the version are separated by the '@' character. | |||
* For example, the dependency "my-plugin@1.0.0" means that the plugin "my-plugin" with version "1.0.0" is required. | |||
* If the version is not specified, then the plugin is required with any version. | |||
* For example, the dependency "my-plugin" means that the plugin "my-plugin" with any version is required. | |||
* | |||
* @see VersionManager | |||
* @author Decebal Suiu | |||
*/ | |||
public class PluginDependency { | |||
private String pluginId; | |||
private String pluginVersionSupport = "*"; | |||
private boolean optional; | |||
private final boolean optional; | |||
public PluginDependency(String dependency) { | |||
int index = dependency.indexOf('@'); | |||
@@ -44,14 +57,29 @@ public class PluginDependency { | |||
} | |||
} | |||
/** | |||
* Returns the unique identifier of the plugin. | |||
* | |||
* @return the plugin id | |||
*/ | |||
public String getPluginId() { | |||
return pluginId; | |||
} | |||
/** | |||
* Returns the version of the plugin that is required. | |||
* | |||
* @return the version of the plugin that is required | |||
*/ | |||
public String getPluginVersionSupport() { | |||
return pluginVersionSupport; | |||
} | |||
/** | |||
* Returns {@code true} if the dependency is optional, {@code false} otherwise. | |||
* | |||
* @return {@code true} if the dependency is optional, {@code false} otherwise | |||
*/ | |||
public boolean isOptional() { | |||
return optional; | |||
} | |||
@@ -77,4 +105,5 @@ public class PluginDependency { | |||
public int hashCode() { | |||
return Objects.hash(pluginId, pluginVersionSupport, optional); | |||
} | |||
} |
@@ -24,20 +24,65 @@ import java.util.List; | |||
*/ | |||
public interface PluginDescriptor { | |||
/** | |||
* The unique identifier of the plugin. | |||
* | |||
* @return the plugin id | |||
*/ | |||
String getPluginId(); | |||
/** | |||
* Returns a description of the plugin. | |||
* | |||
* @return the plugin description | |||
*/ | |||
String getPluginDescription(); | |||
/** | |||
* Returns the fully qualified class name of the plugin class. | |||
* The plugin class must implement the {@link Plugin} interface. | |||
* | |||
* @return the plugin class | |||
*/ | |||
String getPluginClass(); | |||
/** | |||
* Returns the plugin version. | |||
* The version must be unique for each release of the plugin. | |||
* The version is used to check if the plugin is compatible with the application. | |||
* | |||
* @see VersionManager | |||
* @return the plugin version | |||
*/ | |||
String getVersion(); | |||
/** | |||
* Returns the required version of the application. | |||
* | |||
* @return the required version of the application | |||
*/ | |||
String getRequires(); | |||
/** | |||
* Returns the author of the plugin. | |||
* | |||
* @return the author of the plugin | |||
*/ | |||
String getProvider(); | |||
/** | |||
* Returns the license of the plugin. | |||
* | |||
* @return the license of the plugin | |||
*/ | |||
String getLicense(); | |||
/** | |||
* Returns the dependencies of the plugin. | |||
* A dependency is represented by a {@link PluginDependency} object. | |||
* | |||
* @return the dependencies of the plugin | |||
*/ | |||
List<PluginDependency> getDependencies(); | |||
} |
@@ -19,6 +19,7 @@ import java.nio.file.Path; | |||
/** | |||
* Find a plugin descriptor for a plugin path. | |||
* <p> | |||
* You can find the plugin descriptor in manifest file {@link ManifestPluginDescriptorFinder}, | |||
* properties file {@link PropertiesPluginDescriptorFinder}, xml file, | |||
* java services (with {@link java.util.ServiceLoader}), etc. | |||
@@ -28,10 +29,19 @@ import java.nio.file.Path; | |||
public interface PluginDescriptorFinder { | |||
/** | |||
* Returns true if this finder is applicable to the given {@link Path}. | |||
* Returns {@code true} if this finder is applicable to the given {@code pluginPath}. | |||
* This is used to select the appropriate finder for a given plugin path. | |||
* | |||
* @param pluginPath the plugin path | |||
*/ | |||
boolean isApplicable(Path pluginPath); | |||
/** | |||
* Find the plugin descriptor for the given {@code pluginPath}. | |||
* | |||
* @param pluginPath the plugin path | |||
* @return the plugin descriptor or {@code null} if not found | |||
*/ | |||
PluginDescriptor find(Path pluginPath); | |||
} |
@@ -16,10 +16,16 @@ | |||
package org.pf4j; | |||
/** | |||
* Creates a plugin instance. | |||
* It's responsible for creating a plugin instance. | |||
*/ | |||
public interface PluginFactory { | |||
/** | |||
* Create a plugin instance. | |||
* | |||
* @param pluginWrapper the plugin wrapper | |||
* @return a plugin instance | |||
*/ | |||
Plugin create(PluginWrapper pluginWrapper); | |||
} |
@@ -19,19 +19,30 @@ import java.nio.file.Path; | |||
/** | |||
* Load all information (classes) needed by a plugin. | |||
* <p> | |||
* The plugin loader is responsible for creating a class loader for a plugin | |||
* and loading all classes/resources needed by the plugin. | |||
* | |||
* @author Decebal Suiu | |||
*/ | |||
public interface PluginLoader { | |||
/** | |||
* Returns true if this loader is applicable to the given {@link Path}. | |||
* Returns {@code true} if this loader is applicable to the given plugin path. | |||
* This is used to select the appropriate loader for a given plugin path. | |||
* | |||
* @param pluginPath | |||
* @return | |||
* @param pluginPath the plugin path | |||
* @return true if this loader is applicable to the given {@link Path} | |||
*/ | |||
boolean isApplicable(Path pluginPath); | |||
/** | |||
* Load all information (classes) needed by a plugin. | |||
* | |||
* @param pluginPath the plugin path | |||
* @param pluginDescriptor the plugin descriptor | |||
* @return the class loader for the plugin | |||
*/ | |||
ClassLoader loadPlugin(Path pluginPath, PluginDescriptor pluginDescriptor); | |||
} |
@@ -141,6 +141,12 @@ public interface PluginManager { | |||
*/ | |||
boolean deletePlugin(String pluginId); | |||
/** | |||
* Retrieves the class loader for the specified plugin. | |||
* | |||
* @param pluginId the unique plugin identifier, specified in its metadata | |||
* @return the class loader for the plugin | |||
*/ | |||
ClassLoader getPluginClassLoader(String pluginId); | |||
List<Class<?>> getExtensionClasses(String pluginId); | |||
@@ -153,6 +159,12 @@ public interface PluginManager { | |||
<T> List<T> getExtensions(Class<T> type, String pluginId); | |||
/** | |||
* Retrieves the extensions for the specified plugin. | |||
* | |||
* @param pluginId the unique plugin identifier, specified in its metadata | |||
* @return the extensions for the plugin | |||
*/ | |||
List getExtensions(String pluginId); | |||
Set<String> getExtensionClassNames(String pluginId); | |||
@@ -165,14 +177,14 @@ public interface PluginManager { | |||
RuntimeMode getRuntimeMode(); | |||
/** | |||
* Returns {@code true} if the runtime mode is {@code RuntimeMode.DEVELOPMENT}. | |||
* Returns {@code true} if the runtime mode is {@link RuntimeMode#DEVELOPMENT}. | |||
*/ | |||
default boolean isDevelopment() { | |||
return RuntimeMode.DEVELOPMENT.equals(getRuntimeMode()); | |||
} | |||
/** | |||
* Returns {@code true} if the runtime mode is not {@code RuntimeMode.DEVELOPMENT}. | |||
* Returns {@code true} if the runtime mode is not {@link RuntimeMode#DEVELOPMENT}. | |||
*/ | |||
default boolean isNotDevelopment() { | |||
return !isDevelopment(); | |||
@@ -193,7 +205,7 @@ public interface PluginManager { | |||
* disables all version checking. | |||
* | |||
* @default 0.0.0 | |||
* @param version | |||
* @param version the system version | |||
*/ | |||
void setSystemVersion(String version); | |||
@@ -215,7 +227,7 @@ public interface PluginManager { | |||
Path getPluginsRoot(); | |||
/** | |||
* Gets the a read-only list of all paths of the folders where plugins are installed. | |||
* Gets a read-only list of all paths of the folders where plugins are installed. | |||
* | |||
* @return Paths of plugins roots | |||
*/ |
@@ -19,7 +19,7 @@ import java.nio.file.Path; | |||
import java.util.List; | |||
/** | |||
* Directory that contains plugins. A plugin could be a {@code directory}, @code zip} or {@code jar} 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 |
@@ -16,6 +16,14 @@ | |||
package org.pf4j; | |||
/** | |||
* The state of a plugin. | |||
* <p> | |||
* Lifecycle of a plugin: | |||
* <pre> | |||
* CREATED -> RESOLVED -> STARTED -> STOPPED | |||
* CREATED -> DISABLED | |||
* CREATED -> FAILED | |||
* | |||
* @author Decebal Suiu | |||
*/ | |||
public enum PluginState { | |||
@@ -51,14 +59,14 @@ public enum PluginState { | |||
*/ | |||
FAILED("FAILED"); | |||
private String status; | |||
private final String status; | |||
private PluginState(String status) { | |||
PluginState(String status) { | |||
this.status = status; | |||
} | |||
public boolean equals(String status) { | |||
return (status == null ? false : this.status.equalsIgnoreCase(status)); | |||
return (this.status.equalsIgnoreCase(status)); | |||
} | |||
@Override | |||
@@ -66,13 +74,20 @@ public enum PluginState { | |||
return status; | |||
} | |||
/** | |||
* Parse a string to a {@link PluginState}. | |||
* | |||
* @param string the string to parse | |||
* @return the {@link PluginState} or null if the string is not a valid state | |||
*/ | |||
public static PluginState parse(String string) { | |||
for (PluginState status : values()) { | |||
if (status.equals(string)) { | |||
return status; | |||
} | |||
} | |||
for (PluginState status : values()) { | |||
if (status.equals(string)) { | |||
return status; | |||
} | |||
} | |||
return null; | |||
} | |||
return null; | |||
} | |||
} |
@@ -18,6 +18,12 @@ package org.pf4j; | |||
import java.util.EventObject; | |||
/** | |||
* Event object that indicates a change in the state of a plugin. | |||
* The event is propagated to all registered listeners. | |||
* The event source is the {@link PluginManager} that changed the state of the plugin. | |||
* The event object contains the plugin that changed its state and the old state. | |||
* | |||
* @see PluginStateListener | |||
* @author Decebal Suiu | |||
*/ | |||
public class PluginStateEvent extends EventObject { | |||
@@ -32,19 +38,39 @@ public class PluginStateEvent extends EventObject { | |||
this.oldState = oldState; | |||
} | |||
/** | |||
* The object on which the Event initially occurred. | |||
* | |||
* @return the PluginManager that changed the state of the plugin | |||
*/ | |||
@Override | |||
public PluginManager getSource() { | |||
return (PluginManager) super.getSource(); | |||
} | |||
/** | |||
* The plugin that changed its state. | |||
* | |||
* @return the plugin that changed its state | |||
*/ | |||
public PluginWrapper getPlugin() { | |||
return plugin; | |||
} | |||
/** | |||
* The new state of the plugin. | |||
* | |||
* @return the new state of the plugin | |||
*/ | |||
public PluginState getPluginState() { | |||
return plugin.getPluginState(); | |||
} | |||
/** | |||
* The old state of the plugin. | |||
* | |||
* @return the old state of the plugin | |||
*/ | |||
public PluginState getOldState() { | |||
return oldState; | |||
} |
@@ -18,14 +18,19 @@ package org.pf4j; | |||
import java.util.EventListener; | |||
/** | |||
* PluginStateListener defines the interface for an object that listens to plugin state changes. | |||
* Defines the interface for an object that listens to plugin state changes. | |||
* <p> | |||
* The class that is interested in processing a plugin state event implements this interface. | |||
* | |||
* @see PluginStateEvent | |||
* @author Decebal Suiu | |||
*/ | |||
public interface PluginStateListener extends EventListener { | |||
/** | |||
* Invoked when a plugin's state (for example DISABLED, STARTED) is changed. | |||
* Invoked when a plugin's state (for example {@link PluginState#DISABLED}, {@link PluginState#STARTED}) is changed. | |||
* | |||
* @param event the plugin state event | |||
*/ | |||
void pluginStateChanged(PluginStateEvent event); | |||
@@ -16,6 +16,12 @@ | |||
package org.pf4j; | |||
/** | |||
* Provides a way to check if a plugin is disabled and to disable/enable a plugin. | |||
* <p> | |||
* This is useful when you want to store the plugin status in a database or in a file. | |||
* | |||
* @see PluginState#DISABLED | |||
* | |||
* @author Decebal Suiu | |||
* @author Mário Franco | |||
*/ |
@@ -24,13 +24,13 @@ import java.nio.file.Path; | |||
*/ | |||
public class PluginWrapper { | |||
private PluginManager pluginManager; | |||
private PluginDescriptor descriptor; | |||
private Path pluginPath; | |||
private ClassLoader pluginClassLoader; | |||
private final PluginManager pluginManager; | |||
private final PluginDescriptor descriptor; | |||
private final Path pluginPath; | |||
private final ClassLoader pluginClassLoader; | |||
private PluginFactory pluginFactory; | |||
private PluginState pluginState; | |||
private RuntimeMode runtimeMode; | |||
private final RuntimeMode runtimeMode; | |||
private Throwable failedException; | |||
@@ -48,6 +48,8 @@ public class PluginWrapper { | |||
/** | |||
* Returns the plugin manager. | |||
* | |||
* @return the plugin manager | |||
*/ | |||
public PluginManager getPluginManager() { | |||
return pluginManager; | |||
@@ -55,6 +57,8 @@ public class PluginWrapper { | |||
/** | |||
* Returns the plugin descriptor. | |||
* | |||
* @return the plugin descriptor | |||
*/ | |||
public PluginDescriptor getDescriptor() { | |||
return descriptor; | |||
@@ -62,20 +66,29 @@ public class PluginWrapper { | |||
/** | |||
* Returns the path of this plugin. | |||
* | |||
* @return the path of this plugin | |||
*/ | |||
public Path getPluginPath() { | |||
return pluginPath; | |||
} | |||
/** | |||
* Returns the plugin class loader used to load classes and resources | |||
* for this plug-in. The class loader can be used to directly access | |||
* plug-in resources and classes. | |||
* Returns the plugin {@link ClassLoader} used to load classes and resources for this plug-in. | |||
* <p> | |||
* The class loader can be used to directly access plug-in resources and classes. | |||
* | |||
* @return the plugin class loader | |||
*/ | |||
public ClassLoader getPluginClassLoader() { | |||
return pluginClassLoader; | |||
} | |||
/** | |||
* Returns the plugin instance. | |||
* | |||
* @return the plugin instance | |||
*/ | |||
public Plugin getPlugin() { | |||
if (plugin == null) { | |||
plugin = pluginFactory.create(this); | |||
@@ -84,16 +97,26 @@ public class PluginWrapper { | |||
return plugin; | |||
} | |||
/** | |||
* Returns the plugin factory. | |||
* | |||
* @return the plugin factory | |||
*/ | |||
public PluginState getPluginState() { | |||
return pluginState; | |||
} | |||
/** | |||
* Returns the runtime mode. | |||
* | |||
* @return the runtime mode | |||
*/ | |||
public RuntimeMode getRuntimeMode() { | |||
return runtimeMode; | |||
} | |||
/** | |||
* Shortcut | |||
* Shortcut for {@code getDescriptor().getPluginId()}. | |||
*/ | |||
public String getPluginId() { | |||
return getDescriptor().getPluginId(); | |||
@@ -133,10 +156,20 @@ public class PluginWrapper { | |||
return "PluginWrapper [descriptor=" + descriptor + ", pluginPath=" + pluginPath + "]"; | |||
} | |||
/** | |||
* Used internally by the framework to set the plugin factory. | |||
* | |||
* @param pluginState the plugin state | |||
*/ | |||
public void setPluginState(PluginState pluginState) { | |||
this.pluginState = pluginState; | |||
} | |||
/** | |||
* Used internally by the framework to set the plugin factory. | |||
* | |||
* @param pluginFactory the plugin factory | |||
*/ | |||
public void setPluginFactory(PluginFactory pluginFactory) { | |||
this.pluginFactory = pluginFactory; | |||
} | |||
@@ -144,11 +177,18 @@ public class PluginWrapper { | |||
/** | |||
* Returns the exception with which the plugin fails to start. | |||
* See @{link PluginStatus#FAILED}. | |||
* | |||
* @return the exception with which the plugin fails to start | |||
*/ | |||
public Throwable getFailedException() { | |||
return failedException; | |||
} | |||
/** | |||
* Used internally by the framework to set the exception with which the plugin fails to start. | |||
* | |||
* @param failedException the exception with which the plugin fails to start | |||
*/ | |||
public void setFailedException(Throwable failedException) { | |||
this.failedException = failedException; | |||
} |
@@ -20,6 +20,12 @@ import java.util.Map; | |||
import java.util.NoSuchElementException; | |||
/** | |||
* The runtime mode of the PF4J application. | |||
* <p> | |||
* The runtime mode is used to determine the behavior of the application. | |||
* For example, in development mode, the application may display detailed error messages, | |||
* while in deployment mode, the application may display a generic error message. | |||
* | |||
* @author Decebal Suiu | |||
*/ | |||
public enum RuntimeMode { | |||
@@ -51,6 +57,13 @@ public enum RuntimeMode { | |||
return name; | |||
} | |||
/** | |||
* Returns the runtime mode with the specified name. | |||
* | |||
* @param name the name of the runtime mode | |||
* @return the runtime mode with the specified name | |||
* @throws NoSuchElementException if the runtime mode with the specified name is not found | |||
*/ | |||
public static RuntimeMode byName(String name) { | |||
if (map.containsKey(name)) { | |||
return map.get(name); |
@@ -19,6 +19,7 @@ import java.util.Comparator; | |||
/** | |||
* Manager responsible for versions of plugins. | |||
* It's used to check if a version matches a constraint and to compare two versions. | |||
* | |||
* @author Decebal Suiu | |||
*/ | |||
@@ -28,17 +29,17 @@ public interface VersionManager { | |||
* Check if a {@code constraint} and a {@code version} match. | |||
* A possible constrain can be {@code >=1.0.0 & <2.0.0}. | |||
* | |||
* @param version | |||
* @param constraint | |||
* @return | |||
* @param version the version to check | |||
* @param constraint the constraint to check | |||
* @return {@code true} if the version matches the constraint, {@code false} otherwise | |||
*/ | |||
boolean checkVersionConstraint(String version, String constraint); | |||
/** | |||
* Compare two versions. It's similar with {@link Comparator#compare(Object, Object)}. | |||
* | |||
* @param v1 | |||
* @param v2 | |||
* @param v1 the first version to compare | |||
* @param v2 the second version to compare | |||
*/ | |||
int compareVersions(String v1, String v2); | |||