summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDecebal Suiu <decebal.suiu@gmail.com>2014-01-11 06:16:49 +0200
committerDecebal Suiu <decebal.suiu@gmail.com>2014-01-11 06:16:49 +0200
commit4662ecf8f869bcaee5c5ce6418cad56e29cf38c4 (patch)
treeeb20281d30cfdc30ff6fd2a4c62b20665239e6fa
parentc6a1bbda46fcd99ae48fbb8589e0138a67bf3e1d (diff)
parentb57f307e53623dab815f3dfb0817be5b5dd5f503 (diff)
downloadpf4j-4662ecf8f869bcaee5c5ce6418cad56e29cf38c4.tar.gz
pf4j-4662ecf8f869bcaee5c5ce6418cad56e29cf38c4.zip
Merge branch 'master' of https://github.com/decebals/pf4j
-rw-r--r--README.md12
-rw-r--r--demo/api/pom.xml4
-rw-r--r--demo/app/pom.xml4
-rw-r--r--demo/plugins/plugin1/pom.xml246
-rw-r--r--demo/plugins/plugin2/pom.xml230
-rw-r--r--demo/plugins/plugin2/src/main/java/ro/fortsoft/pf4j/demo/hello/HelloPlugin.java2
-rw-r--r--demo/plugins/pom.xml212
-rw-r--r--demo/pom.xml4
-rw-r--r--pf4j/pom.xml24
-rw-r--r--pf4j/src/main/java/ro/fortsoft/pf4j/DefaultExtensionFinder.java126
-rw-r--r--pf4j/src/main/java/ro/fortsoft/pf4j/DefaultPluginManager.java2
-rw-r--r--pf4j/src/main/java/ro/fortsoft/pf4j/Extension.java3
-rw-r--r--pf4j/src/main/java/ro/fortsoft/pf4j/ExtensionsIndexer.java135
-rw-r--r--pf4j/src/main/java/ro/fortsoft/pf4j/SezpozExtensionFinder.java80
-rw-r--r--pf4j/src/main/resources/META-INF/services/javax.annotation.processing.Processor1
-rw-r--r--pom.xml2
16 files changed, 632 insertions, 455 deletions
diff --git a/README.md b/README.md
index a7bc2af..240a4f9 100644
--- a/README.md
+++ b/README.md
@@ -8,7 +8,7 @@ Current build status: [![Build Status](https://buildhive.cloudbees.com/job/dece
Features/Benefits
-------------------
With PF4J you can easily transform a monolithic java application in a modular application.
-PF4J is an open source (Apache license) lightweight (around 35KB) plugin framework for java, with minimal dependencies and very extensible (see PluginDescriptorFinder and ExtensionFinder).
+PF4J is an open source (Apache license) lightweight (around 50KB) plugin framework for java, with minimal dependencies (only slf4j-api) and very extensible (see PluginDescriptorFinder and ExtensionFinder).
No XML, only Java.
@@ -101,8 +101,8 @@ You can define an extension point in your application using **ExtensionPoint** i
}
-Another important internal component is **ExtensionFinder** that describes how plugin manager discovers extensions for extensions points.
-**DefaultExtensionFinder** is a "link" to **SezpozExtensionFinder** that looks up extensions using **Extension** annotation.
+Another important internal component is **ExtensionFinder** that describes how the plugin manager discovers extensions for the extensions points.
+**DefaultExtensionFinder** looks up extensions using **Extension** annotation. You can control extension instance creation overriding `createExtensionFactory` method from DefaultExtensionFinder.
public class WelcomePlugin extends Plugin {
@@ -135,7 +135,7 @@ The output is:
>>> Welcome
>>> Hello
-You can inject your custom component (for example PluginDescriptorFinder, ExtensionFinder, PluginClasspath, ...) in DefaultPluginManager just override createXXX methods (factory method pattern).
+You can inject your custom component (for example PluginDescriptorFinder, ExtensionFinder, PluginClasspath, ...) in DefaultPluginManager just override `create...` methods (factory method pattern).
Example:
@@ -154,7 +154,7 @@ and in plugin respository you must have a plugin.properties file with the below
For more information please see the demo sources.
-Development runtime mode
+Development mode
--------------------------
PF4J can run in two modes: **DEVELOPMENT** and **DEPLOYMENT**.
The DEPLOYMENT(default) mode is the standard workflow for plugins creation: create a new maven module for each plugin, codding the plugin (declares new extension points and/or
@@ -169,7 +169,7 @@ You can retrieve the current runtime mode using `PluginManager.getRuntimeMode()`
The DefaultPluginManager determines automatically the correct runtime mode and for DEVELOPMENT mode overrides some components(pluginsDirectory is __"../plugins"__, __PropertiesPluginDescriptorFinder__ as PluginDescriptorFinder, __DevelopmentPluginClasspath__ as PluginClassPath).
Another advantage of DEVELOPMENT runtime mode is that you can execute some code lines only in this mode (for example more debug messages).
-If you use maven as build manger, after each dependency modification in you plugin (maven module) you must run Maven>Update Project...
+If you use maven as build manger, after each dependency modification in your plugin (maven module) you must run Maven>Update Project...
For more details see the demo application.
diff --git a/demo/api/pom.xml b/demo/api/pom.xml
index 1818ec5..6d76d93 100644
--- a/demo/api/pom.xml
+++ b/demo/api/pom.xml
@@ -4,12 +4,12 @@
<parent>
<groupId>ro.fortsoft.pf4j.demo</groupId>
<artifactId>pf4j-demo-parent</artifactId>
- <version>0.6-SNAPSHOT</version>
+ <version>0.7-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>pf4j-demo-api</artifactId>
- <version>0.6-SNAPSHOT</version>
+ <version>0.7-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Demo Api</name>
diff --git a/demo/app/pom.xml b/demo/app/pom.xml
index bf07815..13c442d 100644
--- a/demo/app/pom.xml
+++ b/demo/app/pom.xml
@@ -4,12 +4,12 @@
<parent>
<groupId>ro.fortsoft.pf4j.demo</groupId>
<artifactId>pf4j-demo-parent</artifactId>
- <version>0.6-SNAPSHOT</version>
+ <version>0.7-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>pf4j-demo-app</artifactId>
- <version>0.6-SNAPSHOT</version>
+ <version>0.7-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Demo App</name>
diff --git a/demo/plugins/plugin1/pom.xml b/demo/plugins/plugin1/pom.xml
index bf8abe5..9c6db84 100644
--- a/demo/plugins/plugin1/pom.xml
+++ b/demo/plugins/plugin1/pom.xml
@@ -1,123 +1,123 @@
-<?xml version="1.0"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
- <parent>
- <groupId>ro.fortsoft.pf4j.demo</groupId>
- <artifactId>pf4j-demo-plugins</artifactId>
- <version>0.6-SNAPSHOT</version>
- </parent>
-
- <modelVersion>4.0.0</modelVersion>
- <artifactId>pf4j-demo-plugin1</artifactId>
- <version>0.6-SNAPSHOT</version>
- <packaging>jar</packaging>
- <name>Demo Plugin #1</name>
-
- <properties>
- <plugin.id>welcome-plugin</plugin.id>
- <plugin.class>ro.fortsoft.pf4j.demo.welcome.WelcomePlugin</plugin.class>
- <plugin.version>0.0.1</plugin.version>
- <plugin.provider>Decebal Suiu</plugin.provider>
- <plugin.dependencies />
- </properties>
-
- <build>
- <plugins>
- <!-- DOESN'T WORK WITH MAVEN 3 (I defined the plugin metadata in properties section)
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>properties-maven-plugin</artifactId>
- <version>1.0-alpha-2</version>
- <executions>
- <execution>
- <phase>initialize</phase>
- <goals>
- <goal>read-project-properties</goal>
- </goals>
- <configuration>
- <files>
- <file>plugin.properties</file>
- </files>
- </configuration>
- </execution>
- </executions>
- </plugin>
- -->
-
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-antrun-plugin</artifactId>
- <version>1.6</version>
- <executions>
- <execution>
- <id>unzip jar file</id>
- <phase>package</phase>
- <configuration>
- <target>
- <unzip src="target/${artifactId}-${version}.${packaging}" dest="target/plugin-classes" />
- </target>
- </configuration>
- <goals>
- <goal>run</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
-
- <plugin>
- <artifactId>maven-assembly-plugin</artifactId>
- <version>2.3</version>
- <configuration>
- <descriptors>
- <descriptor>
- src/main/assembly/assembly.xml
- </descriptor>
- </descriptors>
- <appendAssemblyId>false</appendAssemblyId>
- </configuration>
- <executions>
- <execution>
- <id>make-assembly</id>
- <phase>package</phase>
- <goals>
- <goal>attached</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
-
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-jar-plugin</artifactId>
- <version>2.4</version>
- <configuration>
- <archive>
- <manifestEntries>
- <Plugin-Id>${plugin.id}</Plugin-Id>
- <Plugin-Class>${plugin.class}</Plugin-Class>
- <Plugin-Version>${plugin.version}</Plugin-Version>
- <Plugin-Provider>${plugin.provider}</Plugin-Provider>
- <Plugin-Dependencies>${plugin.dependencies}</Plugin-Dependencies>
- </manifestEntries>
- </archive>
- </configuration>
- </plugin>
-
- <plugin>
- <artifactId>maven-deploy-plugin</artifactId>
- <configuration>
- <skip>true</skip>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
- <dependencies>
- <dependency>
- <groupId>commons-lang</groupId>
- <artifactId>commons-lang</artifactId>
- <version>2.6</version>
- </dependency>
- </dependencies>
-
-</project>
+<?xml version="1.0"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <parent>
+ <groupId>ro.fortsoft.pf4j.demo</groupId>
+ <artifactId>pf4j-demo-plugins</artifactId>
+ <version>0.7-SNAPSHOT</version>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>pf4j-demo-plugin1</artifactId>
+ <version>0.7-SNAPSHOT</version>
+ <packaging>jar</packaging>
+ <name>Demo Plugin #1</name>
+
+ <properties>
+ <plugin.id>welcome-plugin</plugin.id>
+ <plugin.class>ro.fortsoft.pf4j.demo.welcome.WelcomePlugin</plugin.class>
+ <plugin.version>0.0.1</plugin.version>
+ <plugin.provider>Decebal Suiu</plugin.provider>
+ <plugin.dependencies />
+ </properties>
+
+ <build>
+ <plugins>
+ <!-- DOESN'T WORK WITH MAVEN 3 (I defined the plugin metadata in properties section)
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>properties-maven-plugin</artifactId>
+ <version>1.0-alpha-2</version>
+ <executions>
+ <execution>
+ <phase>initialize</phase>
+ <goals>
+ <goal>read-project-properties</goal>
+ </goals>
+ <configuration>
+ <files>
+ <file>plugin.properties</file>
+ </files>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ -->
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <version>1.6</version>
+ <executions>
+ <execution>
+ <id>unzip jar file</id>
+ <phase>package</phase>
+ <configuration>
+ <target>
+ <unzip src="target/${artifactId}-${version}.${packaging}" dest="target/plugin-classes" />
+ </target>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+
+ <plugin>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <version>2.3</version>
+ <configuration>
+ <descriptors>
+ <descriptor>
+ src/main/assembly/assembly.xml
+ </descriptor>
+ </descriptors>
+ <appendAssemblyId>false</appendAssemblyId>
+ </configuration>
+ <executions>
+ <execution>
+ <id>make-assembly</id>
+ <phase>package</phase>
+ <goals>
+ <goal>attached</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>2.4</version>
+ <configuration>
+ <archive>
+ <manifestEntries>
+ <Plugin-Id>${plugin.id}</Plugin-Id>
+ <Plugin-Class>${plugin.class}</Plugin-Class>
+ <Plugin-Version>${plugin.version}</Plugin-Version>
+ <Plugin-Provider>${plugin.provider}</Plugin-Provider>
+ <Plugin-Dependencies>${plugin.dependencies}</Plugin-Dependencies>
+ </manifestEntries>
+ </archive>
+ </configuration>
+ </plugin>
+
+ <plugin>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <configuration>
+ <skip>true</skip>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <dependency>
+ <groupId>commons-lang</groupId>
+ <artifactId>commons-lang</artifactId>
+ <version>2.6</version>
+ </dependency>
+ </dependencies>
+
+</project>
diff --git a/demo/plugins/plugin2/pom.xml b/demo/plugins/plugin2/pom.xml
index 4b84e9f..23acb7a 100644
--- a/demo/plugins/plugin2/pom.xml
+++ b/demo/plugins/plugin2/pom.xml
@@ -1,115 +1,115 @@
-<?xml version="1.0"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
- <parent>
- <groupId>ro.fortsoft.pf4j.demo</groupId>
- <artifactId>pf4j-demo-plugins</artifactId>
- <version>0.6-SNAPSHOT</version>
- </parent>
-
- <modelVersion>4.0.0</modelVersion>
- <artifactId>pf4j-demo-plugin2</artifactId>
- <version>0.6-SNAPSHOT</version>
- <packaging>jar</packaging>
- <name>Demo Plugin #2</name>
-
- <properties>
- <plugin.id>hello-plugin</plugin.id>
- <plugin.class>ro.fortsoft.pf4j.demo.hello.HelloPlugin</plugin.class>
- <plugin.version>0.0.1</plugin.version>
- <plugin.provider>Decebal Suiu</plugin.provider>
- <plugin.dependencies />
- </properties>
-
- <build>
- <plugins>
- <!-- DOESN'T WORK WITH MAVEN 3 (I defined the plugin metadata in properties section)
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>properties-maven-plugin</artifactId>
- <version>1.0-alpha-2</version>
- <executions>
- <execution>
- <phase>initialize</phase>
- <goals>
- <goal>read-project-properties</goal>
- </goals>
- <configuration>
- <files>
- <file>plugin.properties</file>
- </files>
- </configuration>
- </execution>
- </executions>
- </plugin>
- -->
-
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-antrun-plugin</artifactId>
- <version>1.6</version>
- <executions>
- <execution>
- <id>unzip jar file</id>
- <phase>package</phase>
- <configuration>
- <target>
- <unzip src="target/${artifactId}-${version}.${packaging}" dest="target/plugin-classes" />
- </target>
- </configuration>
- <goals>
- <goal>run</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
-
- <plugin>
- <artifactId>maven-assembly-plugin</artifactId>
- <version>2.3</version>
- <configuration>
- <descriptors>
- <descriptor>
- src/main/assembly/assembly.xml
- </descriptor>
- </descriptors>
- <appendAssemblyId>false</appendAssemblyId>
- </configuration>
- <executions>
- <execution>
- <id>make-assembly</id>
- <phase>package</phase>
- <goals>
- <goal>attached</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
-
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-jar-plugin</artifactId>
- <version>2.4</version>
- <configuration>
- <archive>
- <manifestEntries>
- <Plugin-Id>${plugin.id}</Plugin-Id>
- <Plugin-Class>${plugin.class}</Plugin-Class>
- <Plugin-Version>${plugin.version}</Plugin-Version>
- <Plugin-Provider>${plugin.provider}</Plugin-Provider>
- <Plugin-Dependencies>${plugin.dependencies}</Plugin-Dependencies>
- </manifestEntries>
- </archive>
- </configuration>
- </plugin>
-
- <plugin>
- <artifactId>maven-deploy-plugin</artifactId>
- <configuration>
- <skip>true</skip>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
-</project>
+<?xml version="1.0"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <parent>
+ <groupId>ro.fortsoft.pf4j.demo</groupId>
+ <artifactId>pf4j-demo-plugins</artifactId>
+ <version>0.7-SNAPSHOT</version>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>pf4j-demo-plugin2</artifactId>
+ <version>0.7-SNAPSHOT</version>
+ <packaging>jar</packaging>
+ <name>Demo Plugin #2</name>
+
+ <properties>
+ <plugin.id>hello-plugin</plugin.id>
+ <plugin.class>ro.fortsoft.pf4j.demo.hello.HelloPlugin</plugin.class>
+ <plugin.version>0.0.1</plugin.version>
+ <plugin.provider>Decebal Suiu</plugin.provider>
+ <plugin.dependencies />
+ </properties>
+
+ <build>
+ <plugins>
+ <!-- DOESN'T WORK WITH MAVEN 3 (I defined the plugin metadata in properties section)
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>properties-maven-plugin</artifactId>
+ <version>1.0-alpha-2</version>
+ <executions>
+ <execution>
+ <phase>initialize</phase>
+ <goals>
+ <goal>read-project-properties</goal>
+ </goals>
+ <configuration>
+ <files>
+ <file>plugin.properties</file>
+ </files>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ -->
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <version>1.6</version>
+ <executions>
+ <execution>
+ <id>unzip jar file</id>
+ <phase>package</phase>
+ <configuration>
+ <target>
+ <unzip src="target/${artifactId}-${version}.${packaging}" dest="target/plugin-classes" />
+ </target>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+
+ <plugin>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <version>2.3</version>
+ <configuration>
+ <descriptors>
+ <descriptor>
+ src/main/assembly/assembly.xml
+ </descriptor>
+ </descriptors>
+ <appendAssemblyId>false</appendAssemblyId>
+ </configuration>
+ <executions>
+ <execution>
+ <id>make-assembly</id>
+ <phase>package</phase>
+ <goals>
+ <goal>attached</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>2.4</version>
+ <configuration>
+ <archive>
+ <manifestEntries>
+ <Plugin-Id>${plugin.id}</Plugin-Id>
+ <Plugin-Class>${plugin.class}</Plugin-Class>
+ <Plugin-Version>${plugin.version}</Plugin-Version>
+ <Plugin-Provider>${plugin.provider}</Plugin-Provider>
+ <Plugin-Dependencies>${plugin.dependencies}</Plugin-Dependencies>
+ </manifestEntries>
+ </archive>
+ </configuration>
+ </plugin>
+
+ <plugin>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <configuration>
+ <skip>true</skip>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
diff --git a/demo/plugins/plugin2/src/main/java/ro/fortsoft/pf4j/demo/hello/HelloPlugin.java b/demo/plugins/plugin2/src/main/java/ro/fortsoft/pf4j/demo/hello/HelloPlugin.java
index d8963fc..7072e3d 100644
--- a/demo/plugins/plugin2/src/main/java/ro/fortsoft/pf4j/demo/hello/HelloPlugin.java
+++ b/demo/plugins/plugin2/src/main/java/ro/fortsoft/pf4j/demo/hello/HelloPlugin.java
@@ -38,7 +38,7 @@ public class HelloPlugin extends Plugin {
System.out.println("HelloPlugin.stop()");
}
- @Extension
+ @Extension(ordinal=1)
public static class HelloGreeting implements Greeting {
@Override
diff --git a/demo/plugins/pom.xml b/demo/plugins/pom.xml
index 05f6c27..30c2848 100644
--- a/demo/plugins/pom.xml
+++ b/demo/plugins/pom.xml
@@ -1,106 +1,106 @@
-<?xml version="1.0"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
- <parent>
- <groupId>ro.fortsoft.pf4j.demo</groupId>
- <artifactId>pf4j-demo-parent</artifactId>
- <version>0.6-SNAPSHOT</version>
- </parent>
-
- <modelVersion>4.0.0</modelVersion>
- <groupId>ro.fortsoft.pf4j.demo</groupId>
- <artifactId>pf4j-demo-plugins</artifactId>
- <version>0.6-SNAPSHOT</version>
- <packaging>pom</packaging>
- <name>Demo Plugins Parent</name>
-
- <build>
- <resources>
- <resource>
- <filtering>false</filtering>
- <directory>src/main/java</directory>
- <excludes>
- <exclude>**/*.java</exclude>
- </excludes>
- </resource>
- <resource>
- <directory>src/main/resources</directory>
- </resource>
- </resources>
-
- <plugins>
- <plugin>
- <artifactId>maven-dependency-plugin</artifactId>
- <executions>
- <execution>
- <phase>process-sources</phase>
- <goals>
- <goal>copy-dependencies</goal>
- </goals>
- <configuration>
- <outputDirectory>${project.build.directory}/lib</outputDirectory>
- <excludeScope>provided</excludeScope>
- </configuration>
- </execution>
- </executions>
- </plugin>
- </plugins>
-
- <pluginManagement>
- <plugins>
- <plugin>
- <groupId>org.eclipse.m2e</groupId>
- <artifactId>lifecycle-mapping</artifactId>
- <version>1.0.0</version>
- <configuration>
- <lifecycleMappingMetadata>
- <pluginExecutions>
- <pluginExecution>
- <pluginExecutionFilter>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-dependency-plugin</artifactId>
- <versionRange>[2.0,)</versionRange>
- <goals>
- <goal>copy-dependencies</goal>
- </goals>
- </pluginExecutionFilter>
- <action>
- <!--
- <execute/>
- -->
- <execute>
- <runOnIncremental>true</runOnIncremental>
- <runOnConfiguration>true</runOnConfiguration>
- </execute>
- </action>
- </pluginExecution>
- </pluginExecutions>
- </lifecycleMappingMetadata>
- </configuration>
- </plugin>
- </plugins>
- </pluginManagement>
- </build>
-
- <modules>
- <module>plugin1</module>
- <module>plugin2</module>
- </modules>
-
- <dependencies>
- <dependency>
- <groupId>ro.fortsoft.pf4j</groupId>
- <artifactId>pf4j</artifactId>
- <version>${project.version}</version>
- <scope>provided</scope>
- </dependency>
-
- <dependency>
- <groupId>ro.fortsoft.pf4j.demo</groupId>
- <artifactId>pf4j-demo-api</artifactId>
- <version>${project.version}</version>
- <scope>provided</scope>
- </dependency>
- </dependencies>
-
-</project>
+<?xml version="1.0"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <parent>
+ <groupId>ro.fortsoft.pf4j.demo</groupId>
+ <artifactId>pf4j-demo-parent</artifactId>
+ <version>0.7-SNAPSHOT</version>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>ro.fortsoft.pf4j.demo</groupId>
+ <artifactId>pf4j-demo-plugins</artifactId>
+ <version>0.7-SNAPSHOT</version>
+ <packaging>pom</packaging>
+ <name>Demo Plugins Parent</name>
+
+ <build>
+ <resources>
+ <resource>
+ <filtering>false</filtering>
+ <directory>src/main/java</directory>
+ <excludes>
+ <exclude>**/*.java</exclude>
+ </excludes>
+ </resource>
+ <resource>
+ <directory>src/main/resources</directory>
+ </resource>
+ </resources>
+
+ <plugins>
+ <plugin>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <executions>
+ <execution>
+ <phase>process-sources</phase>
+ <goals>
+ <goal>copy-dependencies</goal>
+ </goals>
+ <configuration>
+ <outputDirectory>${project.build.directory}/lib</outputDirectory>
+ <excludeScope>provided</excludeScope>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.eclipse.m2e</groupId>
+ <artifactId>lifecycle-mapping</artifactId>
+ <version>1.0.0</version>
+ <configuration>
+ <lifecycleMappingMetadata>
+ <pluginExecutions>
+ <pluginExecution>
+ <pluginExecutionFilter>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <versionRange>[2.0,)</versionRange>
+ <goals>
+ <goal>copy-dependencies</goal>
+ </goals>
+ </pluginExecutionFilter>
+ <action>
+ <!--
+ <execute />
+ -->
+ <execute>
+ <runOnIncremental>true</runOnIncremental>
+ <runOnConfiguration>true</runOnConfiguration>
+ </execute>
+ </action>
+ </pluginExecution>
+ </pluginExecutions>
+ </lifecycleMappingMetadata>
+ </configuration>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+
+ <modules>
+ <module>plugin1</module>
+ <module>plugin2</module>
+ </modules>
+
+ <dependencies>
+ <dependency>
+ <groupId>ro.fortsoft.pf4j</groupId>
+ <artifactId>pf4j</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>ro.fortsoft.pf4j.demo</groupId>
+ <artifactId>pf4j-demo-api</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+
+</project>
diff --git a/demo/pom.xml b/demo/pom.xml
index 7d00cd7..9ce0579 100644
--- a/demo/pom.xml
+++ b/demo/pom.xml
@@ -4,13 +4,13 @@
<parent>
<groupId>ro.fortsoft.pf4j</groupId>
<artifactId>pf4j-parent</artifactId>
- <version>0.6-SNAPSHOT</version>
+ <version>0.7-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>ro.fortsoft.pf4j.demo</groupId>
<artifactId>pf4j-demo-parent</artifactId>
- <version>0.6-SNAPSHOT</version>
+ <version>0.7-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Demo Parent</name>
diff --git a/pf4j/pom.xml b/pf4j/pom.xml
index 0859a55..f06491e 100644
--- a/pf4j/pom.xml
+++ b/pf4j/pom.xml
@@ -4,23 +4,29 @@
<parent>
<groupId>ro.fortsoft.pf4j</groupId>
<artifactId>pf4j-parent</artifactId>
- <version>0.6-SNAPSHOT</version>
+ <version>0.7-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>pf4j</artifactId>
- <version>0.6-SNAPSHOT</version>
+ <version>0.7-SNAPSHOT</version>
<packaging>jar</packaging>
<name>PF4J</name>
<description>Plugin Framework for Java</description>
-
- <dependencies>
- <dependency>
- <groupId>net.java.sezpoz</groupId>
- <artifactId>sezpoz</artifactId>
- <version>1.9</version>
- </dependency>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <compilerArgument>-proc:none</compilerArgument>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
diff --git a/pf4j/src/main/java/ro/fortsoft/pf4j/DefaultExtensionFinder.java b/pf4j/src/main/java/ro/fortsoft/pf4j/DefaultExtensionFinder.java
index 66c1936..f61195b 100644
--- a/pf4j/src/main/java/ro/fortsoft/pf4j/DefaultExtensionFinder.java
+++ b/pf4j/src/main/java/ro/fortsoft/pf4j/DefaultExtensionFinder.java
@@ -12,16 +12,134 @@
*/
package ro.fortsoft.pf4j;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
/**
- * The default implementation for ExtensionFinder.
- * Now, this class it's a "link" to {@link ro.fortsoft.pf4j.SezpozExtensionFinder}.
+ * The default implementation for ExtensionFinder.
+ * All extensions declared in a plugin are indexed in a file "META-INF/extensions.idx".
+ * This class lookup extensions in all extensions index files "META-INF/extensions.idx".
*
* @author Decebal Suiu
*/
-public class DefaultExtensionFinder extends SezpozExtensionFinder {
+public class DefaultExtensionFinder implements ExtensionFinder {
+ private static final Logger log = LoggerFactory.getLogger(DefaultExtensionFinder.class);
+
+ private ClassLoader classLoader;
+ private ExtensionFactory extensionFactory;
+ private volatile Set<String> entries;
+
public DefaultExtensionFinder(ClassLoader classLoader) {
- super(classLoader);
+ this.classLoader = classLoader;
+ this.extensionFactory = createExtensionFactory();
}
+ @Override
+ public <T> List<ExtensionWrapper<T>> find(Class<T> type) {
+ log.debug("Find extensions for extension point {}", type.getName());
+ List<ExtensionWrapper<T>> result = new ArrayList<ExtensionWrapper<T>>();
+ if (entries == null) {
+ entries = readIndexFiles();
+ }
+
+ for (String entry : entries) {
+ try {
+ Class<?> extensionType = classLoader.loadClass(entry);
+ log.debug("Checking extension type {}", extensionType.getName());
+ if (type.isAssignableFrom(extensionType)) {
+ Object instance = extensionFactory.create(extensionType);
+ if (instance != null) {
+ Extension extension = extensionType.getAnnotation(Extension.class);
+ log.debug("Added extension {} with ordinal {}", extensionType.getName(), extension.ordinal());
+ result.add(new ExtensionWrapper<T>(type.cast(instance), extension.ordinal()));
+ }
+ } else {
+ log.warn("{} is not an extension for extension point {}", extensionType.getName(), type.getName());
+ }
+ } catch (ClassNotFoundException e) {
+ log.error(e.getMessage(), e);
+ }
+ }
+
+ if (entries.isEmpty()) {
+ log.debug("No extensions found for extension point {}", type.getName());
+ } else {
+ log.debug("Found {} extensions for extension point {}", entries.size(), type.getName());
+ }
+
+ // sort by "ordinal" property
+ Collections.sort(result);
+
+ return result;
+ }
+
+ /**
+ * Add the possibility to override the ExtensionFactory.
+ * The default implementation uses Class.newInstance() method.
+ */
+ protected ExtensionFactory createExtensionFactory() {
+ return new ExtensionFactory() {
+
+ @Override
+ public Object create(Class<?> extensionType) {
+ log.debug("Create instance for extension {}", extensionType.getName());
+
+ try {
+ return extensionType.newInstance();
+ } catch (InstantiationException e) {
+ log.error(e.getMessage(), e);
+ } catch (IllegalAccessException e) {
+ log.error(e.getMessage(), e);
+ }
+
+ return null;
+ }
+
+ };
+ }
+
+ private Set<String> readIndexFiles() {
+ log.debug("Reading extensions index files");
+ Set<String> entries = new HashSet<String>();
+
+ try {
+ Enumeration<URL> indexFiles = classLoader.getResources(ExtensionsIndexer.EXTENSIONS_RESOURCE);
+ while (indexFiles.hasMoreElements()) {
+ Reader reader = new InputStreamReader(indexFiles.nextElement().openStream(), "UTF-8");
+ ExtensionsIndexer.readIndex(reader, entries);
+ }
+ } catch (IOException e) {
+ log.error(e.getMessage(), e);
+ }
+
+ if (entries.isEmpty()) {
+ log.debug("No extensions found");
+ } else {
+ log.debug("Found possible {} extensions", entries.size());
+ }
+
+ return entries;
+ }
+
+ /**
+ * Creates an extension instance.
+ */
+ public static interface ExtensionFactory {
+
+ public Object create(Class<?> extensionType);
+
+ }
+
}
diff --git a/pf4j/src/main/java/ro/fortsoft/pf4j/DefaultPluginManager.java b/pf4j/src/main/java/ro/fortsoft/pf4j/DefaultPluginManager.java
index 30658cd..fcb839b 100644
--- a/pf4j/src/main/java/ro/fortsoft/pf4j/DefaultPluginManager.java
+++ b/pf4j/src/main/java/ro/fortsoft/pf4j/DefaultPluginManager.java
@@ -210,7 +210,7 @@ public class DefaultPluginManager implements PluginManager {
filterList.add(new NotFileFilter(createHiddenPluginFilter()));
FileFilter pluginsFilter = new AndFileFilter(filterList);
File[] directories = pluginsDirectory.listFiles(pluginsFilter);
- log.debug("Possible plugins: {}", Arrays.asList(directories));
+ log.debug("Found possible {} plugins: {}", directories.length, Arrays.asList(directories));
if (directories.length == 0) {
log.info("No plugins");
return;
diff --git a/pf4j/src/main/java/ro/fortsoft/pf4j/Extension.java b/pf4j/src/main/java/ro/fortsoft/pf4j/Extension.java
index f1b7cac..f2c01bd 100644
--- a/pf4j/src/main/java/ro/fortsoft/pf4j/Extension.java
+++ b/pf4j/src/main/java/ro/fortsoft/pf4j/Extension.java
@@ -19,12 +19,9 @@ import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
-import net.java.sezpoz.Indexable;
-
/**
* @author Decebal Suiu
*/
-@Indexable
@Retention(RUNTIME)
@Target(TYPE)
@Documented
diff --git a/pf4j/src/main/java/ro/fortsoft/pf4j/ExtensionsIndexer.java b/pf4j/src/main/java/ro/fortsoft/pf4j/ExtensionsIndexer.java
new file mode 100644
index 0000000..c4a8f40
--- /dev/null
+++ b/pf4j/src/main/java/ro/fortsoft/pf4j/ExtensionsIndexer.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2013 Decebal Suiu
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this work except in compliance with
+ * the License. You may obtain a copy of the License in the LICENSE file, or 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 ro.fortsoft.pf4j;
+
+import java.io.BufferedReader;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.Reader;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.annotation.processing.AbstractProcessor;
+import javax.annotation.processing.RoundEnvironment;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.TypeElement;
+import javax.tools.Diagnostic.Kind;
+import javax.tools.FileObject;
+import javax.tools.StandardLocation;
+
+/**
+ * @author Decebal Suiu
+ */
+public class ExtensionsIndexer extends AbstractProcessor {
+
+ public static final String EXTENSIONS_RESOURCE = "META-INF/extensions.idx";
+
+ private List<TypeElement> extensions = new ArrayList<TypeElement>();
+
+ @Override
+ public SourceVersion getSupportedSourceVersion() {
+ return SourceVersion.latest();
+ }
+
+ @Override
+ public Set<String> getSupportedAnnotationTypes() {
+ Set<String> annotationTypes = new HashSet<String>();
+ annotationTypes.add(Extension.class.getName());
+
+ return annotationTypes;
+ }
+
+ @Override
+ public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+ if (roundEnv.processingOver()) {
+ return false;
+ }
+
+ for (Element element : roundEnv.getElementsAnnotatedWith(Extension.class)) {
+ if (!(element instanceof TypeElement)) {
+ continue;
+ }
+
+ TypeElement typeElement = (TypeElement) element;
+ String message = "Extension found in " + processingEnv.getElementUtils().getBinaryName(typeElement).toString();
+ processingEnv.getMessager().printMessage(Kind.NOTE, message);
+ extensions.add(typeElement);
+ }
+
+ /*
+ if (!roundEnv.processingOver()) {
+ return false;
+ }
+ */
+
+ write();
+
+ return false;
+// return true; // no further processing of this annotation type
+ }
+
+ private void write() {
+ Set<String> entries = new HashSet<String>();
+ for (TypeElement typeElement : extensions) {
+ entries.add(processingEnv.getElementUtils().getBinaryName(typeElement).toString());
+ }
+
+ read(entries); // read old entries
+ write(entries); // write entries
+ }
+
+ private void write(Set<String> entries) {
+ try {
+ FileObject file = processingEnv.getFiler().createResource(StandardLocation.CLASS_OUTPUT, "", EXTENSIONS_RESOURCE);
+ Writer writer = file.openWriter();
+ for (String entry : entries) {
+ writer.write(entry);
+ writer.write("\n");
+ }
+ writer.close();
+ } catch (FileNotFoundException e) {
+ // it's the first time, create the file
+ } catch (IOException e) {
+ processingEnv.getMessager().printMessage(Kind.ERROR, e.toString());
+ }
+ }
+
+ private void read(Set<String> entries) {
+ try {
+ FileObject file = processingEnv.getFiler().getResource(StandardLocation.CLASS_OUTPUT, "", EXTENSIONS_RESOURCE);
+ readIndex(file.openReader(true), entries);
+ } catch (FileNotFoundException e) {
+ } catch (IOException e) {
+ // thrown by Eclipse JDT when not found
+ } catch (UnsupportedOperationException e) {
+ // java6 does not support reading old index files
+ }
+ }
+
+ public static void readIndex(Reader reader, Set<String> entries) throws IOException {
+ BufferedReader bufferedReader = new BufferedReader(reader);
+
+ String line;
+ while ((line = bufferedReader.readLine()) != null) {
+ entries.add(line);
+ }
+
+ reader.close();
+ }
+
+}
+ \ No newline at end of file
diff --git a/pf4j/src/main/java/ro/fortsoft/pf4j/SezpozExtensionFinder.java b/pf4j/src/main/java/ro/fortsoft/pf4j/SezpozExtensionFinder.java
deleted file mode 100644
index 3f5014c..0000000
--- a/pf4j/src/main/java/ro/fortsoft/pf4j/SezpozExtensionFinder.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright 2012 Decebal Suiu
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this work except in compliance with
- * the License. You may obtain a copy of the License in the LICENSE file, or 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 ro.fortsoft.pf4j;
-
-import java.lang.reflect.AnnotatedElement;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import net.java.sezpoz.Index;
-import net.java.sezpoz.IndexItem;
-
-/**
- * Using Sezpoz(http://sezpoz.java.net/) for extensions discovery.
- *
- * @author Decebal Suiu
- */
-public class SezpozExtensionFinder implements ExtensionFinder {
-
- private static final Logger log = LoggerFactory.getLogger(SezpozExtensionFinder.class);
-
- private volatile List<IndexItem<Extension, Object>> indices;
- private ClassLoader classLoader;
-
- public SezpozExtensionFinder(ClassLoader classLoader) {
- this.classLoader = classLoader;
- }
-
- @Override
- public <T> List<ExtensionWrapper<T>> find(Class<T> type) {
- log.debug("Find extensions for {}", type);
- List<ExtensionWrapper<T>> result = new ArrayList<ExtensionWrapper<T>>();
- getIndices();
-// System.out.println("indices = "+ indices);
- for (IndexItem<Extension, Object> item : indices) {
- try {
- AnnotatedElement element = item.element();
- Class<?> extensionType = (Class<?>) element;
- log.debug("Checking extension type {}", extensionType);
- if (type.isAssignableFrom(extensionType)) {
- Object instance = item.instance();
- if (instance != null) {
- log.debug("Added extension {}", extensionType);
- result.add(new ExtensionWrapper<T>(type.cast(instance), item.annotation().ordinal()));
- }
- }
- } catch (InstantiationException e) {
- log.error(e.getMessage(), e);
- }
- }
-
- return result;
- }
-
- private List<IndexItem<Extension, Object>> getIndices() {
- if (indices == null) {
- indices = new ArrayList<IndexItem<Extension, Object>>();
- Iterator<IndexItem<Extension, Object>> it = Index.load(Extension.class, Object.class, classLoader).iterator();
- while (it.hasNext()) {
- indices.add(it.next());
- }
- }
-
- return indices;
- }
-
-}
diff --git a/pf4j/src/main/resources/META-INF/services/javax.annotation.processing.Processor b/pf4j/src/main/resources/META-INF/services/javax.annotation.processing.Processor
new file mode 100644
index 0000000..a944d7c
--- /dev/null
+++ b/pf4j/src/main/resources/META-INF/services/javax.annotation.processing.Processor
@@ -0,0 +1 @@
+ro.fortsoft.pf4j.ExtensionsIndexer
diff --git a/pom.xml b/pom.xml
index c54a45b..cedf32e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -10,7 +10,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>ro.fortsoft.pf4j</groupId>
<artifactId>pf4j-parent</artifactId>
- <version>0.6-SNAPSHOT</version>
+ <version>0.7-SNAPSHOT</version>
<packaging>pom</packaging>
<name>PF4J Parent</name>
<description>Plugin Framework for Java</description>