System.out.println("WelcomePlugin.start()");
// for testing the development mode
if (RuntimeMode.DEVELOPMENT.equals(wrapper.getRuntimeMode())) {
- System.out.println(StringUtils.upperCase("WelcomePlugin"));
+ System.out.println(StringUtils.upperCase("WelcomePlugin"));
}
}
@Extension
public static class WelcomeGreeting implements Greeting {
- @Override
+ @Override
public String getGreeting() {
return "Welcome";
}
@Extension(ordinal=1)
public static class HelloGreeting implements Greeting {
- @Override
+ @Override
public String getGreeting() {
return "Hello";
}
/*
Runtime.getRuntime().addShutdownHook(new Thread() {
- @Override
- public void run() {
- pluginManager.stopPlugins();
- }
+ @Override
+ public void run() {
+ pluginManager.stopPlugins();
+ }
});
*/
}
- private static void printLogo() {
- logger.info(StringUtils.repeat("#", 40));
- logger.info(StringUtils.center("PF4J-DEMO", 40));
- logger.info(StringUtils.repeat("#", 40));
- }
+ private static void printLogo() {
+ logger.info(StringUtils.repeat("#", 40));
+ logger.info(StringUtils.center("PF4J-DEMO", 40));
+ logger.info(StringUtils.repeat("#", 40));
+ }
}
* @author Decebal Suiu
*/
public class WelcomePlugin extends Plugin {
+
private static final Logger logger = LoggerFactory.getLogger(WelcomePlugin.class);
public WelcomePlugin(PluginWrapper wrapper) {
@Override
public void start() {
logger.info("WelcomePlugin.start()");
- logger.info(StringUtils.upperCase("WelcomePlugin"));
+ logger.info(StringUtils.upperCase("WelcomePlugin"));
}
@Override
@Extension
public static class WelcomeGreeting implements Greeting {
- @Override
+ @Override
public String getGreeting() {
return "Welcome";
}
@Extension(ordinal=1)
public static class HelloGreeting implements Greeting {
- @Override
+ @Override
public String getGreeting() {
return "Hello";
}
protected PluginManager pluginManager;
protected List<ExtensionFinder> finders = new ArrayList<>();
- public DefaultExtensionFinder(PluginManager pluginManager) {
+ public DefaultExtensionFinder(PluginManager pluginManager) {
this.pluginManager = pluginManager;
add(new LegacyExtensionFinder(pluginManager));
*/
public class DefaultPluginManager extends AbstractPluginManager {
- private static final Logger log = LoggerFactory.getLogger(DefaultPluginManager.class);
+ private static final Logger log = LoggerFactory.getLogger(DefaultPluginManager.class);
protected PluginClasspath pluginClasspath;
@Override
protected ExtensionFinder createExtensionFinder() {
- DefaultExtensionFinder extensionFinder = new DefaultExtensionFinder(this);
+ DefaultExtensionFinder extensionFinder = new DefaultExtensionFinder(this);
addPluginStateListener(extensionFinder);
return extensionFinder;
}
log.info("PF4J version {} in '{}' mode", getVersion(), getRuntimeMode());
- }
+ }
/**
* Load a plugin from disk. If the path is a zip file, first unpack
*/
public class DependencyResolver {
- private static final Logger log = LoggerFactory.getLogger(DependencyResolver.class);
+ private static final Logger log = LoggerFactory.getLogger(DependencyResolver.class);
- private VersionManager versionManager;
+ private VersionManager versionManager;
private DirectedGraph<String> dependenciesGraph; // the value is 'pluginId'
private DirectedGraph<String> dependentsGraph; // the value is 'pluginId'
"' for plugin '" + dependent.getPluginId() + "'");
}
- public static class Result {
+ public static class Result {
- private boolean cyclicDependency;
- private List<String> notFoundDependencies; // value is "pluginId"
+ private boolean cyclicDependency;
+ private List<String> notFoundDependencies; // value is "pluginId"
private List<String> sortedPlugins; // value is "pluginId"
private List<WrongDependencyVersion> wrongVersionDependencies;
return cyclicDependency;
}
- /**
- * Returns a list with dependencies required that were not found.
- */
+ /**
+ * Returns a list with dependencies required that were not found.
+ */
public List<String> getNotFoundDependencies() {
return notFoundDependencies;
}
@Documented
public @interface Extension {
- int ordinal() default 0;
+ int ordinal() default 0;
}
*/
public class LegacyExtensionFinder extends AbstractExtensionFinder {
- private static final Logger log = LoggerFactory.getLogger(LegacyExtensionFinder.class);
+ private static final Logger log = LoggerFactory.getLogger(LegacyExtensionFinder.class);
- public LegacyExtensionFinder(PluginManager pluginManager) {
+ public LegacyExtensionFinder(PluginManager pluginManager) {
super(pluginManager);
- }
+ }
@Override
public Map<String, Set<String>> readClasspathStorages() {
}
@Override
- public PluginDescriptor find(Path pluginPath) throws PluginException {
+ public PluginDescriptor find(Path pluginPath) throws PluginException {
Manifest manifest = readManifest(pluginPath);
return createPluginDescriptor(manifest);
- }
+ }
protected Manifest readManifest(Path pluginPath) throws PluginException {
if (FileUtils.isJarFile(pluginPath)) {
private static final Logger log = LoggerFactory.getLogger(PluginClassLoader.class);
private static final String JAVA_PACKAGE_PREFIX = "java.";
- private static final String PLUGIN_PACKAGE_PREFIX = "org.pf4j.";
+ private static final String PLUGIN_PACKAGE_PREFIX = "org.pf4j.";
- private PluginManager pluginManager;
- private PluginDescriptor pluginDescriptor;
- private boolean parentFirst;
+ private PluginManager pluginManager;
+ private PluginDescriptor pluginDescriptor;
+ private boolean parentFirst;
public PluginClassLoader(PluginManager pluginManager, PluginDescriptor pluginDescriptor, ClassLoader parent) {
this(pluginManager, pluginDescriptor, parent, false);
* before trying to load the a class through this loader.
*/
public PluginClassLoader(PluginManager pluginManager, PluginDescriptor pluginDescriptor, ClassLoader parent, boolean parentFirst) {
- super(new URL[0], parent);
+ super(new URL[0], parent);
- this.pluginManager = pluginManager;
- this.pluginDescriptor = pluginDescriptor;
- this.parentFirst = parentFirst;
- }
+ this.pluginManager = pluginManager;
+ this.pluginDescriptor = pluginDescriptor;
+ this.parentFirst = parentFirst;
+ }
@Override
- public void addURL(URL url) {
+ public void addURL(URL url) {
log.debug("Add '{}'", url);
- super.addURL(url);
- }
+ super.addURL(url);
+ }
- public void addFile(File file) {
+ public void addFile(File file) {
try {
addURL(file.getCanonicalFile().toURI().toURL());
} catch (IOException e) {
* via the standard {@link ClassLoader#loadClass(String)} mechanism.
* Use {@link #parentFirst} to change the loading strategy.
*/
- @Override
+ @Override
public Class<?> loadClass(String className) throws ClassNotFoundException {
synchronized (getClassLoadingLock(className)) {
// first check whether it's a system class, delegate to the system loader
*/
boolean isApplicable(Path pluginPath);
- PluginDescriptor find(Path pluginPath) throws PluginException;
+ PluginDescriptor find(Path pluginPath) throws PluginException;
}
/**
* Retrieves all resolved plugins (with resolved dependency).
*/
- List<PluginWrapper> getResolvedPlugins();
+ List<PluginWrapper> getResolvedPlugins();
- /**
- * Retrieves all unresolved plugins (with unresolved dependency).
- */
- List<PluginWrapper> getUnresolvedPlugins();
+ /**
+ * Retrieves all unresolved plugins (with unresolved dependency).
+ */
+ List<PluginWrapper> getUnresolvedPlugins();
/**
* Retrieves all started plugins.
* @param pluginPath
* @return the pluginId of the installed plugin or null
*/
- String loadPlugin(Path pluginPath);
+ String loadPlugin(Path pluginPath);
/**
* Start all active plugins.
*/
boolean deletePlugin(String pluginId);
- ClassLoader getPluginClassLoader(String pluginId);
+ ClassLoader getPluginClassLoader(String pluginId);
<T> List<Class<T>> getExtensionClasses(Class<T> type);
<T> List<Class<T>> getExtensionClasses(Class<T> type, String pluginId);
- <T> List<T> getExtensions(Class<T> type);
+ <T> List<T> getExtensions(Class<T> type);
<T> List<T> getExtensions(Class<T> type, String pluginId);
ExtensionFactory getExtensionFactory();
/**
- * The runtime mode. Must currently be either DEVELOPMENT or DEPLOYMENT.
- */
- RuntimeMode getRuntimeMode();
+ * The runtime mode. Must currently be either DEVELOPMENT or DEPLOYMENT.
+ */
+ RuntimeMode getRuntimeMode();
/**
* Retrieves the {@link PluginWrapper} that loaded the given class 'clazz'.
/**
* The runtime knows the plugin is there. It knows about the plugin path, the plugin descriptor.
*/
- public static final PluginState CREATED = new PluginState("CREATED");
+ public static final PluginState CREATED = new PluginState("CREATED");
/**
* The plugin cannot be used.
/**
* The {@link Plugin#start()} has executed. A started plugin may contribute extensions.
*/
- public static final PluginState STARTED = new PluginState("STARTED");
+ public static final PluginState STARTED = new PluginState("STARTED");
/**
* The {@link Plugin#stop()} has executed.
*/
public static final PluginState STOPPED = new PluginState("STOPPED");
- private String status;
+ private String status;
- private PluginState(String status) {
- this.status = status;
- }
+ private PluginState(String status) {
+ this.status = status;
+ }
@Override
public boolean equals(Object o) {
}
@Override
- public String toString() {
- return status;
- }
+ public String toString() {
+ return status;
+ }
}
public class PluginWrapper {
private PluginManager pluginManager;
- private PluginDescriptor descriptor;
- private Path pluginPath;
- private ClassLoader pluginClassLoader;
- private PluginFactory pluginFactory;
- private PluginState pluginState;
- private RuntimeMode runtimeMode;
+ private PluginDescriptor descriptor;
+ private Path pluginPath;
+ private ClassLoader pluginClassLoader;
+ private PluginFactory pluginFactory;
+ private PluginState pluginState;
+ private RuntimeMode runtimeMode;
Plugin plugin; // cache
- public PluginWrapper(PluginManager pluginManager, PluginDescriptor descriptor, Path pluginPath, ClassLoader pluginClassLoader) {
+ public PluginWrapper(PluginManager pluginManager, PluginDescriptor descriptor, Path pluginPath, ClassLoader pluginClassLoader) {
this.pluginManager = pluginManager;
- this.descriptor = descriptor;
- this.pluginPath = pluginPath;
- this.pluginClassLoader = pluginClassLoader;
+ this.descriptor = descriptor;
+ this.pluginPath = pluginPath;
+ this.pluginClassLoader = pluginClassLoader;
- pluginState = PluginState.CREATED;
- }
+ pluginState = PluginState.CREATED;
+ }
/**
* Returns the plugin manager.
* Returns the plugin descriptor.
*/
public PluginDescriptor getDescriptor() {
- return descriptor;
+ return descriptor;
}
/**
* Returns the path of this plugin.
*/
public Path getPluginPath() {
- return pluginPath;
+ 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.
- */
+ * for this plug-in. The class loader can be used to directly access
+ * plug-in resources and classes.
+ */
public ClassLoader getPluginClassLoader() {
- return pluginClassLoader;
+ return pluginClassLoader;
}
public Plugin getPlugin() {
}
return plugin;
- }
+ }
- public PluginState getPluginState() {
- return pluginState;
- }
+ public PluginState getPluginState() {
+ return pluginState;
+ }
- public RuntimeMode getRuntimeMode() {
- return runtimeMode;
- }
+ public RuntimeMode getRuntimeMode() {
+ return runtimeMode;
+ }
/**
* Shortcut
return getDescriptor().getPluginId();
}
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + descriptor.getPluginId().hashCode();
-
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
-
- if (obj == null) {
- return false;
- }
-
- if (getClass() != obj.getClass()) {
- return false;
- }
-
- PluginWrapper other = (PluginWrapper) obj;
- if (!descriptor.getPluginId().equals(other.descriptor.getPluginId())) {
- return false;
- }
-
- return true;
- }
-
- @Override
- public String toString() {
- return "PluginWrapper [descriptor=" + descriptor + ", pluginPath=" + pluginPath + "]";
- }
-
- void setPluginState(PluginState pluginState) {
- this.pluginState = pluginState;
- }
-
- void setRuntimeMode(RuntimeMode runtimeMode) {
- this.runtimeMode = runtimeMode;
- }
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + descriptor.getPluginId().hashCode();
+
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj == null) {
+ return false;
+ }
+
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+
+ PluginWrapper other = (PluginWrapper) obj;
+ if (!descriptor.getPluginId().equals(other.descriptor.getPluginId())) {
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return "PluginWrapper [descriptor=" + descriptor + ", pluginPath=" + pluginPath + "]";
+ }
+
+ void setPluginState(PluginState pluginState) {
+ this.pluginState = pluginState;
+ }
+
+ void setRuntimeMode(RuntimeMode runtimeMode) {
+ this.runtimeMode = runtimeMode;
+ }
void setPluginFactory(PluginFactory pluginFactory) {
this.pluginFactory = pluginFactory;
*/
public class PropertiesPluginDescriptorFinder implements PluginDescriptorFinder {
- private static final Logger log = LoggerFactory.getLogger(PropertiesPluginDescriptorFinder.class);
+ private static final Logger log = LoggerFactory.getLogger(PropertiesPluginDescriptorFinder.class);
- private static final String DEFAULT_PROPERTIES_FILE_NAME = "plugin.properties";
+ private static final String DEFAULT_PROPERTIES_FILE_NAME = "plugin.properties";
- protected String propertiesFileName;
+ protected String propertiesFileName;
- public PropertiesPluginDescriptorFinder() {
- this(DEFAULT_PROPERTIES_FILE_NAME);
- }
+ public PropertiesPluginDescriptorFinder() {
+ this(DEFAULT_PROPERTIES_FILE_NAME);
+ }
- public PropertiesPluginDescriptorFinder(String propertiesFileName) {
+ public PropertiesPluginDescriptorFinder(String propertiesFileName) {
this.propertiesFileName = propertiesFileName;
- }
+ }
@Override
public boolean isApplicable(Path pluginPath) {
}
@Override
- public PluginDescriptor find(Path pluginPath) throws PluginException {
+ public PluginDescriptor find(Path pluginPath) throws PluginException {
Properties properties = readProperties(pluginPath);
return createPluginDescriptor(properties);
- }
+ }
protected Properties readProperties(Path pluginPath) throws PluginException {
Path propertiesPath = getPropertiesPath(pluginPath, propertiesFileName);
}
protected Path getPropertiesPath(Path pluginPath, String propertiesFileName) throws PluginException {
- if (Files.isDirectory(pluginPath)) {
+ if (Files.isDirectory(pluginPath)) {
return pluginPath.resolve(Paths.get(propertiesFileName));
} else {
- // it's a jar file
+ // it's a jar file
try {
return FileUtils.getPath(pluginPath, propertiesFileName);
} catch (IOException e) {
}
@Override
- public SourceVersion getSupportedSourceVersion() {
- return SourceVersion.latest();
- }
+ public SourceVersion getSupportedSourceVersion() {
+ return SourceVersion.latest();
+ }
- @Override
- public Set<String> getSupportedAnnotationTypes() {
- Set<String> annotationTypes = new HashSet<>();
+ @Override
+ public Set<String> getSupportedAnnotationTypes() {
+ Set<String> annotationTypes = new HashSet<>();
annotationTypes.add(Extension.class.getName());
return annotationTypes;
- }
+ }
@Override
public Set<String> getSupportedOptions() {
}
@Override
- public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
- if (roundEnv.processingOver()) {
+ public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+ if (roundEnv.processingOver()) {
return false;
}
info("Processing @%s", Extension.class);
- for (Element element : roundEnv.getElementsAnnotatedWith(Extension.class)) {
+ for (Element element : roundEnv.getElementsAnnotatedWith(Extension.class)) {
// check if @Extension is put on class and not on method or constructor
if (!(element instanceof TypeElement)) {
- continue;
- }
+ continue;
+ }
// check if class extends/implements an extension point
if (!isExtension(element.asType())) {
// write extensions
storage.write(extensions);
- return false;
- }
+ return false;
+ }
public ProcessingEnvironment getProcessingEnvironment() {
return processingEnv;
*/
public void addVertex(V vertex) {
if (containsVertex(vertex)) {
- return;
+ return;
}
neighbors.put(vertex, new ArrayList<V>());
public Map<V, Integer> outDegree() {
Map<V, Integer> result = new HashMap<>();
for (V vertex : neighbors.keySet()) {
- result.put(vertex, neighbors.get(vertex).size());
+ result.put(vertex, neighbors.get(vertex).size());
}
return result;
public Map<V, Integer> inDegree() {
Map<V, Integer> result = new HashMap<>();
for (V vertex : neighbors.keySet()) {
- result.put(vertex, 0); // all in-degrees are 0
+ result.put(vertex, 0); // all in-degrees are 0
}
for (V from : neighbors.keySet()) {
for (V to : neighbors.get(from)) {
Stack<V> zeroVertices = new Stack<>(); // stack as good as any here
for (V v : degree.keySet()) {
if (degree.get(v) == 0) {
- zeroVertices.push(v);
+ zeroVertices.push(v);
}
}
degree.put(neighbor, degree.get(neighbor) - 1);
// remember any vertices that now have zero in-degree
if (degree.get(neighbor) == 0) {
- zeroVertices.push(neighbor);
+ zeroVertices.push(neighbor);
}
}
}
// check that we have used the entire graph (if not, there was a cycle)
if (result.size() != neighbors.size()) {
- return null;
+ return null;
}
return result;
* Report (as a List) the reverse topological sort of the vertices; null for no such sort.
*/
public List<V> reverseTopologicalSort() {
- List<V> list = topologicalSort();
- if (list == null) {
- return null;
- }
+ List<V> list = topologicalSort();
+ if (list == null) {
+ return null;
+ }
- Collections.reverse(list);
+ Collections.reverse(list);
- return list;
+ return list;
}
/**
public String toString() {
StringBuffer sb = new StringBuffer();
for (V vertex : neighbors.keySet()) {
- sb.append("\n " + vertex + " -> " + neighbors.get(vertex));
+ sb.append("\n " + vertex + " -> " + neighbors.get(vertex));
}
return sb.toString();
*/
public class DirectoryFileFilter implements FileFilter {
- @Override
+ @Override
public boolean accept(File file) {
return file.isDirectory();
}
public static List<String> readLines(Path path, boolean ignoreComments) throws IOException {
File file = path.toFile();
- if (!file.exists() || !file.isFile()) {
- return new ArrayList<>();
- }
+ if (!file.exists() || !file.isFile()) {
+ return new ArrayList<>();
+ }
- List<String> lines = new ArrayList<>();
+ List<String> lines = new ArrayList<>();
- try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
- String line;
- while ((line = reader.readLine()) != null) {
- if (ignoreComments && !line.startsWith("#") && !lines.contains(line)) {
- lines.add(line);
- }
- }
- }
+ try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
+ String line;
+ while ((line = reader.readLine()) != null) {
+ if (ignoreComments && !line.startsWith("#") && !lines.contains(line)) {
+ lines.add(line);
+ }
+ }
+ }
- return lines;
- }
+ return lines;
+ }
public static void writeLines(Collection<String> lines, File file) throws IOException {
Files.write(file.toPath(), lines, StandardCharsets.UTF_8);
}
/**
- * Delete a file or recursively delete a folder, do not follow symlinks.
- *
- * @param path the file or folder to delete
- * @throws IOException if something goes wrong
- */
+ * Delete a file or recursively delete a folder, do not follow symlinks.
+ *
+ * @param path the file or folder to delete
+ * @throws IOException if something goes wrong
+ */
public static void delete(Path path) throws IOException {
Files.walkFileTree(path, new SimpleFileVisitor<Path>() {
}
});
- }
+ }
- public static List<File> getJars(Path folder) {
- List<File> bucket = new ArrayList<>();
- getJars(bucket, folder);
+ public static List<File> getJars(Path folder) {
+ List<File> bucket = new ArrayList<>();
+ getJars(bucket, folder);
- return bucket;
+ return bucket;
}
private static void getJars(final List<File> bucket, Path folder) {
*/
public class HiddenFilter implements FileFilter {
- @Override
- public boolean accept(File file) {
- return file.isHidden();
- }
+ @Override
+ public boolean accept(File file) {
+ return file.isHidden();
+ }
}
*/
public class StringUtils {
- public static boolean isNullOrEmpty(String str) {
- return (str == null) || str.isEmpty();
- }
+ public static boolean isNullOrEmpty(String str) {
+ return (str == null) || str.isEmpty();
+ }
public static boolean isNotNullOrEmpty(String str) {
return !isNullOrEmpty(str);
*/
public class Unzip {
- private static final Logger log = LoggerFactory.getLogger(Unzip.class);
+ private static final Logger log = LoggerFactory.getLogger(Unzip.class);
/**
* Holds the destination directory.
FileUtils.delete(destination.toPath());
}
- try (ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(source))) {
+ try (ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(source))) {
ZipEntry zipEntry;
while ((zipEntry = zipInputStream.getNextEntry()) != null) {
try {