]> source.dussan.org Git - pf4j.git/commitdiff
prepare for maven central repository
authorDecebal Suiu <decebal.suiu@gmail.com>
Tue, 16 Oct 2012 11:33:48 +0000 (14:33 +0300)
committerDecebal Suiu <decebal.suiu@gmail.com>
Tue, 16 Oct 2012 11:33:48 +0000 (14:33 +0300)
66 files changed:
README.md
demo/api/pom.xml
demo/api/src/main/java/org/pf4j/demo/api/Greeting.java [deleted file]
demo/api/src/main/java/ro/fortsoft/pf4j/demo/api/Greeting.java [new file with mode: 0644]
demo/app/pom.xml
demo/app/src/main/java/org/pf4j/demo/Boot.java [deleted file]
demo/app/src/main/java/ro/fortsoft/pf4j/demo/Boot.java [new file with mode: 0644]
demo/plugin1/plugin.properties
demo/plugin1/pom.xml
demo/plugin1/src/main/java/org/pf4j/demo/welcome/WelcomePlugin.java [deleted file]
demo/plugin1/src/main/java/ro/fortsoft/pf4j/demo/welcome/WelcomePlugin.java [new file with mode: 0644]
demo/plugin2/plugin.properties
demo/plugin2/pom.xml
demo/plugin2/src/main/java/org/pf4j/demo/hello/HelloPlugin.java [deleted file]
demo/plugin2/src/main/java/ro/fortsoft/pf4j/demo/hello/HelloPlugin.java [new file with mode: 0644]
demo/pom.xml
pf4j/pom.xml
pf4j/src/main/java/org/pf4j/DefaultExtensionFinder.java [deleted file]
pf4j/src/main/java/org/pf4j/DefaultPluginDescriptorFinder.java [deleted file]
pf4j/src/main/java/org/pf4j/DefaultPluginManager.java [deleted file]
pf4j/src/main/java/org/pf4j/DependencyResolver.java [deleted file]
pf4j/src/main/java/org/pf4j/Extension.java [deleted file]
pf4j/src/main/java/org/pf4j/ExtensionFinder.java [deleted file]
pf4j/src/main/java/org/pf4j/ExtensionPoint.java [deleted file]
pf4j/src/main/java/org/pf4j/ExtensionWrapper.java [deleted file]
pf4j/src/main/java/org/pf4j/Plugin.java [deleted file]
pf4j/src/main/java/org/pf4j/PluginClassLoader.java [deleted file]
pf4j/src/main/java/org/pf4j/PluginDescriptor.java [deleted file]
pf4j/src/main/java/org/pf4j/PluginDescriptorFinder.java [deleted file]
pf4j/src/main/java/org/pf4j/PluginException.java [deleted file]
pf4j/src/main/java/org/pf4j/PluginLoader.java [deleted file]
pf4j/src/main/java/org/pf4j/PluginManager.java [deleted file]
pf4j/src/main/java/org/pf4j/PluginVersion.java [deleted file]
pf4j/src/main/java/org/pf4j/PluginWrapper.java [deleted file]
pf4j/src/main/java/org/pf4j/util/DirectedGraph.java [deleted file]
pf4j/src/main/java/org/pf4j/util/DirectoryFilter.java [deleted file]
pf4j/src/main/java/org/pf4j/util/ExtensionFilter.java [deleted file]
pf4j/src/main/java/org/pf4j/util/JarFilter.java [deleted file]
pf4j/src/main/java/org/pf4j/util/UberClassLoader.java [deleted file]
pf4j/src/main/java/org/pf4j/util/Unzip.java [deleted file]
pf4j/src/main/java/org/pf4j/util/ZipFilter.java [deleted file]
pf4j/src/main/java/ro/fortsoft/pf4j/DefaultExtensionFinder.java [new file with mode: 0644]
pf4j/src/main/java/ro/fortsoft/pf4j/DefaultPluginDescriptorFinder.java [new file with mode: 0644]
pf4j/src/main/java/ro/fortsoft/pf4j/DefaultPluginManager.java [new file with mode: 0644]
pf4j/src/main/java/ro/fortsoft/pf4j/DependencyResolver.java [new file with mode: 0644]
pf4j/src/main/java/ro/fortsoft/pf4j/Extension.java [new file with mode: 0644]
pf4j/src/main/java/ro/fortsoft/pf4j/ExtensionFinder.java [new file with mode: 0644]
pf4j/src/main/java/ro/fortsoft/pf4j/ExtensionPoint.java [new file with mode: 0644]
pf4j/src/main/java/ro/fortsoft/pf4j/ExtensionWrapper.java [new file with mode: 0644]
pf4j/src/main/java/ro/fortsoft/pf4j/Plugin.java [new file with mode: 0644]
pf4j/src/main/java/ro/fortsoft/pf4j/PluginClassLoader.java [new file with mode: 0644]
pf4j/src/main/java/ro/fortsoft/pf4j/PluginDescriptor.java [new file with mode: 0644]
pf4j/src/main/java/ro/fortsoft/pf4j/PluginDescriptorFinder.java [new file with mode: 0644]
pf4j/src/main/java/ro/fortsoft/pf4j/PluginException.java [new file with mode: 0644]
pf4j/src/main/java/ro/fortsoft/pf4j/PluginLoader.java [new file with mode: 0644]
pf4j/src/main/java/ro/fortsoft/pf4j/PluginManager.java [new file with mode: 0644]
pf4j/src/main/java/ro/fortsoft/pf4j/PluginVersion.java [new file with mode: 0644]
pf4j/src/main/java/ro/fortsoft/pf4j/PluginWrapper.java [new file with mode: 0644]
pf4j/src/main/java/ro/fortsoft/pf4j/util/DirectedGraph.java [new file with mode: 0644]
pf4j/src/main/java/ro/fortsoft/pf4j/util/DirectoryFilter.java [new file with mode: 0644]
pf4j/src/main/java/ro/fortsoft/pf4j/util/ExtensionFilter.java [new file with mode: 0644]
pf4j/src/main/java/ro/fortsoft/pf4j/util/JarFilter.java [new file with mode: 0644]
pf4j/src/main/java/ro/fortsoft/pf4j/util/UberClassLoader.java [new file with mode: 0644]
pf4j/src/main/java/ro/fortsoft/pf4j/util/Unzip.java [new file with mode: 0644]
pf4j/src/main/java/ro/fortsoft/pf4j/util/ZipFilter.java [new file with mode: 0644]
pom.xml

index ff1870bbb8e4a44e92954db3dfcea43f62b98017..ae3a21261edb68787034dab8d8e920ab5a3dbbf9 100644 (file)
--- a/README.md
+++ b/README.md
@@ -30,7 +30,7 @@ In your pom.xml you must define the dependencies to PF4J artifacts with:
 
 ```xml
 <dependency>
-    <groupId>org.pf4j</groupId>
+    <groupId>ro.fortsoft.pf4j</groupId>
     <artifactId>pf4j</artifactId>
     <version>${pf4j.version}</version>
 </dependency>    
@@ -77,13 +77,13 @@ In this case the `classes/META-INF/MANIFEST.MF` looks like:
     Created-By: Apache Maven
     Built-By: decebal
     Build-Jdk: 1.6.0_17
-    Plugin-Class: org.pf4j.demo.welcome.WelcomePlugin
+    Plugin-Class: ro.fortsoft.pf4j.demo.welcome.WelcomePlugin
     Plugin-Dependencies: x, y, z
     Plugin-Id: welcome-plugin
     Plugin-Provider: Decebal Suiu
     Plugin-Version: 0.0.1
 
-In above manifest I described a plugin with id `welcome-plugin`, with class `org.pf4j.demo.welcome.WelcomePlugin`, with version `0.0.1` and with dependencies 
+In above manifest I described a plugin with id `welcome-plugin`, with class `ro.fortsoft.pf4j.demo.welcome.WelcomePlugin`, with version `0.0.1` and with dependencies 
 to plugins `x, y, z`.
 
 You can define an extension point in your application using **ExtensionPoint** interface marker.
index 1514476a533298151945657558eea68741b791fb..59c02ff771faba7c4d7ae7d21c9140311372a26a 100644 (file)
@@ -2,7 +2,7 @@
 <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>org.pf4j.demo</groupId>
+        <groupId>ro.fortsoft.pf4j.demo</groupId>
         <artifactId>pom</artifactId>
         <version>0.1-SNAPSHOT</version>
     </parent>
@@ -34,7 +34,7 @@
     
     <dependencies>
         <dependency>
-            <groupId>org.pf4j</groupId>
+            <groupId>ro.fortsoft.pf4j</groupId>
             <artifactId>pf4j</artifactId>
             <version>${project.version}</version>
             <scope>provided</scope>
diff --git a/demo/api/src/main/java/org/pf4j/demo/api/Greeting.java b/demo/api/src/main/java/org/pf4j/demo/api/Greeting.java
deleted file mode 100644 (file)
index b21f80c..0000000
+++ /dev/null
@@ -1,24 +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 org.pf4j.demo.api;
-
-import org.pf4j.ExtensionPoint;
-
-/**
- * @author Decebal Suiu
- */
-public interface Greeting extends ExtensionPoint {
-
-    public String getGreeting();
-
-}
diff --git a/demo/api/src/main/java/ro/fortsoft/pf4j/demo/api/Greeting.java b/demo/api/src/main/java/ro/fortsoft/pf4j/demo/api/Greeting.java
new file mode 100644 (file)
index 0000000..9a700c2
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * 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.demo.api;
+
+import ro.fortsoft.pf4j.ExtensionPoint;
+
+/**
+ * @author Decebal Suiu
+ */
+public interface Greeting extends ExtensionPoint {
+
+    public String getGreeting();
+
+}
index d9084b19cf0fa838ebc2febfa814a3e8a28e4793..38867a92d7386afe3f3c1a7c538fea54e69c87b4 100644 (file)
@@ -2,7 +2,7 @@
 <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>org.pf4j.demo</groupId>
+        <groupId>ro.fortsoft.pf4j.demo</groupId>
         <artifactId>pom</artifactId>
         <version>0.1-SNAPSHOT</version>
     </parent>
@@ -22,7 +22,7 @@
     </licenses>
 
     <properties>
-        <main.class>org.pf4j.demo.Boot</main.class>
+        <main.class>ro.fortsoft.pf4j.demo.Boot</main.class>
     </properties>
     
     <build>
 
     <dependencies>
         <dependency>
-            <groupId>org.pf4j</groupId>
+            <groupId>ro.fortsoft.pf4j</groupId>
             <artifactId>pf4j</artifactId>
             <version>${project.version}</version>
         </dependency>    
         <dependency>
-            <groupId>org.pf4j.demo</groupId>
+            <groupId>ro.fortsoft.pf4j.demo</groupId>
             <artifactId>pf4j-demo-api</artifactId>
             <version>${project.version}</version>
         </dependency>        
diff --git a/demo/app/src/main/java/org/pf4j/demo/Boot.java b/demo/app/src/main/java/org/pf4j/demo/Boot.java
deleted file mode 100644 (file)
index b34af53..0000000
+++ /dev/null
@@ -1,63 +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 org.pf4j.demo;
-
-import java.util.List;
-
-import org.apache.commons.lang.StringUtils;
-import org.pf4j.DefaultPluginManager;
-import org.pf4j.ExtensionWrapper;
-import org.pf4j.PluginManager;
-import org.pf4j.demo.api.Greeting;
-
-/**
- * A boot class that start the demo.
- *
- * @author Decebal Suiu
- */
-public class Boot {
-
-    public static void main(String[] args) {
-       // print logo
-       printLogo();
-       
-        // load and start (active/resolved) plugins
-        final PluginManager pluginManager = new DefaultPluginManager();
-        pluginManager.loadPlugins();
-        pluginManager.startPlugins();
-        
-        List<ExtensionWrapper<Greeting>> greetings = pluginManager.getExtensions(Greeting.class);
-        for (ExtensionWrapper<Greeting> greeting : greetings) {
-               System.out.println(">>> " + greeting.getInstance().getGreeting());
-        }
-        
-        pluginManager.stopPlugins();
-        /*
-        Runtime.getRuntime().addShutdownHook(new Thread() {
-
-                       @Override
-                       public void run() {
-                               pluginManager.stopPlugins();
-                       }
-               
-        });
-        */
-    }
-
-       private static void printLogo() {
-       System.out.println(StringUtils.repeat("#", 40));
-       System.out.println(StringUtils.center("PF4J-DEMO", 40));
-       System.out.println(StringUtils.repeat("#", 40));                
-       }
-
-}
diff --git a/demo/app/src/main/java/ro/fortsoft/pf4j/demo/Boot.java b/demo/app/src/main/java/ro/fortsoft/pf4j/demo/Boot.java
new file mode 100644 (file)
index 0000000..9a361fa
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * 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.demo;
+
+import java.util.List;
+
+import org.apache.commons.lang.StringUtils;
+
+import ro.fortsoft.pf4j.DefaultPluginManager;
+import ro.fortsoft.pf4j.ExtensionWrapper;
+import ro.fortsoft.pf4j.PluginManager;
+import ro.fortsoft.pf4j.demo.api.Greeting;
+
+/**
+ * A boot class that start the demo.
+ *
+ * @author Decebal Suiu
+ */
+public class Boot {
+
+    public static void main(String[] args) {
+       // print logo
+       printLogo();
+       
+        // load and start (active/resolved) plugins
+        final PluginManager pluginManager = new DefaultPluginManager();
+        pluginManager.loadPlugins();
+        pluginManager.startPlugins();
+        
+        List<ExtensionWrapper<Greeting>> greetings = pluginManager.getExtensions(Greeting.class);
+        for (ExtensionWrapper<Greeting> greeting : greetings) {
+               System.out.println(">>> " + greeting.getInstance().getGreeting());
+        }
+        
+        pluginManager.stopPlugins();
+        /*
+        Runtime.getRuntime().addShutdownHook(new Thread() {
+
+                       @Override
+                       public void run() {
+                               pluginManager.stopPlugins();
+                       }
+               
+        });
+        */
+    }
+
+       private static void printLogo() {
+       System.out.println(StringUtils.repeat("#", 40));
+       System.out.println(StringUtils.center("PF4J-DEMO", 40));
+       System.out.println(StringUtils.repeat("#", 40));                
+       }
+
+}
index 9da9bcce6bb56f3640c64d593c0ea7d003e0c021..4f95d990cb51ff8b717348768250db980333c686 100644 (file)
@@ -1,5 +1,5 @@
 plugin.id=welcome-plugin
-plugin.class=org.pf4j.demo.welcome.WelcomePlugin
+plugin.class=ro.fortsoft.pf4j.demo.welcome.WelcomePlugin
 plugin.version=0.0.1
 plugin.provider=Decebal Suiu
 plugin.dependencies=
index 10c1163e49ea5b4ff30ace79da57e7d6c448db56..99d467e7c41eb9592255cd3127c3698f31a60e16 100644 (file)
@@ -2,7 +2,7 @@
 <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>org.pf4j.demo</groupId>
+        <groupId>ro.fortsoft.pf4j.demo</groupId>
         <artifactId>pom</artifactId>
         <version>0.1-SNAPSHOT</version>
     </parent>
         
     <dependencies>
         <dependency>
-            <groupId>org.pf4j</groupId>
+            <groupId>ro.fortsoft.pf4j</groupId>
             <artifactId>pf4j</artifactId>
             <version>${project.version}</version>
             <scope>provided</scope>
         </dependency>    
         <dependency>
-            <groupId>org.pf4j.demo</groupId>
+            <groupId>ro.fortsoft.pf4j.demo</groupId>
             <artifactId>pf4j-demo-api</artifactId>
             <version>${project.version}</version>
             <scope>provided</scope>
diff --git a/demo/plugin1/src/main/java/org/pf4j/demo/welcome/WelcomePlugin.java b/demo/plugin1/src/main/java/org/pf4j/demo/welcome/WelcomePlugin.java
deleted file mode 100644 (file)
index 22ebf7d..0000000
+++ /dev/null
@@ -1,46 +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 org.pf4j.demo.welcome;
-
-import org.pf4j.Extension;
-import org.pf4j.Plugin;
-import org.pf4j.PluginWrapper;
-import org.pf4j.demo.api.Greeting;
-
-/**
- * @author Decebal Suiu
- */
-public class WelcomePlugin extends Plugin {
-
-    public WelcomePlugin(PluginWrapper wrapper) {
-        super(wrapper);
-    }
-
-    public void start() {
-        System.out.println("WelcomePlugin.start()");
-    }
-
-    public void stop() {
-        System.out.println("WelcomePlugin.stop()");
-    }
-
-    @Extension
-    public static class WelcomeGreeting implements Greeting {
-
-        public String getGreeting() {
-            return "Welcome";
-        }
-
-    }
-
-}
diff --git a/demo/plugin1/src/main/java/ro/fortsoft/pf4j/demo/welcome/WelcomePlugin.java b/demo/plugin1/src/main/java/ro/fortsoft/pf4j/demo/welcome/WelcomePlugin.java
new file mode 100644 (file)
index 0000000..d10d3dd
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * 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.demo.welcome;
+
+import ro.fortsoft.pf4j.Extension;
+import ro.fortsoft.pf4j.Plugin;
+import ro.fortsoft.pf4j.PluginWrapper;
+import ro.fortsoft.pf4j.demo.api.Greeting;
+
+/**
+ * @author Decebal Suiu
+ */
+public class WelcomePlugin extends Plugin {
+
+    public WelcomePlugin(PluginWrapper wrapper) {
+        super(wrapper);
+    }
+
+    public void start() {
+        System.out.println("WelcomePlugin.start()");
+    }
+
+    public void stop() {
+        System.out.println("WelcomePlugin.stop()");
+    }
+
+    @Extension
+    public static class WelcomeGreeting implements Greeting {
+
+        public String getGreeting() {
+            return "Welcome";
+        }
+
+    }
+
+}
index 60b6f3336178298fe13b0ae419355bd1c35640d5..0de45e6f884d4a7482dd3541008cad4d16c74d75 100644 (file)
@@ -1,5 +1,5 @@
 plugin.id=hello-plugin
-plugin.class=org.pf4j.demo.hello.HelloPlugin
+plugin.class=ro.fortsoft.pf4j.demo.hello.HelloPlugin
 plugin.version=0.0.1
 plugin.provider=Decebal Suiu
 plugin.dependencies=
index 7f4f6171b1a84978153cf402a34d4f5c42559528..c1b5cb3587b02dbfeb4cd7b29a2281c38a385015 100644 (file)
@@ -2,7 +2,7 @@
 <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>org.pf4j.demo</groupId>
+        <groupId>ro.fortsoft.pf4j.demo</groupId>
         <artifactId>pom</artifactId>
         <version>0.1-SNAPSHOT</version>
     </parent>
         
     <dependencies>
         <dependency>
-            <groupId>org.pf4j</groupId>
+            <groupId>ro.fortsoft.pf4j</groupId>
             <artifactId>pf4j</artifactId>
             <version>${project.version}</version>
             <scope>provided</scope>
         </dependency>    
         <dependency>
-            <groupId>org.pf4j.demo</groupId>
+            <groupId>ro.fortsoft.pf4j.demo</groupId>
             <artifactId>pf4j-demo-api</artifactId>
             <version>${project.version}</version>
             <scope>provided</scope>
diff --git a/demo/plugin2/src/main/java/org/pf4j/demo/hello/HelloPlugin.java b/demo/plugin2/src/main/java/org/pf4j/demo/hello/HelloPlugin.java
deleted file mode 100644 (file)
index ad7fd0c..0000000
+++ /dev/null
@@ -1,48 +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 org.pf4j.demo.hello;
-
-import org.pf4j.Extension;
-import org.pf4j.Plugin;
-import org.pf4j.PluginWrapper;
-import org.pf4j.demo.api.Greeting;
-
-/**
- * A very simple plugin.
- *
- * @author Decebal Suiu
- */
-public class HelloPlugin extends Plugin {
-
-    public HelloPlugin(PluginWrapper wrapper) {
-        super(wrapper);
-    }
-
-    public void start() {
-        System.out.println("HelloPlugin.start()");
-    }
-
-    public void stop() {
-        System.out.println("HelloPlugin.stop()");
-    }
-
-    @Extension
-    public static class HelloGreeting implements Greeting {
-
-        public String getGreeting() {
-            return "Hello";
-        }
-
-    }
-
-}
diff --git a/demo/plugin2/src/main/java/ro/fortsoft/pf4j/demo/hello/HelloPlugin.java b/demo/plugin2/src/main/java/ro/fortsoft/pf4j/demo/hello/HelloPlugin.java
new file mode 100644 (file)
index 0000000..8f12e23
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * 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.demo.hello;
+
+import ro.fortsoft.pf4j.Extension;
+import ro.fortsoft.pf4j.Plugin;
+import ro.fortsoft.pf4j.PluginWrapper;
+import ro.fortsoft.pf4j.demo.api.Greeting;
+
+/**
+ * A very simple plugin.
+ *
+ * @author Decebal Suiu
+ */
+public class HelloPlugin extends Plugin {
+
+    public HelloPlugin(PluginWrapper wrapper) {
+        super(wrapper);
+    }
+
+    public void start() {
+        System.out.println("HelloPlugin.start()");
+    }
+
+    public void stop() {
+        System.out.println("HelloPlugin.stop()");
+    }
+
+    @Extension
+    public static class HelloGreeting implements Greeting {
+
+        public String getGreeting() {
+            return "Hello";
+        }
+
+    }
+
+}
index dbb029a7bd8a2ba390f37c580c726f1a1d649dba..ec642decfc774d942c60c38599054184307e2c41 100644 (file)
@@ -2,13 +2,13 @@
 <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>org.pf4j</groupId>
+        <groupId>ro.fortsoft.pf4j</groupId>
         <artifactId>pom</artifactId>
         <version>0.1-SNAPSHOT</version>
     </parent>
 
     <modelVersion>4.0.0</modelVersion>
-    <groupId>org.pf4j.demo</groupId>
+    <groupId>ro.fortsoft.pf4j.demo</groupId>
     <artifactId>pom</artifactId>
     <version>0.1-SNAPSHOT</version>
     <packaging>pom</packaging>
index 920a870bb57715e23539bee63b337916d2f5a39e..feae21a2b57e3db2ff353fdfea8ce1233ce5e704 100644 (file)
@@ -2,7 +2,7 @@
 <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>org.pf4j</groupId>
+        <groupId>ro.fortsoft.pf4j</groupId>
         <artifactId>pom</artifactId>
         <version>0.1-SNAPSHOT</version>
     </parent>
diff --git a/pf4j/src/main/java/org/pf4j/DefaultExtensionFinder.java b/pf4j/src/main/java/org/pf4j/DefaultExtensionFinder.java
deleted file mode 100644 (file)
index e7a6dc9..0000000
+++ /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 org.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 DefaultExtensionFinder implements ExtensionFinder {
-
-       private static final Logger LOG = LoggerFactory.getLogger(DefaultExtensionFinder.class);
-       
-       private volatile List<IndexItem<Extension, Object>> indices;
-       private ClassLoader classLoader;
-       
-       public DefaultExtensionFinder(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/java/org/pf4j/DefaultPluginDescriptorFinder.java b/pf4j/src/main/java/org/pf4j/DefaultPluginDescriptorFinder.java
deleted file mode 100644 (file)
index 0055e57..0000000
+++ /dev/null
@@ -1,90 +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 org.pf4j;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.util.jar.Attributes;
-import java.util.jar.Manifest;
-
-import org.apache.commons.lang.StringUtils;
-
-/**
- * Read the plugin descriptor from the manifest file.
- *
- * @author Decebal Suiu
- */
-public class DefaultPluginDescriptorFinder implements PluginDescriptorFinder {
-
-       @Override
-       public PluginDescriptor find(File pluginRepository) throws PluginException {
-       // TODO it's ok with classes/ ?
-        File manifestFile = new File(pluginRepository, "classes/META-INF/MANIFEST.MF");
-        if (!manifestFile.exists()) {
-            // not found a 'plugin.xml' file for this plugin
-            throw new PluginException("Cannot find '" + manifestFile + "' file");
-        }
-
-       FileInputStream input = null;
-               try {
-                       input = new FileInputStream(manifestFile);
-               } catch (FileNotFoundException e) {
-                       // not happening 
-               }
-               
-       Manifest manifest = null;
-        try {
-            manifest = new Manifest(input);
-        } catch (IOException e) {
-            throw new PluginException(e.getMessage(), e);
-        } finally {
-            try {
-                               input.close();
-                       } catch (IOException e) {
-                               throw new PluginException(e.getMessage(), e);
-                       }
-        } 
-        
-        PluginDescriptor pluginDescriptor = new PluginDescriptor();
-        
-        // TODO validate !!!
-        Attributes attrs = manifest.getMainAttributes();
-        String id = attrs.getValue("Plugin-Id");
-        if (StringUtils.isEmpty(id)) {
-               throw new PluginException("Plugin-Id cannot be empty");
-        }
-        pluginDescriptor.setPluginId(id);
-        
-        String clazz = attrs.getValue("Plugin-Class");
-        if (StringUtils.isEmpty(clazz)) {
-               throw new PluginException("Plugin-Class cannot be empty");
-        }
-        pluginDescriptor.setPluginClass(clazz);
-        
-        String version = attrs.getValue("Plugin-Version");
-        if (StringUtils.isEmpty(version)) {
-               throw new PluginException("Plugin-Version cannot be empty");
-        }
-        pluginDescriptor.setPluginVersion(PluginVersion.createVersion(version));
-        
-        String provider = attrs.getValue("Plugin-Provider");
-        pluginDescriptor.setProvider(provider);        
-        String dependencies = attrs.getValue("Plugin-Dependencies");
-        pluginDescriptor.setDependencies(dependencies);
-
-               return pluginDescriptor;
-       }
-    
-}
diff --git a/pf4j/src/main/java/org/pf4j/DefaultPluginManager.java b/pf4j/src/main/java/org/pf4j/DefaultPluginManager.java
deleted file mode 100644 (file)
index 9cb7ccd..0000000
+++ /dev/null
@@ -1,327 +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 org.pf4j;
-
-import java.io.File;
-import java.io.FilenameFilter;
-import java.io.IOException;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Modifier;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.pf4j.util.DirectoryFilter;
-import org.pf4j.util.UberClassLoader;
-import org.pf4j.util.Unzip;
-import org.pf4j.util.ZipFilter;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-
-/**
- * Default implementation of the PluginManager interface.
- *
- * @author Decebal Suiu
- */
-public class DefaultPluginManager implements PluginManager {
-
-       private static final Logger LOG = LoggerFactory.getLogger(DefaultPluginManager.class);
-
-    /**
-     * The plugins repository.
-     */
-    private File pluginsDirectory;
-
-    private ExtensionFinder extensionFinder;
-    
-    private PluginDescriptorFinder pluginDescriptorFinder;
-    
-    /**
-     * A map of plugins this manager is responsible for (the key is the 'pluginId').
-     */
-    private Map<String, Plugin> plugins;
-
-    /**
-     * A map of plugin class loaders (he key is the 'pluginId').
-     */
-    private Map<String, PluginClassLoader> pluginClassLoaders;
-
-    /**
-     * A relation between 'pluginPath' and 'pluginId'
-     */
-    private Map<String, String> pathToIdMap;
-
-    /**
-     * A list with unresolved plugins (unresolved dependency).
-     */
-    private List<Plugin> unresolvedPlugins;
-
-    /**
-     * A list with resolved plugins (resolved dependency).
-     */
-    private List<Plugin> resolvedPlugins;
-
-    /**
-     * A list with disabled plugins.
-     */
-    private List<Plugin> disabledPlugins;
-    
-    private UberClassLoader uberClassLoader;
-
-    /**
-     * Th plugins directory is supplied by System.getProperty("pf4j.pluginsDir", "plugins").
-     */
-    public DefaultPluginManager() {
-       this(new File(System.getProperty("pf4j.pluginsDir", "plugins")));
-    }
-    
-    /**
-     * Constructs DefaultPluginManager which the given plugins directory.
-     *
-     * @param pluginsDirectory
-     *            the directory to search for plugins
-     */
-    public DefaultPluginManager(File pluginsDirectory) {
-        this.pluginsDirectory = pluginsDirectory;
-        plugins = new HashMap<String, Plugin>();
-        pluginClassLoaders = new HashMap<String, PluginClassLoader>();
-        pathToIdMap = new HashMap<String, String>();
-        unresolvedPlugins = new ArrayList<Plugin>();
-        resolvedPlugins = new ArrayList<Plugin>();
-        disabledPlugins = new ArrayList<Plugin>();
-        pluginDescriptorFinder = new DefaultPluginDescriptorFinder();
-        uberClassLoader = new UberClassLoader();
-        extensionFinder = new DefaultExtensionFinder(uberClassLoader);
-    }
-
-    /**
-     * Retrieves all active plugins.
-     */
-    public List<Plugin> getPlugins() {
-        return new ArrayList<Plugin>(plugins.values());
-    }
-
-       public List<Plugin> getResolvedPlugins() {
-               return resolvedPlugins;
-       }
-
-       public Plugin getPlugin(String pluginId) {
-               return plugins.get(pluginId);
-       }
-
-    public List<Plugin> getUnresolvedPlugins() {
-               return unresolvedPlugins;
-       }
-
-       public List<Plugin> getDisabledPlugins() {
-               return disabledPlugins;
-       }
-
-    /**
-     * Start all active plugins.
-     */
-    public void startPlugins() {
-       List<Plugin> resolvedPlugins = getResolvedPlugins();
-        for (Plugin plugin : resolvedPlugins) {
-            try {
-                               plugin.start();
-                       } catch (PluginException e) {
-                               // TODO Auto-generated catch block
-                               e.printStackTrace();
-                       }
-        }
-    }
-
-    /**
-     * Stop all active plugins.
-     */
-    public void stopPlugins() {
-       List<Plugin> resolvedPlugins = getResolvedPlugins();
-        for (Plugin plugin : resolvedPlugins) {
-            try {
-                               plugin.stop();
-                       } catch (PluginException e) {
-                               // TODO Auto-generated catch block
-                               e.printStackTrace();
-                       }
-        }
-    }
-
-    /**
-     * Load plugins.
-     */
-    public void loadPlugins() {
-       // check for plugins directory
-        if (!pluginsDirectory.exists() || !pluginsDirectory.isDirectory()) {
-            LOG.error("No '" + pluginsDirectory + "' directory");
-            return;
-        }
-
-        // expand all plugin archives
-        FilenameFilter zipFilter = new ZipFilter();
-        String[] zipFiles = pluginsDirectory.list(zipFilter);
-        for (String zipFile : zipFiles) {
-               try {
-                               expandPluginArchive(zipFile);
-                       } catch (IOException e) {
-                               LOG.error(e.getMessage(), e);
-                               e.printStackTrace();
-                       }
-        }
-
-        // load any plugin from plugins directory
-        FilenameFilter directoryFilter = new DirectoryFilter();
-        String[] directories = pluginsDirectory.list(directoryFilter);
-        for (String directory : directories) {
-            try {
-                loadPlugin(directory);
-            } catch (Exception e) {
-                               LOG.error(e.getMessage(), e);
-                e.printStackTrace();
-            }
-        }
-
-        // check for no plugins
-        if (directories.length == 0) {
-               LOG.info("No plugins");
-               return;
-        }
-
-        // resolve 'unresolvedPlugins'
-        resolvePlugins();
-    }
-
-    /**
-     * Get plugin class loader for this path.
-     */
-    public PluginClassLoader getPluginClassLoader(String pluginId) {
-       return pluginClassLoaders.get(pluginId);
-    }
-
-       public <T> List<ExtensionWrapper<T>> getExtensions(Class<T> type) {
-               return extensionFinder.find(type);
-       }
-       
-       private void loadPlugin(String fileName) throws Exception {
-        // test for plugin directory
-        File pluginDirectory = new File(pluginsDirectory, fileName);
-        if (!pluginDirectory.isDirectory()) {
-            return;
-        }
-
-        // try to load the plugin
-        String pluginPath = "/".concat(fileName);
-
-        // test for disabled plugin
-        if (disabledPlugins.contains(pluginPath)) {
-            return;
-        }
-
-        // it's a new plugin
-        if (plugins.get(pathToIdMap.get(pluginPath)) != null) {
-            return;
-        }
-
-        // retrieves the plugin descriptor
-        LOG.debug("Find plugin descriptor '" + pluginPath + "'");
-        PluginDescriptor pluginDescriptor = pluginDescriptorFinder.find(pluginDirectory);
-        LOG.debug("Descriptor " + pluginDescriptor);
-        String pluginClassName = pluginDescriptor.getPluginClass();
-        LOG.debug("Class '" + pluginClassName + "'" + " for plugin '" + pluginPath + "'");
-
-        // load plugin
-        LOG.debug("Loading plugin '" + pluginPath + "'");
-        PluginWrapper pluginWrapper = new PluginWrapper(pluginDescriptor);
-        PluginLoader pluginLoader = new PluginLoader(this, pluginWrapper, pluginDirectory);
-        pluginLoader.load();
-        LOG.debug("Loaded plugin '" + pluginPath + "'");
-        
-        // set some variables in plugin wrapper
-        pluginWrapper.setPluginPath(pluginPath);
-        pluginWrapper.setPluginClassLoader(pluginLoader.getPluginClassLoader());
-
-        // create the plugin instance
-        LOG.debug("Creating instance for plugin '" + pluginPath + "'");
-        Plugin plugin = getPluginInstance(pluginWrapper, pluginLoader);
-        LOG.debug("Created instance '" + plugin + "' for plugin '" + pluginPath + "'");
-
-        String pluginId = pluginDescriptor.getPluginId();
-
-        // add plugin to the list with plugins
-        plugins.put(pluginId, plugin);
-        unresolvedPlugins.add(plugin);
-
-        // add plugin class loader to the list with class loaders
-        PluginClassLoader pluginClassLoader = pluginLoader.getPluginClassLoader();
-        pluginDescriptor.setPluginClassLoader(pluginClassLoader);
-        pluginClassLoaders.put(pluginId, pluginClassLoader);
-    }
-
-    private void expandPluginArchive(String fileName) throws IOException {
-        File pluginArchiveFile = new File(pluginsDirectory, fileName);
-        long pluginArchiveDate = pluginArchiveFile.lastModified();
-        String pluginName = fileName.substring(0, fileName.length() - 4);
-        File pluginDirectory = new File(pluginsDirectory, pluginName);
-        // check if exists directory or the '.zip' file is "newer" than directory
-        if (!pluginDirectory.exists() || pluginArchiveDate > pluginDirectory.lastModified()) {
-               LOG.debug("Expand plugin archive '" + pluginArchiveFile + "' in '" + pluginDirectory + "'");
-            // create directorie for plugin
-            pluginDirectory.mkdirs();
-
-            // expand '.zip' file
-            Unzip unzip = new Unzip();
-            unzip.setSource(pluginArchiveFile);
-            unzip.setDestination(pluginDirectory);
-            unzip.extract();
-        }
-    }
-
-    private Plugin getPluginInstance(PluginWrapper pluginWrapper, PluginLoader pluginLoader)
-               throws Exception {
-       String pluginClassName = pluginWrapper.getDescriptor().getPluginClass();
-
-        ClassLoader pluginClassLoader = pluginLoader.getPluginClassLoader();
-        Class<?> pluginClass = pluginClassLoader.loadClass(pluginClassName);
-
-        // once we have the class, we can do some checks on it to ensure
-        // that it is a valid implementation of a plugin.
-        int modifiers = pluginClass.getModifiers();
-        if (Modifier.isAbstract(modifiers) || Modifier.isInterface(modifiers)
-                || (!Plugin.class.isAssignableFrom(pluginClass))) {
-            throw new PluginException("The plugin class '" + pluginClassName
-                    + "' is not compatible.");
-        }
-
-        // create the plugin instance
-        Constructor<?> constructor = pluginClass.getConstructor(new Class[] { PluginWrapper.class });
-        Plugin plugin = (Plugin) constructor.newInstance(new Object[] { pluginWrapper });
-
-        return plugin;
-    }
-
-       private void resolvePlugins() {
-        resolveDependencies();
-       }
-
-       private void resolveDependencies() {
-               DependencyResolver dependencyResolver = new DependencyResolver(unresolvedPlugins);
-        resolvedPlugins = dependencyResolver.getSortedDependencies();
-        for (Plugin plugin : resolvedPlugins) {
-               unresolvedPlugins.remove(plugin);
-               uberClassLoader.addLoader(plugin.getWrapper().getPluginClassLoader());
-        }
-       }
-
-}
diff --git a/pf4j/src/main/java/org/pf4j/DependencyResolver.java b/pf4j/src/main/java/org/pf4j/DependencyResolver.java
deleted file mode 100644 (file)
index 2f5f601..0000000
+++ /dev/null
@@ -1,81 +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 org.pf4j;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.pf4j.util.DirectedGraph;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-
-/**
- * @author Decebal Suiu
- */
-class DependencyResolver {
-
-       private static final Logger LOG = LoggerFactory.getLogger(DependencyResolver.class);
-       
-    private List<Plugin> plugins;
-
-       public DependencyResolver(List<Plugin> plugins) {
-               this.plugins = plugins;
-       }
-
-       /**
-        * Get the list of plugins in dependency sorted order.
-        */
-       public List<Plugin> getSortedDependencies() {
-               DirectedGraph<String> graph = new DirectedGraph<String>();
-               for (Plugin plugin : plugins) {
-                       PluginDescriptor descriptor = plugin.getWrapper().getDescriptor();
-                       String pluginId = descriptor.getPluginId();
-                       List<String> dependencies = descriptor.getDependencies();
-                       if (!dependencies.isEmpty()) {
-                               for (String dependency : dependencies) {
-                                       graph.addEdge(pluginId, dependency);
-                               }
-                       } else {
-                               graph.addVertex(pluginId);
-                       }
-               }
-
-               LOG.debug("Graph: " + graph);
-               List<String> pluginsId = graph.reverseTopologicalSort();
-
-               if (pluginsId == null) {
-                       LOG.error("Cyclic dependences !!!");
-                       return null;
-               }
-
-               LOG.debug("Plugins order: " + pluginsId);
-               List<Plugin> sortedPlugins = new ArrayList<Plugin>();
-               for (String pluginId : pluginsId) {
-                       sortedPlugins.add(getPlugin(pluginId));
-               }
-
-               return sortedPlugins;
-       }
-
-       private Plugin getPlugin(String pluginId) {
-               for (Plugin plugin : plugins) {
-                       if (pluginId.equals(plugin.getWrapper().getDescriptor().getPluginId())) {
-                               return plugin;
-                       }
-               }
-
-               return null;
-       }
-
-}
diff --git a/pf4j/src/main/java/org/pf4j/Extension.java b/pf4j/src/main/java/org/pf4j/Extension.java
deleted file mode 100644 (file)
index 6c499b6..0000000
+++ /dev/null
@@ -1,35 +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 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.Retention;
-import java.lang.annotation.Target;
-
-import net.java.sezpoz.Indexable;
-
-/**
- * @author Decebal Suiu
- */
-@Indexable
-@Retention(RUNTIME)
-@Target(TYPE)
-@Documented
-public @interface Extension {
-
-        int ordinal() default 0;
-        
-}
diff --git a/pf4j/src/main/java/org/pf4j/ExtensionFinder.java b/pf4j/src/main/java/org/pf4j/ExtensionFinder.java
deleted file mode 100644 (file)
index 5fc466d..0000000
+++ /dev/null
@@ -1,24 +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 org.pf4j;
-
-import java.util.List;
-
-/**
- * @author Decebal Suiu
- */
-public interface ExtensionFinder {
-
-       public <T> List<ExtensionWrapper<T>> find(Class<T> type);
-       
-}
diff --git a/pf4j/src/main/java/org/pf4j/ExtensionPoint.java b/pf4j/src/main/java/org/pf4j/ExtensionPoint.java
deleted file mode 100644 (file)
index 9113c1d..0000000
+++ /dev/null
@@ -1,20 +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 org.pf4j;
-
-/**
- * @author Decebal Suiu
- */
-public interface ExtensionPoint {
-
-}
diff --git a/pf4j/src/main/java/org/pf4j/ExtensionWrapper.java b/pf4j/src/main/java/org/pf4j/ExtensionWrapper.java
deleted file mode 100644 (file)
index 9ba320e..0000000
+++ /dev/null
@@ -1,41 +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 org.pf4j;
-
-/**
- * @author Decebal Suiu
- */
-public class ExtensionWrapper<T> implements Comparable<ExtensionWrapper<T>> {
-
-       private final T instance;
-       private final int ordinal;
-       
-       public ExtensionWrapper(T instance, int ordinal) {
-               this.instance = instance;
-               this.ordinal = ordinal;
-       }
-
-       public T getInstance() {
-               return instance;
-       }
-
-       public int getOrdinal() {
-               return ordinal;
-       }
-
-       @Override
-       public int compareTo(ExtensionWrapper<T> o) {
-               return (ordinal - o.getOrdinal());
-       }
-
-}
\ No newline at end of file
diff --git a/pf4j/src/main/java/org/pf4j/Plugin.java b/pf4j/src/main/java/org/pf4j/Plugin.java
deleted file mode 100644 (file)
index bab55c1..0000000
+++ /dev/null
@@ -1,68 +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 org.pf4j;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * This class will be extended by all plugins and
- * serve as the common class between a plugin and the application.
- *
- * @author Decebal Suiu
- */
-public abstract class Plugin {
-
-    /**
-     * Makes logging service available for descending classes.
-     */
-    protected final Logger log = LoggerFactory.getLogger(getClass());
-
-    /**
-     * Wrapper of the plugin.
-     */
-    PluginWrapper wrapper;
-
-    /**
-     * Constructor to be used by plugin manager for plugin instantiation.
-     * Your plugins have to provide constructor with this exact signature to
-     * be successfully loaded by manager.
-     */
-    public Plugin(final PluginWrapper wrapper) {
-        if (wrapper == null) {
-            throw new IllegalArgumentException("Wrapper cannot be null");
-        }
-
-        this.wrapper = wrapper;
-    }
-
-    /**
-     * Retrieves the wrapper of this plug-in.
-     */
-    public final PluginWrapper getWrapper() {
-        return wrapper;
-    }
-
-    /**
-     * Start method is called by the application when the plugin is loaded.
-     */
-    public void start() throws PluginException {
-    }
-
-    /**
-     * Stop method is called by the application when the plugin is unloaded.
-     */
-    public void stop() throws PluginException {
-    }
-
-}
diff --git a/pf4j/src/main/java/org/pf4j/PluginClassLoader.java b/pf4j/src/main/java/org/pf4j/PluginClassLoader.java
deleted file mode 100644 (file)
index 884642f..0000000
+++ /dev/null
@@ -1,91 +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 org.pf4j;
-
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.util.List;
-
-/**
- * One instance of this class should be created by plugin manager for every available plug-in.
- * 
- * @author Decebal Suiu
- */
-class PluginClassLoader extends URLClassLoader {
-
-       private static final String JAVA_PACKAGE_PREFIX = "java.";
-       private static final String JAVAX_PACKAGE_PREFIX = "javax.";
-       private static final String PLUGIN_PACKAGE_PREFIX = "org.pf4j.";
-
-       private PluginManager pluginManager;
-       private PluginWrapper pluginWrapper;
-
-       public PluginClassLoader(PluginManager pluginManager, PluginWrapper pluginWrapper, ClassLoader parent) {
-               super(new URL[0], parent);
-               
-               this.pluginManager = pluginManager;
-               this.pluginWrapper = pluginWrapper;
-       }
-
-       @Override
-       public void addURL(URL url) {
-               super.addURL(url);
-       }
-
-       @Override
-    public Class<?> loadClass(String className) throws ClassNotFoundException {
-//             System.out.println(">>>" + className);
-
-               // first check whether it's a system class, delegate to the system loader
-               if (className.startsWith(JAVA_PACKAGE_PREFIX) || className.startsWith(JAVAX_PACKAGE_PREFIX)) {
-                       return findSystemClass(className);
-               }
-
-        // second check whether it's already been loaded
-        Class<?> loadedClass = findLoadedClass(className);
-        if (loadedClass != null) {
-               return loadedClass;
-        }
-
-        // nope, try to load locally
-        try {
-               return findClass(className);
-        } catch (ClassNotFoundException e) {
-               // try next step
-        }
-
-        // if the class it's a part of the plugin engine use parent class loader
-        if (className.startsWith(PLUGIN_PACKAGE_PREFIX)) {
-               try {
-                       return PluginClassLoader.class.getClassLoader().loadClass(className);
-               } catch (ClassNotFoundException e) {
-                       // try next step
-               }
-        }
-
-        // look in dependencies
-        List<String> dependencies = pluginWrapper.getDescriptor().getDependencies();
-        for (String dependency : dependencies) {
-               PluginClassLoader classLoader = pluginManager.getPluginClassLoader(dependency);
-               try {
-                       return classLoader.loadClass(className);
-               } catch (ClassNotFoundException e) {
-                       // try next dependency
-               }
-        }
-
-        // use the standard URLClassLoader (which follows normal parent delegation)
-        return super.loadClass(className);
-    }
-
-}
diff --git a/pf4j/src/main/java/org/pf4j/PluginDescriptor.java b/pf4j/src/main/java/org/pf4j/PluginDescriptor.java
deleted file mode 100644 (file)
index 8346e48..0000000
+++ /dev/null
@@ -1,140 +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 org.pf4j;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-import org.apache.commons.lang.StringUtils;
-import org.apache.commons.lang.builder.ToStringBuilder;
-import org.apache.commons.lang.builder.ToStringStyle;
-
-/**
- * A plugin descriptor contains information about a plug-in obtained
- * from the manifest (META-INF) file.
- *
- * @author Decebal Suiu
- */
-class PluginDescriptor {
-
-       private String pluginId;
-    private String pluginClass;
-    private PluginVersion version;
-    private String provider;
-    private String pluginPath;
-    private List<String> dependencies;
-    private PluginClassLoader pluginClassLoader;
-
-    public PluginDescriptor() {
-        dependencies = new ArrayList<String>();
-    }
-
-    /**
-     * Returns the unique identifier of this plugin.
-     */
-    public String getPluginId() {
-        return pluginId;
-    }
-
-    /**
-     * Returns the name of the class that implements Plugin interface.
-     */
-    public String getPluginClass() {
-        return pluginClass;
-    }
-
-    /**
-     * Returns the version of this plugin.
-     */
-    public PluginVersion getVersion() {
-        return version;
-    }
-
-    /**
-     * Returns the provider name of this plugin.
-     */
-    public String getProvider() {
-        return provider;
-    }
-
-    /**
-     * Returns the path of this plugin relative to plugins directory.
-     */
-    public String getPluginPath() {
-        return pluginPath;
-    }
-
-    /**
-     * Returns all dependencies declared by this plugin.
-     * Returns an empty array if this plugin does not declare any require.
-     */
-    public List<String> getDependencies() {
-        return dependencies;
-    }
-
-    /**
-     * 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.
-        */
-    public PluginClassLoader getPluginClassLoader() {
-       return pluginClassLoader;
-    }
-
-    @Override
-    public String toString() {
-        return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
-            .append("pluginId", pluginId)
-            .append("pluginClass", pluginClass)
-            .append("version", version)
-            .append("provider", provider)
-            .append("pluginPath", pluginPath)
-            .append("dependencies", dependencies)
-            .toString();
-    }
-
-    void setPluginId(String pluginId) {
-        this.pluginId = pluginId;
-    }
-
-    void setPluginClass(String pluginClassName) {
-        this.pluginClass = pluginClassName;
-    }
-
-    void setPluginVersion(PluginVersion version) {
-        this.version = version;
-    }
-
-    void setProvider(String provider) {
-        this.provider = provider;
-    }
-
-    void setPluginPath(String pluginPath) {
-        this.pluginPath = pluginPath;
-    }
-    
-    void setDependencies(String dependencies) {
-       if (dependencies != null) {
-               this.dependencies = Arrays.asList(StringUtils.split(dependencies, ','));
-       } else {
-               this.dependencies = Collections.emptyList();
-       }
-    }
-
-       void setPluginClassLoader(PluginClassLoader pluginClassLoader) {
-               this.pluginClassLoader = pluginClassLoader;
-       }
-
-}
diff --git a/pf4j/src/main/java/org/pf4j/PluginDescriptorFinder.java b/pf4j/src/main/java/org/pf4j/PluginDescriptorFinder.java
deleted file mode 100644 (file)
index c59ec65..0000000
+++ /dev/null
@@ -1,28 +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 org.pf4j;
-
-import java.io.File;
-
-/**
- * Find a plugin descriptor in a directory (plugin repository).
- * You can find in manifest file @see DefaultPluginDescriptorFinder,
- * xml file, properties file, java services (with ServiceLoader), etc.
- * 
- * @author Decebal Suiu
- */
-public interface PluginDescriptorFinder {
-
-       public PluginDescriptor find(File pluginRepository) throws PluginException;
-       
-}
diff --git a/pf4j/src/main/java/org/pf4j/PluginException.java b/pf4j/src/main/java/org/pf4j/PluginException.java
deleted file mode 100644 (file)
index c341c70..0000000
+++ /dev/null
@@ -1,40 +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 org.pf4j;
-
-/**
- * An exception used to indicate that a plugin problem occurred.
- *
- * @author Decebal Suiu
- */
-class PluginException extends Exception {
-
-       private static final long serialVersionUID = 1L;
-
-       public PluginException() {
-        super();
-    }
-
-    public PluginException(String message) {
-        super(message);
-    }
-
-    public PluginException(Throwable cause) {
-        super(cause);
-    }
-
-    public PluginException(String message, Throwable cause) {
-        super(message, cause);
-    }
-
-}
diff --git a/pf4j/src/main/java/org/pf4j/PluginLoader.java b/pf4j/src/main/java/org/pf4j/PluginLoader.java
deleted file mode 100644 (file)
index bd64d59..0000000
+++ /dev/null
@@ -1,142 +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 org.pf4j;
-
-import java.io.File;
-import java.io.FilenameFilter;
-import java.net.MalformedURLException;
-import java.util.Vector;
-
-import org.pf4j.util.DirectoryFilter;
-import org.pf4j.util.JarFilter;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-
-/**
- * Load all informations needed by a plugin.
- * This means add all jar files from 'lib' directory, 'classes'
- * to classpath.
- * It's a class for only the internal use.
- *
- * @author Decebal Suiu
- */
-class PluginLoader {
-
-       private static final Logger LOG = LoggerFactory.getLogger(PluginLoader.class);
-
-    /*
-     * The plugin repository.
-     */
-    private File pluginRepository;
-
-    /*
-     * The directory with '.class' files.
-     */
-    private File classesDirectory;
-
-    /*
-     * The directory with '.jar' files.
-     */
-    private File libDirectory;
-
-    private PluginClassLoader pluginClassLoader;
-
-    public PluginLoader(PluginManager pluginManager, PluginWrapper pluginWrapper, File pluginRepository) {
-        this.pluginRepository = pluginRepository;
-        classesDirectory = new File(pluginRepository, "classes");
-        libDirectory = new File(pluginRepository, "lib");
-        ClassLoader parent = getClass().getClassLoader(); 
-        pluginClassLoader = new PluginClassLoader(pluginManager, pluginWrapper, parent);        
-        LOG.debug("Created class loader " + pluginClassLoader);
-    }
-
-    public File getPluginRepository() {
-        return pluginRepository;
-    }
-
-    public boolean load() {
-        return loadClassesAndJars();
-    }
-
-    public PluginClassLoader getPluginClassLoader() {
-               return pluginClassLoader;
-       }
-
-       private boolean loadClassesAndJars() {
-       return loadClasses() && loadJars();
-    }
-
-    private void getJars(Vector<String> v, File file) {
-        FilenameFilter jarFilter = new JarFilter();
-        FilenameFilter directoryFilter = new DirectoryFilter();
-
-        if (file.exists() && file.isDirectory() && file.isAbsolute()) {
-            String[] jars = file.list(jarFilter);
-            for (int i = 0; (jars != null) && (i < jars.length); ++i) {
-                v.addElement(jars[i]);
-            }
-
-            String[] directoryList = file.list(directoryFilter);
-            for (int i = 0; (directoryList != null) && (i < directoryList.length); ++i) {
-                File directory = new File(file, directoryList[i]);
-                getJars(v, directory);
-            }
-        }
-    }
-
-    private boolean loadClasses() {
-        // make 'classesDirectory' absolute
-        classesDirectory = classesDirectory.getAbsoluteFile();
-
-        if (classesDirectory.exists() && classesDirectory.isDirectory()) {
-            LOG.debug("Found '" + classesDirectory.getPath() + "' directory");
-
-            try {
-                pluginClassLoader.addURL(classesDirectory.toURI().toURL());
-                LOG.debug("Added '" + classesDirectory + "' to the class loader path");
-            } catch (MalformedURLException e) {
-                e.printStackTrace();
-                LOG.error(e.getMessage(), e);
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    /**
-     * Add all *.jar files from '/lib' directory.
-     */
-    private boolean loadJars() {
-        // make 'jarDirectory' absolute
-        libDirectory = libDirectory.getAbsoluteFile();
-
-        Vector<String> jars = new Vector<String>();
-        getJars(jars, libDirectory);
-        for (String jar : jars) {
-            File jarFile = new File(libDirectory, jar);
-            try {
-                pluginClassLoader.addURL(jarFile.toURI().toURL());
-                LOG.debug("Added '" + jarFile + "' to the class loader path");
-            } catch (MalformedURLException e) {
-                e.printStackTrace();
-                LOG.error(e.getMessage(), e);
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-}
diff --git a/pf4j/src/main/java/org/pf4j/PluginManager.java b/pf4j/src/main/java/org/pf4j/PluginManager.java
deleted file mode 100644 (file)
index cf0cff1..0000000
+++ /dev/null
@@ -1,49 +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 org.pf4j;
-
-import java.util.List;
-
-/**
- * Provides the functionality for plugin management such as load,
- * start and stop the plugins.
- *
- * @author Decebal Suiu
- */
-public interface PluginManager {
-
-    /**
-     * Retrieves all plugins.
-     */
-    public List<Plugin> getPlugins();
-
-    /**
-     * Load plugins.
-     */
-    public void loadPlugins();
-
-    /**
-     * Start all active plugins.
-     */
-    public void startPlugins();
-
-    /**
-     * Stop all active plugins.
-     */
-    public void stopPlugins();
-
-       public PluginClassLoader getPluginClassLoader(String pluginId);
-
-       public <T> List<ExtensionWrapper<T>> getExtensions(Class<T> type);
-       
-}
diff --git a/pf4j/src/main/java/org/pf4j/PluginVersion.java b/pf4j/src/main/java/org/pf4j/PluginVersion.java
deleted file mode 100644 (file)
index 66267c9..0000000
+++ /dev/null
@@ -1,191 +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 org.pf4j;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.StringTokenizer;
-
-/**
- * Represents the version of a Plugin and allows versions to be compared.
- * Version identifiers have five components.
- *
- *  1. Major version. A non-negative integer.
- *  2. Minor version. A non-negative integer.
- *  3. Release version. A non-negative integer.
- *  4. Build version. A non-negative integer.
- *  5. Qualifier. A text string.
- *
- * This class is immutable.
- *
- * @author Decebal Suiu
- */
-public class PluginVersion implements Comparable<PluginVersion> {
-
-       private int major;
-       private int minor;
-       private int release;
-       private int build;
-       private String qualifier;
-
-    private PluginVersion() {
-    }
-
-       public PluginVersion(int major, int minor, int release) {
-               this.major = major;
-               this.minor = minor;
-               this.release = release;
-       }
-
-       public PluginVersion(int major, int minor, int release, int build) {
-               this.major = major;
-               this.minor = minor;
-               this.release = release;
-               this.build = build;
-       }
-
-       public PluginVersion(int major, int minor, int release, int build, String qualifier) {
-               this.major = major;
-               this.minor = minor;
-               this.release = release;
-               this.build = build;
-               this.qualifier = qualifier;
-       }
-
-       public static PluginVersion createVersion(String version) {
-        if (version == null) {
-            return new PluginVersion();
-        }
-
-               PluginVersion v = new PluginVersion();
-
-               StringTokenizer st = new StringTokenizer(version, ".");
-               List<String> tmp = new ArrayList<String>();
-               for (int i = 0; st.hasMoreTokens() && i < 4; i++) {
-                       tmp.add(st.nextToken());
-               }
-
-               int n = tmp.size();
-               switch (n) {
-                       case 0 :
-                               break;
-                       case 1 :
-                               v.major = Integer.parseInt(tmp.get(0));
-                               break;
-                       case 2 :
-                               v.major = Integer.parseInt(tmp.get(0));
-                               v.minor = Integer.parseInt(tmp.get(1));
-                               break;
-                       case 3 :
-                               v.major = Integer.parseInt(tmp.get(0));
-                               v.minor = Integer.parseInt(tmp.get(1));
-                               v.release = Integer.parseInt(tmp.get(2));
-                               break;
-                       case 4 :
-                               v.major = Integer.parseInt(tmp.get(0));
-                               v.minor = Integer.parseInt(tmp.get(1));
-                               v.release = Integer.parseInt(tmp.get(2));
-                               v.build = Integer.parseInt(tmp.get(3));
-                               break;
-               }
-
-               return v;
-       }
-
-       public int getMajor() {
-               return this.major;
-       }
-
-       public int getMinor() {
-               return this.minor;
-       }
-
-       public int getRelease() {
-               return this.release;
-       }
-
-    public int getBuild() {
-        return this.build;
-    }
-
-    public String getQualifier() {
-               return qualifier;
-       }
-
-       public String toString() {
-        StringBuffer sb = new StringBuffer(50);
-        sb.append(major);
-        sb.append('.');
-        sb.append(minor);
-        sb.append('.');
-        sb.append(release);
-        sb.append('.');
-        sb.append(build);
-        if (qualifier != null) {
-               sb.append(qualifier);
-        }
-
-        return sb.toString();
-    }
-
-    public int compareTo(PluginVersion version) {
-        if (version.major > major) {
-            return 1;
-        } else if (version.major < major) {
-            return -1;
-        }
-
-        if (version.minor > minor) {
-            return 1;
-        } else if (version.minor < minor) {
-            return -1;
-        }
-
-        if (version.release > release) {
-            return 1;
-        } else if (version.release < release) {
-            return -1;
-        }
-
-        if (version.build > build) {
-            return 1;
-        } else if (version.build < build) {
-            return -1;
-        }
-
-        return 0;
-    }
-
-    /*
-    private String extractQualifier(String token) {
-       StringTokenizer st = new StringTokenizer(token, "-");
-       if (st.countTokens() == 2) {
-               return st.
-       }
-    }
-    */
-
-    // for test only
-    public static void main(String[] args) {
-        PluginVersion v = PluginVersion.createVersion("4.0.0.123");
-        System.out.println(v.toString());
-//        v = PluginVersion.createVersion("4.0.0.123-alpha");
-//        System.out.println(v.toString());
-        PluginVersion v1 = PluginVersion.createVersion("4.1.0");
-        System.out.println(v1.toString());
-        PluginVersion v2  = PluginVersion.createVersion("4.0.32");
-        System.out.println(v2.toString());
-        System.out.println(v1.compareTo(v2));
-    }
-
-}
diff --git a/pf4j/src/main/java/org/pf4j/PluginWrapper.java b/pf4j/src/main/java/org/pf4j/PluginWrapper.java
deleted file mode 100644 (file)
index 46a0da1..0000000
+++ /dev/null
@@ -1,61 +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 org.pf4j;
-
-/**
- * A wrapper over plugin instance.
- *
- * @author Decebal Suiu
- */
-public class PluginWrapper {
-
-       PluginDescriptor descriptor;
-       String pluginPath;
-       PluginClassLoader pluginClassLoader;
-       
-       public PluginWrapper(PluginDescriptor descriptor) {
-               this.descriptor = descriptor;
-       }
-       
-    /**
-     * Returns the plugin descriptor.
-     */
-    public PluginDescriptor getDescriptor() {
-       return descriptor;
-    }
-
-    /**
-     * Returns the path of this plugin relative to plugins directory.
-     */
-    public String 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.
-        */
-    public PluginClassLoader getPluginClassLoader() {
-       return pluginClassLoader;
-    }
-
-       void setPluginPath(String pluginPath) {
-               this.pluginPath = pluginPath;
-       }
-
-       void setPluginClassLoader(PluginClassLoader pluginClassLoader) {
-               this.pluginClassLoader = pluginClassLoader;
-       }
-
-}
diff --git a/pf4j/src/main/java/org/pf4j/util/DirectedGraph.java b/pf4j/src/main/java/org/pf4j/util/DirectedGraph.java
deleted file mode 100644 (file)
index a5fa829..0000000
+++ /dev/null
@@ -1,171 +0,0 @@
-/*\r
- * Copyright 2012 Decebal Suiu\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this work except in compliance with\r
- * the License. You may obtain a copy of the License in the LICENSE file, or at:\r
- * \r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- * \r
- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on\r
- * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the\r
- * specific language governing permissions and limitations under the License.\r
- */\r
-package org.pf4j.util;\r
-\r
-import java.util.ArrayList;\r
-import java.util.Collections;\r
-import java.util.HashMap;\r
-import java.util.List;\r
-import java.util.Map;\r
-import java.util.Stack;\r
-\r
-/**\r
- * @author Decebal Suiu\r
- */\r
-public class DirectedGraph<V> {\r
-\r
-    /**\r
-     * The implementation here is basically an adjacency list, but instead\r
-     * of an array of lists, a Map is used to map each vertex to its list of\r
-     * adjacent vertices.\r
-     */\r
-    private Map<V, List<V>> neighbors = new HashMap<V, List<V>>();\r
-\r
-    /**\r
-     * Add a vertex to the graph. Nothing happens if vertex is already in graph.\r
-     */\r
-    public void addVertex(V vertex) {\r
-        if (neighbors.containsKey(vertex)) {\r
-               return;\r
-        }\r
-        neighbors.put(vertex, new ArrayList<V>());\r
-    }\r
-\r
-    /**\r
-     * True if graph contains vertex.\r
-     */\r
-    public boolean containsVertex(V vertex) {\r
-        return neighbors.containsKey(vertex);\r
-    }\r
-\r
-    /**\r
-     * Add an edge to the graph; if either vertex does not exist, it's added.\r
-     * This implementation allows the creation of multi-edges and self-loops.\r
-     */\r
-    public void addEdge(V from, V to) {\r
-        this.addVertex(from);\r
-        this.addVertex(to);\r
-        neighbors.get(from).add(to);\r
-    }\r
-\r
-    /**\r
-     * Remove an edge from the graph. Nothing happens if no such edge.\r
-     * @throws IllegalArgumentException if either vertex doesn't exist.\r
-     */\r
-    public void remove(V from, V to) {\r
-        if (!(this.containsVertex(from) && this.containsVertex(to))) {\r
-            throw new IllegalArgumentException("Nonexistent vertex");\r
-        }\r
-        neighbors.get(from).remove(to);\r
-    }\r
-\r
-    /**\r
-     * Report (as a Map) the out-degree of each vertex.\r
-     */\r
-    public Map<V, Integer> outDegree() {\r
-        Map<V, Integer> result = new HashMap<V, Integer>();\r
-        for (V vertex : neighbors.keySet()) {\r
-               result.put(vertex, neighbors.get(vertex).size());\r
-        }\r
-\r
-        return result;\r
-    }\r
-\r
-    /**\r
-     * Report (as a Map) the in-degree of each vertex.\r
-     */\r
-    public Map<V,Integer> inDegree() {\r
-        Map<V, Integer> result = new HashMap<V, Integer>();\r
-        for (V vertex : neighbors.keySet()) {\r
-               result.put(vertex, 0); // all in-degrees are 0\r
-        }\r
-        for (V from : neighbors.keySet()) {\r
-            for (V to : neighbors.get(from)) {\r
-                result.put(to, result.get(to) + 1); // increment in-degree\r
-            }\r
-        }\r
-\r
-        return result;\r
-    }\r
-\r
-    /**\r
-     * Report (as a List) the topological sort of the vertices; null for no such sort.\r
-     */\r
-    public List<V> topologicalSort() {\r
-        Map<V, Integer> degree = inDegree();\r
-\r
-        // determine all vertices with zero in-degree\r
-        Stack<V> zeroVertices = new Stack<V>(); // stack as good as any here\r
-        for (V v : degree.keySet()) {\r
-            if (degree.get(v) == 0) {\r
-               zeroVertices.push(v);\r
-            }\r
-        }\r
-\r
-        // determine the topological order\r
-        List<V> result = new ArrayList<V>();\r
-        while (!zeroVertices.isEmpty()) {\r
-            V vertex = zeroVertices.pop(); // choose a vertex with zero in-degree\r
-            result.add(vertex); // vertex 'v' is next in topological order\r
-            // "remove" vertex 'v' by updating its neighbors\r
-            for (V neighbor : neighbors.get(vertex)) {\r
-                degree.put(neighbor, degree.get(neighbor) - 1);\r
-                // remember any vertices that now have zero in-degree\r
-                if (degree.get(neighbor) == 0) {\r
-                       zeroVertices.push(neighbor);\r
-                }\r
-            }\r
-        }\r
-\r
-        // check that we have used the entire graph (if not, there was a cycle)\r
-        if (result.size() != neighbors.size()) {\r
-               return null;\r
-        }\r
-\r
-        return result;\r
-    }\r
-\r
-    /**\r
-     * Report (as a List) the reverse topological sort of the vertices; null for no such sort.\r
-     */\r
-    public List<V> reverseTopologicalSort() {\r
-       List<V> list = topologicalSort();\r
-       if (list == null) {\r
-               return null;\r
-       }\r
-       Collections.reverse(list);\r
-\r
-       return list;\r
-    }\r
-\r
-    /**\r
-     * True if graph is a dag (directed acyclic graph).\r
-     */\r
-    public boolean isDag () {\r
-        return topologicalSort() != null;\r
-    }\r
-\r
-    /**\r
-     * String representation of graph.\r
-     */\r
-    @Override\r
-    public String toString() {\r
-        StringBuffer sb = new StringBuffer();\r
-        for (V vertex : neighbors.keySet()) {\r
-               sb.append("\n   " + vertex + " -> " + neighbors.get(vertex));\r
-        }\r
-\r
-        return sb.toString();\r
-    }\r
-\r
-}\r
diff --git a/pf4j/src/main/java/org/pf4j/util/DirectoryFilter.java b/pf4j/src/main/java/org/pf4j/util/DirectoryFilter.java
deleted file mode 100644 (file)
index c6a236b..0000000
+++ /dev/null
@@ -1,35 +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 org.pf4j.util;
-
-import java.io.File;
-import java.io.FileFilter;
-import java.io.FilenameFilter;
-
-/**
- * @author Decebal Suiu
- */
-public class DirectoryFilter implements FileFilter, FilenameFilter {
-
-    /**
-     * Accepts any file ending in .jar. The case of the filename is ignored.
-     */
-    public boolean accept(File file) {
-        return file.isDirectory();
-    }
-
-    public boolean accept(File dir, String name) {
-        return accept(new File(dir, name));
-    }
-
-}
diff --git a/pf4j/src/main/java/org/pf4j/util/ExtensionFilter.java b/pf4j/src/main/java/org/pf4j/util/ExtensionFilter.java
deleted file mode 100644 (file)
index 1252a4e..0000000
+++ /dev/null
@@ -1,41 +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 org.pf4j.util;
-
-import java.io.File;
-import java.io.FilenameFilter;
-
-/**
- * @author Decebal Suiu
- */
-public class ExtensionFilter implements FilenameFilter {
-
-    private String extension;
-
-    public ExtensionFilter(String extension) {
-        this.extension = extension;
-    }
-
-    /**
-     * Accepts any file ending in extension. The case of the filename is ignored.
-     */
-    public boolean accept(File file) {
-        // perform a case insensitive check.
-        return file.getName().toUpperCase().endsWith(extension.toUpperCase());
-    }
-
-    public boolean accept(File dir, String name) {
-        return accept(new File(dir, name));
-    }
-
-}
diff --git a/pf4j/src/main/java/org/pf4j/util/JarFilter.java b/pf4j/src/main/java/org/pf4j/util/JarFilter.java
deleted file mode 100644 (file)
index 09c322c..0000000
+++ /dev/null
@@ -1,32 +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 org.pf4j.util;
-
-/**
- * File filter that accepts all files ending with .JAR.
- * This filter is case insensitive.
- *
- * @author Decebal Suiu
- */
-public class JarFilter extends ExtensionFilter {
-
-    /**
-     * The extension that this filter will search for.
-     */
-    private static final String JAR_EXTENSION = ".JAR";
-
-    public JarFilter() {
-        super(JAR_EXTENSION);
-    }
-
-}
diff --git a/pf4j/src/main/java/org/pf4j/util/UberClassLoader.java b/pf4j/src/main/java/org/pf4j/util/UberClassLoader.java
deleted file mode 100644 (file)
index 4ecfe2c..0000000
+++ /dev/null
@@ -1,72 +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 org.pf4j.util;
-
-import java.io.IOException;
-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;
-
-/**
- * A class loader that has multiple loaders and uses them for loading classes and resources.
- * 
- * @author Decebal Suiu
- */
-public class UberClassLoader extends ClassLoader {
-
-       private Set<ClassLoader> loaders = new HashSet<ClassLoader>();
-
-       public void addLoader(ClassLoader loader) {
-               loaders.add(loader);
-       }
-
-       @Override
-       public Class<?> findClass(String name) throws ClassNotFoundException {
-               for (ClassLoader loader : loaders) {
-                       try {
-                               return loader.loadClass(name);
-                       } catch (ClassNotFoundException e) {
-                               // try next
-                       }
-               }
-               
-               throw new ClassNotFoundException(name);
-       }
-
-       @Override
-       public URL findResource(String name) {
-               for (ClassLoader loader : loaders) {
-                       URL url = loader.getResource(name);
-                       if (url != null) {
-                               return url;
-                       }
-               }
-               
-               return null;
-       }
-
-       @Override
-       protected Enumeration<URL> findResources(String name) throws IOException {
-               List<URL> resources = new ArrayList<URL>();
-               for (ClassLoader loader : loaders) {
-                       resources.addAll(Collections.list(loader.getResources(name)));
-               }
-               
-               return Collections.enumeration(resources);
-       }
-       
-}
diff --git a/pf4j/src/main/java/org/pf4j/util/Unzip.java b/pf4j/src/main/java/org/pf4j/util/Unzip.java
deleted file mode 100644 (file)
index d5e6a04..0000000
+++ /dev/null
@@ -1,122 +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 org.pf4j.util;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipInputStream;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * This class extracts the containt of the plugin archive into a directory.
- * It's a class for only the internal use.
- *
- * @author Decebal Suiu
- */
-public class Unzip {
-
-       private static final Logger LOG = LoggerFactory.getLogger(Unzip.class);
-
-    /**
-     * Holds the destination directory.
-     * File will be unzipped into the destination directory.
-     */
-    private File destination;
-
-    /**
-     * Holds path to zip file.
-     */
-    private File source;
-
-    public Unzip() {
-    }
-
-    public Unzip(File source, File destination) {
-        this.source = source;
-        this.destination = destination;
-    }
-
-    public void setSource(File source) {
-        this.source = source;
-    }
-
-    public void setDestination(File destination) {
-        this.destination = destination;
-    }
-
-    public void extract() throws IOException {
-        LOG.debug("Extract content of " + source + " to " + destination);
-
-        // delete destination file if exists
-        removeDirectory(destination);
-
-       ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(source));
-           ZipEntry zipEntry = null;
-
-       while ((zipEntry = zipInputStream.getNextEntry()) != null) {
-               try {
-                       File file = new File(destination, zipEntry.getName());
-
-                       // create intermediary directories - sometimes zip don't add them
-                       File dir = new File(file.getParent());
-                       dir.mkdirs();
-
-                       if (zipEntry.isDirectory()) {
-                           file.mkdirs();
-                       } else {
-                           byte[] buffer = new byte[1024];
-                           int length = 0;
-                           FileOutputStream fos = new FileOutputStream(file);
-
-                           while ((length = zipInputStream.read(buffer)) >= 0) {
-                               fos.write(buffer, 0, length);
-                           }
-
-                           fos.close();
-                }
-           } catch (FileNotFoundException e) {
-               LOG.error("File '" + zipEntry.getName() + "' not found");
-           }
-           }
-
-       zipInputStream.close();
-    }
-
-    private boolean removeDirectory(File directory) {
-        if (!directory.exists()) {
-            return true;
-        }
-
-        if (!directory.isDirectory()) {
-            return false;
-        }
-
-        File[] files = directory.listFiles();
-        for (File file : files) {
-            if (file.isDirectory()) {
-                removeDirectory(file);
-            } else {
-                file.delete();
-            }
-        }
-
-        return directory.delete();
-    }
-
-}
diff --git a/pf4j/src/main/java/org/pf4j/util/ZipFilter.java b/pf4j/src/main/java/org/pf4j/util/ZipFilter.java
deleted file mode 100644 (file)
index 4884e90..0000000
+++ /dev/null
@@ -1,32 +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 org.pf4j.util;
-
-/**
- * File filter that accepts all files ending with .ZIP.
- * This filter is case insensitive.
- *
- * @author Decebal Suiu
- */
-public class ZipFilter extends ExtensionFilter {
-
-    /**
-     * The extension that this filter will search for.
-     */
-    private static final String ZIP_EXTENSION = ".ZIP";
-
-    public ZipFilter() {
-        super(ZIP_EXTENSION);
-    }
-
-}
diff --git a/pf4j/src/main/java/ro/fortsoft/pf4j/DefaultExtensionFinder.java b/pf4j/src/main/java/ro/fortsoft/pf4j/DefaultExtensionFinder.java
new file mode 100644 (file)
index 0000000..66c896c
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * 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 DefaultExtensionFinder implements ExtensionFinder {
+
+       private static final Logger LOG = LoggerFactory.getLogger(DefaultExtensionFinder.class);
+       
+       private volatile List<IndexItem<Extension, Object>> indices;
+       private ClassLoader classLoader;
+       
+       public DefaultExtensionFinder(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/java/ro/fortsoft/pf4j/DefaultPluginDescriptorFinder.java b/pf4j/src/main/java/ro/fortsoft/pf4j/DefaultPluginDescriptorFinder.java
new file mode 100644 (file)
index 0000000..fa86e2e
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * 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.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.jar.Attributes;
+import java.util.jar.Manifest;
+
+import org.apache.commons.lang.StringUtils;
+
+/**
+ * Read the plugin descriptor from the manifest file.
+ *
+ * @author Decebal Suiu
+ */
+public class DefaultPluginDescriptorFinder implements PluginDescriptorFinder {
+
+       @Override
+       public PluginDescriptor find(File pluginRepository) throws PluginException {
+       // TODO it's ok with classes/ ?
+        File manifestFile = new File(pluginRepository, "classes/META-INF/MANIFEST.MF");
+        if (!manifestFile.exists()) {
+            // not found a 'plugin.xml' file for this plugin
+            throw new PluginException("Cannot find '" + manifestFile + "' file");
+        }
+
+       FileInputStream input = null;
+               try {
+                       input = new FileInputStream(manifestFile);
+               } catch (FileNotFoundException e) {
+                       // not happening 
+               }
+               
+       Manifest manifest = null;
+        try {
+            manifest = new Manifest(input);
+        } catch (IOException e) {
+            throw new PluginException(e.getMessage(), e);
+        } finally {
+            try {
+                               input.close();
+                       } catch (IOException e) {
+                               throw new PluginException(e.getMessage(), e);
+                       }
+        } 
+        
+        PluginDescriptor pluginDescriptor = new PluginDescriptor();
+        
+        // TODO validate !!!
+        Attributes attrs = manifest.getMainAttributes();
+        String id = attrs.getValue("Plugin-Id");
+        if (StringUtils.isEmpty(id)) {
+               throw new PluginException("Plugin-Id cannot be empty");
+        }
+        pluginDescriptor.setPluginId(id);
+        
+        String clazz = attrs.getValue("Plugin-Class");
+        if (StringUtils.isEmpty(clazz)) {
+               throw new PluginException("Plugin-Class cannot be empty");
+        }
+        pluginDescriptor.setPluginClass(clazz);
+        
+        String version = attrs.getValue("Plugin-Version");
+        if (StringUtils.isEmpty(version)) {
+               throw new PluginException("Plugin-Version cannot be empty");
+        }
+        pluginDescriptor.setPluginVersion(PluginVersion.createVersion(version));
+        
+        String provider = attrs.getValue("Plugin-Provider");
+        pluginDescriptor.setProvider(provider);        
+        String dependencies = attrs.getValue("Plugin-Dependencies");
+        pluginDescriptor.setDependencies(dependencies);
+
+               return pluginDescriptor;
+       }
+    
+}
diff --git a/pf4j/src/main/java/ro/fortsoft/pf4j/DefaultPluginManager.java b/pf4j/src/main/java/ro/fortsoft/pf4j/DefaultPluginManager.java
new file mode 100644 (file)
index 0000000..ea56e67
--- /dev/null
@@ -0,0 +1,328 @@
+/*
+ * 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.io.File;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import ro.fortsoft.pf4j.util.DirectoryFilter;
+import ro.fortsoft.pf4j.util.UberClassLoader;
+import ro.fortsoft.pf4j.util.Unzip;
+import ro.fortsoft.pf4j.util.ZipFilter;
+
+
+/**
+ * Default implementation of the PluginManager interface.
+ *
+ * @author Decebal Suiu
+ */
+public class DefaultPluginManager implements PluginManager {
+
+       private static final Logger LOG = LoggerFactory.getLogger(DefaultPluginManager.class);
+
+    /**
+     * The plugins repository.
+     */
+    private File pluginsDirectory;
+
+    private ExtensionFinder extensionFinder;
+    
+    private PluginDescriptorFinder pluginDescriptorFinder;
+    
+    /**
+     * A map of plugins this manager is responsible for (the key is the 'pluginId').
+     */
+    private Map<String, Plugin> plugins;
+
+    /**
+     * A map of plugin class loaders (he key is the 'pluginId').
+     */
+    private Map<String, PluginClassLoader> pluginClassLoaders;
+
+    /**
+     * A relation between 'pluginPath' and 'pluginId'
+     */
+    private Map<String, String> pathToIdMap;
+
+    /**
+     * A list with unresolved plugins (unresolved dependency).
+     */
+    private List<Plugin> unresolvedPlugins;
+
+    /**
+     * A list with resolved plugins (resolved dependency).
+     */
+    private List<Plugin> resolvedPlugins;
+
+    /**
+     * A list with disabled plugins.
+     */
+    private List<Plugin> disabledPlugins;
+    
+    private UberClassLoader uberClassLoader;
+
+    /**
+     * Th plugins directory is supplied by System.getProperty("pf4j.pluginsDir", "plugins").
+     */
+    public DefaultPluginManager() {
+       this(new File(System.getProperty("pf4j.pluginsDir", "plugins")));
+    }
+    
+    /**
+     * Constructs DefaultPluginManager which the given plugins directory.
+     *
+     * @param pluginsDirectory
+     *            the directory to search for plugins
+     */
+    public DefaultPluginManager(File pluginsDirectory) {
+        this.pluginsDirectory = pluginsDirectory;
+        plugins = new HashMap<String, Plugin>();
+        pluginClassLoaders = new HashMap<String, PluginClassLoader>();
+        pathToIdMap = new HashMap<String, String>();
+        unresolvedPlugins = new ArrayList<Plugin>();
+        resolvedPlugins = new ArrayList<Plugin>();
+        disabledPlugins = new ArrayList<Plugin>();
+        pluginDescriptorFinder = new DefaultPluginDescriptorFinder();
+        uberClassLoader = new UberClassLoader();
+        extensionFinder = new DefaultExtensionFinder(uberClassLoader);
+    }
+
+    /**
+     * Retrieves all active plugins.
+     */
+    public List<Plugin> getPlugins() {
+        return new ArrayList<Plugin>(plugins.values());
+    }
+
+       public List<Plugin> getResolvedPlugins() {
+               return resolvedPlugins;
+       }
+
+       public Plugin getPlugin(String pluginId) {
+               return plugins.get(pluginId);
+       }
+
+    public List<Plugin> getUnresolvedPlugins() {
+               return unresolvedPlugins;
+       }
+
+       public List<Plugin> getDisabledPlugins() {
+               return disabledPlugins;
+       }
+
+    /**
+     * Start all active plugins.
+     */
+    public void startPlugins() {
+       List<Plugin> resolvedPlugins = getResolvedPlugins();
+        for (Plugin plugin : resolvedPlugins) {
+            try {
+                               plugin.start();
+                       } catch (PluginException e) {
+                               // TODO Auto-generated catch block
+                               e.printStackTrace();
+                       }
+        }
+    }
+
+    /**
+     * Stop all active plugins.
+     */
+    public void stopPlugins() {
+       List<Plugin> resolvedPlugins = getResolvedPlugins();
+        for (Plugin plugin : resolvedPlugins) {
+            try {
+                               plugin.stop();
+                       } catch (PluginException e) {
+                               // TODO Auto-generated catch block
+                               e.printStackTrace();
+                       }
+        }
+    }
+
+    /**
+     * Load plugins.
+     */
+    public void loadPlugins() {
+       // check for plugins directory
+        if (!pluginsDirectory.exists() || !pluginsDirectory.isDirectory()) {
+            LOG.error("No '" + pluginsDirectory + "' directory");
+            return;
+        }
+
+        // expand all plugin archives
+        FilenameFilter zipFilter = new ZipFilter();
+        String[] zipFiles = pluginsDirectory.list(zipFilter);
+        for (String zipFile : zipFiles) {
+               try {
+                               expandPluginArchive(zipFile);
+                       } catch (IOException e) {
+                               LOG.error(e.getMessage(), e);
+                               e.printStackTrace();
+                       }
+        }
+
+        // load any plugin from plugins directory
+        FilenameFilter directoryFilter = new DirectoryFilter();
+        String[] directories = pluginsDirectory.list(directoryFilter);
+        for (String directory : directories) {
+            try {
+                loadPlugin(directory);
+            } catch (Exception e) {
+                               LOG.error(e.getMessage(), e);
+                e.printStackTrace();
+            }
+        }
+
+        // check for no plugins
+        if (directories.length == 0) {
+               LOG.info("No plugins");
+               return;
+        }
+
+        // resolve 'unresolvedPlugins'
+        resolvePlugins();
+    }
+
+    /**
+     * Get plugin class loader for this path.
+     */
+    public PluginClassLoader getPluginClassLoader(String pluginId) {
+       return pluginClassLoaders.get(pluginId);
+    }
+
+       public <T> List<ExtensionWrapper<T>> getExtensions(Class<T> type) {
+               return extensionFinder.find(type);
+       }
+       
+       private void loadPlugin(String fileName) throws Exception {
+        // test for plugin directory
+        File pluginDirectory = new File(pluginsDirectory, fileName);
+        if (!pluginDirectory.isDirectory()) {
+            return;
+        }
+
+        // try to load the plugin
+        String pluginPath = "/".concat(fileName);
+
+        // test for disabled plugin
+        if (disabledPlugins.contains(pluginPath)) {
+            return;
+        }
+
+        // it's a new plugin
+        if (plugins.get(pathToIdMap.get(pluginPath)) != null) {
+            return;
+        }
+
+        // retrieves the plugin descriptor
+        LOG.debug("Find plugin descriptor '" + pluginPath + "'");
+        PluginDescriptor pluginDescriptor = pluginDescriptorFinder.find(pluginDirectory);
+        LOG.debug("Descriptor " + pluginDescriptor);
+        String pluginClassName = pluginDescriptor.getPluginClass();
+        LOG.debug("Class '" + pluginClassName + "'" + " for plugin '" + pluginPath + "'");
+
+        // load plugin
+        LOG.debug("Loading plugin '" + pluginPath + "'");
+        PluginWrapper pluginWrapper = new PluginWrapper(pluginDescriptor);
+        PluginLoader pluginLoader = new PluginLoader(this, pluginWrapper, pluginDirectory);
+        pluginLoader.load();
+        LOG.debug("Loaded plugin '" + pluginPath + "'");
+        
+        // set some variables in plugin wrapper
+        pluginWrapper.setPluginPath(pluginPath);
+        pluginWrapper.setPluginClassLoader(pluginLoader.getPluginClassLoader());
+
+        // create the plugin instance
+        LOG.debug("Creating instance for plugin '" + pluginPath + "'");
+        Plugin plugin = getPluginInstance(pluginWrapper, pluginLoader);
+        LOG.debug("Created instance '" + plugin + "' for plugin '" + pluginPath + "'");
+
+        String pluginId = pluginDescriptor.getPluginId();
+
+        // add plugin to the list with plugins
+        plugins.put(pluginId, plugin);
+        unresolvedPlugins.add(plugin);
+
+        // add plugin class loader to the list with class loaders
+        PluginClassLoader pluginClassLoader = pluginLoader.getPluginClassLoader();
+        pluginDescriptor.setPluginClassLoader(pluginClassLoader);
+        pluginClassLoaders.put(pluginId, pluginClassLoader);
+    }
+
+    private void expandPluginArchive(String fileName) throws IOException {
+        File pluginArchiveFile = new File(pluginsDirectory, fileName);
+        long pluginArchiveDate = pluginArchiveFile.lastModified();
+        String pluginName = fileName.substring(0, fileName.length() - 4);
+        File pluginDirectory = new File(pluginsDirectory, pluginName);
+        // check if exists directory or the '.zip' file is "newer" than directory
+        if (!pluginDirectory.exists() || pluginArchiveDate > pluginDirectory.lastModified()) {
+               LOG.debug("Expand plugin archive '" + pluginArchiveFile + "' in '" + pluginDirectory + "'");
+            // create directorie for plugin
+            pluginDirectory.mkdirs();
+
+            // expand '.zip' file
+            Unzip unzip = new Unzip();
+            unzip.setSource(pluginArchiveFile);
+            unzip.setDestination(pluginDirectory);
+            unzip.extract();
+        }
+    }
+
+    private Plugin getPluginInstance(PluginWrapper pluginWrapper, PluginLoader pluginLoader)
+               throws Exception {
+       String pluginClassName = pluginWrapper.getDescriptor().getPluginClass();
+
+        ClassLoader pluginClassLoader = pluginLoader.getPluginClassLoader();
+        Class<?> pluginClass = pluginClassLoader.loadClass(pluginClassName);
+
+        // once we have the class, we can do some checks on it to ensure
+        // that it is a valid implementation of a plugin.
+        int modifiers = pluginClass.getModifiers();
+        if (Modifier.isAbstract(modifiers) || Modifier.isInterface(modifiers)
+                || (!Plugin.class.isAssignableFrom(pluginClass))) {
+            throw new PluginException("The plugin class '" + pluginClassName
+                    + "' is not compatible.");
+        }
+
+        // create the plugin instance
+        Constructor<?> constructor = pluginClass.getConstructor(new Class[] { PluginWrapper.class });
+        Plugin plugin = (Plugin) constructor.newInstance(new Object[] { pluginWrapper });
+
+        return plugin;
+    }
+
+       private void resolvePlugins() {
+        resolveDependencies();
+       }
+
+       private void resolveDependencies() {
+               DependencyResolver dependencyResolver = new DependencyResolver(unresolvedPlugins);
+        resolvedPlugins = dependencyResolver.getSortedDependencies();
+        for (Plugin plugin : resolvedPlugins) {
+               unresolvedPlugins.remove(plugin);
+               uberClassLoader.addLoader(plugin.getWrapper().getPluginClassLoader());
+        }
+       }
+
+}
diff --git a/pf4j/src/main/java/ro/fortsoft/pf4j/DependencyResolver.java b/pf4j/src/main/java/ro/fortsoft/pf4j/DependencyResolver.java
new file mode 100644 (file)
index 0000000..7485b22
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * 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.util.ArrayList;
+import java.util.List;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import ro.fortsoft.pf4j.util.DirectedGraph;
+
+
+/**
+ * @author Decebal Suiu
+ */
+class DependencyResolver {
+
+       private static final Logger LOG = LoggerFactory.getLogger(DependencyResolver.class);
+       
+    private List<Plugin> plugins;
+
+       public DependencyResolver(List<Plugin> plugins) {
+               this.plugins = plugins;
+       }
+
+       /**
+        * Get the list of plugins in dependency sorted order.
+        */
+       public List<Plugin> getSortedDependencies() {
+               DirectedGraph<String> graph = new DirectedGraph<String>();
+               for (Plugin plugin : plugins) {
+                       PluginDescriptor descriptor = plugin.getWrapper().getDescriptor();
+                       String pluginId = descriptor.getPluginId();
+                       List<String> dependencies = descriptor.getDependencies();
+                       if (!dependencies.isEmpty()) {
+                               for (String dependency : dependencies) {
+                                       graph.addEdge(pluginId, dependency);
+                               }
+                       } else {
+                               graph.addVertex(pluginId);
+                       }
+               }
+
+               LOG.debug("Graph: " + graph);
+               List<String> pluginsId = graph.reverseTopologicalSort();
+
+               if (pluginsId == null) {
+                       LOG.error("Cyclic dependences !!!");
+                       return null;
+               }
+
+               LOG.debug("Plugins order: " + pluginsId);
+               List<Plugin> sortedPlugins = new ArrayList<Plugin>();
+               for (String pluginId : pluginsId) {
+                       sortedPlugins.add(getPlugin(pluginId));
+               }
+
+               return sortedPlugins;
+       }
+
+       private Plugin getPlugin(String pluginId) {
+               for (Plugin plugin : plugins) {
+                       if (pluginId.equals(plugin.getWrapper().getDescriptor().getPluginId())) {
+                               return plugin;
+                       }
+               }
+
+               return null;
+       }
+
+}
diff --git a/pf4j/src/main/java/ro/fortsoft/pf4j/Extension.java b/pf4j/src/main/java/ro/fortsoft/pf4j/Extension.java
new file mode 100644 (file)
index 0000000..f1b7cac
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * 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 static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+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
+public @interface Extension {
+
+        int ordinal() default 0;
+        
+}
diff --git a/pf4j/src/main/java/ro/fortsoft/pf4j/ExtensionFinder.java b/pf4j/src/main/java/ro/fortsoft/pf4j/ExtensionFinder.java
new file mode 100644 (file)
index 0000000..2eeca18
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * 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.util.List;
+
+/**
+ * @author Decebal Suiu
+ */
+public interface ExtensionFinder {
+
+       public <T> List<ExtensionWrapper<T>> find(Class<T> type);
+       
+}
diff --git a/pf4j/src/main/java/ro/fortsoft/pf4j/ExtensionPoint.java b/pf4j/src/main/java/ro/fortsoft/pf4j/ExtensionPoint.java
new file mode 100644 (file)
index 0000000..8d94847
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * 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;
+
+/**
+ * @author Decebal Suiu
+ */
+public interface ExtensionPoint {
+
+}
diff --git a/pf4j/src/main/java/ro/fortsoft/pf4j/ExtensionWrapper.java b/pf4j/src/main/java/ro/fortsoft/pf4j/ExtensionWrapper.java
new file mode 100644 (file)
index 0000000..2f147c0
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * 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;
+
+/**
+ * @author Decebal Suiu
+ */
+public class ExtensionWrapper<T> implements Comparable<ExtensionWrapper<T>> {
+
+       private final T instance;
+       private final int ordinal;
+       
+       public ExtensionWrapper(T instance, int ordinal) {
+               this.instance = instance;
+               this.ordinal = ordinal;
+       }
+
+       public T getInstance() {
+               return instance;
+       }
+
+       public int getOrdinal() {
+               return ordinal;
+       }
+
+       @Override
+       public int compareTo(ExtensionWrapper<T> o) {
+               return (ordinal - o.getOrdinal());
+       }
+
+}
\ No newline at end of file
diff --git a/pf4j/src/main/java/ro/fortsoft/pf4j/Plugin.java b/pf4j/src/main/java/ro/fortsoft/pf4j/Plugin.java
new file mode 100644 (file)
index 0000000..22498d7
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * 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 org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This class will be extended by all plugins and
+ * serve as the common class between a plugin and the application.
+ *
+ * @author Decebal Suiu
+ */
+public abstract class Plugin {
+
+    /**
+     * Makes logging service available for descending classes.
+     */
+    protected final Logger log = LoggerFactory.getLogger(getClass());
+
+    /**
+     * Wrapper of the plugin.
+     */
+    PluginWrapper wrapper;
+
+    /**
+     * Constructor to be used by plugin manager for plugin instantiation.
+     * Your plugins have to provide constructor with this exact signature to
+     * be successfully loaded by manager.
+     */
+    public Plugin(final PluginWrapper wrapper) {
+        if (wrapper == null) {
+            throw new IllegalArgumentException("Wrapper cannot be null");
+        }
+
+        this.wrapper = wrapper;
+    }
+
+    /**
+     * Retrieves the wrapper of this plug-in.
+     */
+    public final PluginWrapper getWrapper() {
+        return wrapper;
+    }
+
+    /**
+     * Start method is called by the application when the plugin is loaded.
+     */
+    public void start() throws PluginException {
+    }
+
+    /**
+     * Stop method is called by the application when the plugin is unloaded.
+     */
+    public void stop() throws PluginException {
+    }
+
+}
diff --git a/pf4j/src/main/java/ro/fortsoft/pf4j/PluginClassLoader.java b/pf4j/src/main/java/ro/fortsoft/pf4j/PluginClassLoader.java
new file mode 100644 (file)
index 0000000..1d80c92
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * 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.net.URL;
+import java.net.URLClassLoader;
+import java.util.List;
+
+/**
+ * One instance of this class should be created by plugin manager for every available plug-in.
+ * 
+ * @author Decebal Suiu
+ */
+class PluginClassLoader extends URLClassLoader {
+
+       private static final String JAVA_PACKAGE_PREFIX = "java.";
+       private static final String JAVAX_PACKAGE_PREFIX = "javax.";
+       private static final String PLUGIN_PACKAGE_PREFIX = "ro.fortsoft.pf4j.";
+
+       private PluginManager pluginManager;
+       private PluginWrapper pluginWrapper;
+
+       public PluginClassLoader(PluginManager pluginManager, PluginWrapper pluginWrapper, ClassLoader parent) {
+               super(new URL[0], parent);
+               
+               this.pluginManager = pluginManager;
+               this.pluginWrapper = pluginWrapper;
+       }
+
+       @Override
+       public void addURL(URL url) {
+               super.addURL(url);
+       }
+
+       @Override
+    public Class<?> loadClass(String className) throws ClassNotFoundException {
+//             System.out.println(">>>" + className);
+
+               // first check whether it's a system class, delegate to the system loader
+               if (className.startsWith(JAVA_PACKAGE_PREFIX) || className.startsWith(JAVAX_PACKAGE_PREFIX)) {
+                       return findSystemClass(className);
+               }
+
+        // second check whether it's already been loaded
+        Class<?> loadedClass = findLoadedClass(className);
+        if (loadedClass != null) {
+               return loadedClass;
+        }
+
+        // nope, try to load locally
+        try {
+               return findClass(className);
+        } catch (ClassNotFoundException e) {
+               // try next step
+        }
+
+        // if the class it's a part of the plugin engine use parent class loader
+        if (className.startsWith(PLUGIN_PACKAGE_PREFIX)) {
+               try {
+                       return PluginClassLoader.class.getClassLoader().loadClass(className);
+               } catch (ClassNotFoundException e) {
+                       // try next step
+               }
+        }
+
+        // look in dependencies
+        List<String> dependencies = pluginWrapper.getDescriptor().getDependencies();
+        for (String dependency : dependencies) {
+               PluginClassLoader classLoader = pluginManager.getPluginClassLoader(dependency);
+               try {
+                       return classLoader.loadClass(className);
+               } catch (ClassNotFoundException e) {
+                       // try next dependency
+               }
+        }
+
+        // use the standard URLClassLoader (which follows normal parent delegation)
+        return super.loadClass(className);
+    }
+
+}
diff --git a/pf4j/src/main/java/ro/fortsoft/pf4j/PluginDescriptor.java b/pf4j/src/main/java/ro/fortsoft/pf4j/PluginDescriptor.java
new file mode 100644 (file)
index 0000000..494877e
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+ * 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.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.apache.commons.lang.builder.ToStringStyle;
+
+/**
+ * A plugin descriptor contains information about a plug-in obtained
+ * from the manifest (META-INF) file.
+ *
+ * @author Decebal Suiu
+ */
+class PluginDescriptor {
+
+       private String pluginId;
+    private String pluginClass;
+    private PluginVersion version;
+    private String provider;
+    private String pluginPath;
+    private List<String> dependencies;
+    private PluginClassLoader pluginClassLoader;
+
+    public PluginDescriptor() {
+        dependencies = new ArrayList<String>();
+    }
+
+    /**
+     * Returns the unique identifier of this plugin.
+     */
+    public String getPluginId() {
+        return pluginId;
+    }
+
+    /**
+     * Returns the name of the class that implements Plugin interface.
+     */
+    public String getPluginClass() {
+        return pluginClass;
+    }
+
+    /**
+     * Returns the version of this plugin.
+     */
+    public PluginVersion getVersion() {
+        return version;
+    }
+
+    /**
+     * Returns the provider name of this plugin.
+     */
+    public String getProvider() {
+        return provider;
+    }
+
+    /**
+     * Returns the path of this plugin relative to plugins directory.
+     */
+    public String getPluginPath() {
+        return pluginPath;
+    }
+
+    /**
+     * Returns all dependencies declared by this plugin.
+     * Returns an empty array if this plugin does not declare any require.
+     */
+    public List<String> getDependencies() {
+        return dependencies;
+    }
+
+    /**
+     * 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.
+        */
+    public PluginClassLoader getPluginClassLoader() {
+       return pluginClassLoader;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
+            .append("pluginId", pluginId)
+            .append("pluginClass", pluginClass)
+            .append("version", version)
+            .append("provider", provider)
+            .append("pluginPath", pluginPath)
+            .append("dependencies", dependencies)
+            .toString();
+    }
+
+    void setPluginId(String pluginId) {
+        this.pluginId = pluginId;
+    }
+
+    void setPluginClass(String pluginClassName) {
+        this.pluginClass = pluginClassName;
+    }
+
+    void setPluginVersion(PluginVersion version) {
+        this.version = version;
+    }
+
+    void setProvider(String provider) {
+        this.provider = provider;
+    }
+
+    void setPluginPath(String pluginPath) {
+        this.pluginPath = pluginPath;
+    }
+    
+    void setDependencies(String dependencies) {
+       if (dependencies != null) {
+               this.dependencies = Arrays.asList(StringUtils.split(dependencies, ','));
+       } else {
+               this.dependencies = Collections.emptyList();
+       }
+    }
+
+       void setPluginClassLoader(PluginClassLoader pluginClassLoader) {
+               this.pluginClassLoader = pluginClassLoader;
+       }
+
+}
diff --git a/pf4j/src/main/java/ro/fortsoft/pf4j/PluginDescriptorFinder.java b/pf4j/src/main/java/ro/fortsoft/pf4j/PluginDescriptorFinder.java
new file mode 100644 (file)
index 0000000..44b0846
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * 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.io.File;
+
+/**
+ * Find a plugin descriptor in a directory (plugin repository).
+ * You can find in manifest file @see DefaultPluginDescriptorFinder,
+ * xml file, properties file, java services (with ServiceLoader), etc.
+ * 
+ * @author Decebal Suiu
+ */
+public interface PluginDescriptorFinder {
+
+       public PluginDescriptor find(File pluginRepository) throws PluginException;
+       
+}
diff --git a/pf4j/src/main/java/ro/fortsoft/pf4j/PluginException.java b/pf4j/src/main/java/ro/fortsoft/pf4j/PluginException.java
new file mode 100644 (file)
index 0000000..600e28f
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * 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;
+
+/**
+ * An exception used to indicate that a plugin problem occurred.
+ *
+ * @author Decebal Suiu
+ */
+class PluginException extends Exception {
+
+       private static final long serialVersionUID = 1L;
+
+       public PluginException() {
+        super();
+    }
+
+    public PluginException(String message) {
+        super(message);
+    }
+
+    public PluginException(Throwable cause) {
+        super(cause);
+    }
+
+    public PluginException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+}
diff --git a/pf4j/src/main/java/ro/fortsoft/pf4j/PluginLoader.java b/pf4j/src/main/java/ro/fortsoft/pf4j/PluginLoader.java
new file mode 100644 (file)
index 0000000..8ae65e7
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * 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.io.File;
+import java.io.FilenameFilter;
+import java.net.MalformedURLException;
+import java.util.Vector;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import ro.fortsoft.pf4j.util.DirectoryFilter;
+import ro.fortsoft.pf4j.util.JarFilter;
+
+
+/**
+ * Load all informations needed by a plugin.
+ * This means add all jar files from 'lib' directory, 'classes'
+ * to classpath.
+ * It's a class for only the internal use.
+ *
+ * @author Decebal Suiu
+ */
+class PluginLoader {
+
+       private static final Logger LOG = LoggerFactory.getLogger(PluginLoader.class);
+
+    /*
+     * The plugin repository.
+     */
+    private File pluginRepository;
+
+    /*
+     * The directory with '.class' files.
+     */
+    private File classesDirectory;
+
+    /*
+     * The directory with '.jar' files.
+     */
+    private File libDirectory;
+
+    private PluginClassLoader pluginClassLoader;
+
+    public PluginLoader(PluginManager pluginManager, PluginWrapper pluginWrapper, File pluginRepository) {
+        this.pluginRepository = pluginRepository;
+        classesDirectory = new File(pluginRepository, "classes");
+        libDirectory = new File(pluginRepository, "lib");
+        ClassLoader parent = getClass().getClassLoader(); 
+        pluginClassLoader = new PluginClassLoader(pluginManager, pluginWrapper, parent);        
+        LOG.debug("Created class loader " + pluginClassLoader);
+    }
+
+    public File getPluginRepository() {
+        return pluginRepository;
+    }
+
+    public boolean load() {
+        return loadClassesAndJars();
+    }
+
+    public PluginClassLoader getPluginClassLoader() {
+               return pluginClassLoader;
+       }
+
+       private boolean loadClassesAndJars() {
+       return loadClasses() && loadJars();
+    }
+
+    private void getJars(Vector<String> v, File file) {
+        FilenameFilter jarFilter = new JarFilter();
+        FilenameFilter directoryFilter = new DirectoryFilter();
+
+        if (file.exists() && file.isDirectory() && file.isAbsolute()) {
+            String[] jars = file.list(jarFilter);
+            for (int i = 0; (jars != null) && (i < jars.length); ++i) {
+                v.addElement(jars[i]);
+            }
+
+            String[] directoryList = file.list(directoryFilter);
+            for (int i = 0; (directoryList != null) && (i < directoryList.length); ++i) {
+                File directory = new File(file, directoryList[i]);
+                getJars(v, directory);
+            }
+        }
+    }
+
+    private boolean loadClasses() {
+        // make 'classesDirectory' absolute
+        classesDirectory = classesDirectory.getAbsoluteFile();
+
+        if (classesDirectory.exists() && classesDirectory.isDirectory()) {
+            LOG.debug("Found '" + classesDirectory.getPath() + "' directory");
+
+            try {
+                pluginClassLoader.addURL(classesDirectory.toURI().toURL());
+                LOG.debug("Added '" + classesDirectory + "' to the class loader path");
+            } catch (MalformedURLException e) {
+                e.printStackTrace();
+                LOG.error(e.getMessage(), e);
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Add all *.jar files from '/lib' directory.
+     */
+    private boolean loadJars() {
+        // make 'jarDirectory' absolute
+        libDirectory = libDirectory.getAbsoluteFile();
+
+        Vector<String> jars = new Vector<String>();
+        getJars(jars, libDirectory);
+        for (String jar : jars) {
+            File jarFile = new File(libDirectory, jar);
+            try {
+                pluginClassLoader.addURL(jarFile.toURI().toURL());
+                LOG.debug("Added '" + jarFile + "' to the class loader path");
+            } catch (MalformedURLException e) {
+                e.printStackTrace();
+                LOG.error(e.getMessage(), e);
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+}
diff --git a/pf4j/src/main/java/ro/fortsoft/pf4j/PluginManager.java b/pf4j/src/main/java/ro/fortsoft/pf4j/PluginManager.java
new file mode 100644 (file)
index 0000000..e191e22
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * 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.util.List;
+
+/**
+ * Provides the functionality for plugin management such as load,
+ * start and stop the plugins.
+ *
+ * @author Decebal Suiu
+ */
+public interface PluginManager {
+
+    /**
+     * Retrieves all plugins.
+     */
+    public List<Plugin> getPlugins();
+
+    /**
+     * Load plugins.
+     */
+    public void loadPlugins();
+
+    /**
+     * Start all active plugins.
+     */
+    public void startPlugins();
+
+    /**
+     * Stop all active plugins.
+     */
+    public void stopPlugins();
+
+       public PluginClassLoader getPluginClassLoader(String pluginId);
+
+       public <T> List<ExtensionWrapper<T>> getExtensions(Class<T> type);
+       
+}
diff --git a/pf4j/src/main/java/ro/fortsoft/pf4j/PluginVersion.java b/pf4j/src/main/java/ro/fortsoft/pf4j/PluginVersion.java
new file mode 100644 (file)
index 0000000..9fcab40
--- /dev/null
@@ -0,0 +1,191 @@
+/*
+ * 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.util.ArrayList;
+import java.util.List;
+import java.util.StringTokenizer;
+
+/**
+ * Represents the version of a Plugin and allows versions to be compared.
+ * Version identifiers have five components.
+ *
+ *  1. Major version. A non-negative integer.
+ *  2. Minor version. A non-negative integer.
+ *  3. Release version. A non-negative integer.
+ *  4. Build version. A non-negative integer.
+ *  5. Qualifier. A text string.
+ *
+ * This class is immutable.
+ *
+ * @author Decebal Suiu
+ */
+public class PluginVersion implements Comparable<PluginVersion> {
+
+       private int major;
+       private int minor;
+       private int release;
+       private int build;
+       private String qualifier;
+
+    private PluginVersion() {
+    }
+
+       public PluginVersion(int major, int minor, int release) {
+               this.major = major;
+               this.minor = minor;
+               this.release = release;
+       }
+
+       public PluginVersion(int major, int minor, int release, int build) {
+               this.major = major;
+               this.minor = minor;
+               this.release = release;
+               this.build = build;
+       }
+
+       public PluginVersion(int major, int minor, int release, int build, String qualifier) {
+               this.major = major;
+               this.minor = minor;
+               this.release = release;
+               this.build = build;
+               this.qualifier = qualifier;
+       }
+
+       public static PluginVersion createVersion(String version) {
+        if (version == null) {
+            return new PluginVersion();
+        }
+
+               PluginVersion v = new PluginVersion();
+
+               StringTokenizer st = new StringTokenizer(version, ".");
+               List<String> tmp = new ArrayList<String>();
+               for (int i = 0; st.hasMoreTokens() && i < 4; i++) {
+                       tmp.add(st.nextToken());
+               }
+
+               int n = tmp.size();
+               switch (n) {
+                       case 0 :
+                               break;
+                       case 1 :
+                               v.major = Integer.parseInt(tmp.get(0));
+                               break;
+                       case 2 :
+                               v.major = Integer.parseInt(tmp.get(0));
+                               v.minor = Integer.parseInt(tmp.get(1));
+                               break;
+                       case 3 :
+                               v.major = Integer.parseInt(tmp.get(0));
+                               v.minor = Integer.parseInt(tmp.get(1));
+                               v.release = Integer.parseInt(tmp.get(2));
+                               break;
+                       case 4 :
+                               v.major = Integer.parseInt(tmp.get(0));
+                               v.minor = Integer.parseInt(tmp.get(1));
+                               v.release = Integer.parseInt(tmp.get(2));
+                               v.build = Integer.parseInt(tmp.get(3));
+                               break;
+               }
+
+               return v;
+       }
+
+       public int getMajor() {
+               return this.major;
+       }
+
+       public int getMinor() {
+               return this.minor;
+       }
+
+       public int getRelease() {
+               return this.release;
+       }
+
+    public int getBuild() {
+        return this.build;
+    }
+
+    public String getQualifier() {
+               return qualifier;
+       }
+
+       public String toString() {
+        StringBuffer sb = new StringBuffer(50);
+        sb.append(major);
+        sb.append('.');
+        sb.append(minor);
+        sb.append('.');
+        sb.append(release);
+        sb.append('.');
+        sb.append(build);
+        if (qualifier != null) {
+               sb.append(qualifier);
+        }
+
+        return sb.toString();
+    }
+
+    public int compareTo(PluginVersion version) {
+        if (version.major > major) {
+            return 1;
+        } else if (version.major < major) {
+            return -1;
+        }
+
+        if (version.minor > minor) {
+            return 1;
+        } else if (version.minor < minor) {
+            return -1;
+        }
+
+        if (version.release > release) {
+            return 1;
+        } else if (version.release < release) {
+            return -1;
+        }
+
+        if (version.build > build) {
+            return 1;
+        } else if (version.build < build) {
+            return -1;
+        }
+
+        return 0;
+    }
+
+    /*
+    private String extractQualifier(String token) {
+       StringTokenizer st = new StringTokenizer(token, "-");
+       if (st.countTokens() == 2) {
+               return st.
+       }
+    }
+    */
+
+    // for test only
+    public static void main(String[] args) {
+        PluginVersion v = PluginVersion.createVersion("4.0.0.123");
+        System.out.println(v.toString());
+//        v = PluginVersion.createVersion("4.0.0.123-alpha");
+//        System.out.println(v.toString());
+        PluginVersion v1 = PluginVersion.createVersion("4.1.0");
+        System.out.println(v1.toString());
+        PluginVersion v2  = PluginVersion.createVersion("4.0.32");
+        System.out.println(v2.toString());
+        System.out.println(v1.compareTo(v2));
+    }
+
+}
diff --git a/pf4j/src/main/java/ro/fortsoft/pf4j/PluginWrapper.java b/pf4j/src/main/java/ro/fortsoft/pf4j/PluginWrapper.java
new file mode 100644 (file)
index 0000000..6d935e0
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * 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;
+
+/**
+ * A wrapper over plugin instance.
+ *
+ * @author Decebal Suiu
+ */
+public class PluginWrapper {
+
+       PluginDescriptor descriptor;
+       String pluginPath;
+       PluginClassLoader pluginClassLoader;
+       
+       public PluginWrapper(PluginDescriptor descriptor) {
+               this.descriptor = descriptor;
+       }
+       
+    /**
+     * Returns the plugin descriptor.
+     */
+    public PluginDescriptor getDescriptor() {
+       return descriptor;
+    }
+
+    /**
+     * Returns the path of this plugin relative to plugins directory.
+     */
+    public String 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.
+        */
+    public PluginClassLoader getPluginClassLoader() {
+       return pluginClassLoader;
+    }
+
+       void setPluginPath(String pluginPath) {
+               this.pluginPath = pluginPath;
+       }
+
+       void setPluginClassLoader(PluginClassLoader pluginClassLoader) {
+               this.pluginClassLoader = pluginClassLoader;
+       }
+
+}
diff --git a/pf4j/src/main/java/ro/fortsoft/pf4j/util/DirectedGraph.java b/pf4j/src/main/java/ro/fortsoft/pf4j/util/DirectedGraph.java
new file mode 100644 (file)
index 0000000..5c1f446
--- /dev/null
@@ -0,0 +1,171 @@
+/*\r
+ * Copyright 2012 Decebal Suiu\r
+ * \r
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this work except in compliance with\r
+ * the License. You may obtain a copy of the License in the LICENSE file, or at:\r
+ * \r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ * \r
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on\r
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the\r
+ * specific language governing permissions and limitations under the License.\r
+ */\r
+package ro.fortsoft.pf4j.util;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collections;\r
+import java.util.HashMap;\r
+import java.util.List;\r
+import java.util.Map;\r
+import java.util.Stack;\r
+\r
+/**\r
+ * @author Decebal Suiu\r
+ */\r
+public class DirectedGraph<V> {\r
+\r
+    /**\r
+     * The implementation here is basically an adjacency list, but instead\r
+     * of an array of lists, a Map is used to map each vertex to its list of\r
+     * adjacent vertices.\r
+     */\r
+    private Map<V, List<V>> neighbors = new HashMap<V, List<V>>();\r
+\r
+    /**\r
+     * Add a vertex to the graph. Nothing happens if vertex is already in graph.\r
+     */\r
+    public void addVertex(V vertex) {\r
+        if (neighbors.containsKey(vertex)) {\r
+               return;\r
+        }\r
+        neighbors.put(vertex, new ArrayList<V>());\r
+    }\r
+\r
+    /**\r
+     * True if graph contains vertex.\r
+     */\r
+    public boolean containsVertex(V vertex) {\r
+        return neighbors.containsKey(vertex);\r
+    }\r
+\r
+    /**\r
+     * Add an edge to the graph; if either vertex does not exist, it's added.\r
+     * This implementation allows the creation of multi-edges and self-loops.\r
+     */\r
+    public void addEdge(V from, V to) {\r
+        this.addVertex(from);\r
+        this.addVertex(to);\r
+        neighbors.get(from).add(to);\r
+    }\r
+\r
+    /**\r
+     * Remove an edge from the graph. Nothing happens if no such edge.\r
+     * @throws IllegalArgumentException if either vertex doesn't exist.\r
+     */\r
+    public void remove(V from, V to) {\r
+        if (!(this.containsVertex(from) && this.containsVertex(to))) {\r
+            throw new IllegalArgumentException("Nonexistent vertex");\r
+        }\r
+        neighbors.get(from).remove(to);\r
+    }\r
+\r
+    /**\r
+     * Report (as a Map) the out-degree of each vertex.\r
+     */\r
+    public Map<V, Integer> outDegree() {\r
+        Map<V, Integer> result = new HashMap<V, Integer>();\r
+        for (V vertex : neighbors.keySet()) {\r
+               result.put(vertex, neighbors.get(vertex).size());\r
+        }\r
+\r
+        return result;\r
+    }\r
+\r
+    /**\r
+     * Report (as a Map) the in-degree of each vertex.\r
+     */\r
+    public Map<V,Integer> inDegree() {\r
+        Map<V, Integer> result = new HashMap<V, Integer>();\r
+        for (V vertex : neighbors.keySet()) {\r
+               result.put(vertex, 0); // all in-degrees are 0\r
+        }\r
+        for (V from : neighbors.keySet()) {\r
+            for (V to : neighbors.get(from)) {\r
+                result.put(to, result.get(to) + 1); // increment in-degree\r
+            }\r
+        }\r
+\r
+        return result;\r
+    }\r
+\r
+    /**\r
+     * Report (as a List) the topological sort of the vertices; null for no such sort.\r
+     */\r
+    public List<V> topologicalSort() {\r
+        Map<V, Integer> degree = inDegree();\r
+\r
+        // determine all vertices with zero in-degree\r
+        Stack<V> zeroVertices = new Stack<V>(); // stack as good as any here\r
+        for (V v : degree.keySet()) {\r
+            if (degree.get(v) == 0) {\r
+               zeroVertices.push(v);\r
+            }\r
+        }\r
+\r
+        // determine the topological order\r
+        List<V> result = new ArrayList<V>();\r
+        while (!zeroVertices.isEmpty()) {\r
+            V vertex = zeroVertices.pop(); // choose a vertex with zero in-degree\r
+            result.add(vertex); // vertex 'v' is next in topological order\r
+            // "remove" vertex 'v' by updating its neighbors\r
+            for (V neighbor : neighbors.get(vertex)) {\r
+                degree.put(neighbor, degree.get(neighbor) - 1);\r
+                // remember any vertices that now have zero in-degree\r
+                if (degree.get(neighbor) == 0) {\r
+                       zeroVertices.push(neighbor);\r
+                }\r
+            }\r
+        }\r
+\r
+        // check that we have used the entire graph (if not, there was a cycle)\r
+        if (result.size() != neighbors.size()) {\r
+               return null;\r
+        }\r
+\r
+        return result;\r
+    }\r
+\r
+    /**\r
+     * Report (as a List) the reverse topological sort of the vertices; null for no such sort.\r
+     */\r
+    public List<V> reverseTopologicalSort() {\r
+       List<V> list = topologicalSort();\r
+       if (list == null) {\r
+               return null;\r
+       }\r
+       Collections.reverse(list);\r
+\r
+       return list;\r
+    }\r
+\r
+    /**\r
+     * True if graph is a dag (directed acyclic graph).\r
+     */\r
+    public boolean isDag () {\r
+        return topologicalSort() != null;\r
+    }\r
+\r
+    /**\r
+     * String representation of graph.\r
+     */\r
+    @Override\r
+    public String toString() {\r
+        StringBuffer sb = new StringBuffer();\r
+        for (V vertex : neighbors.keySet()) {\r
+               sb.append("\n   " + vertex + " -> " + neighbors.get(vertex));\r
+        }\r
+\r
+        return sb.toString();\r
+    }\r
+\r
+}\r
diff --git a/pf4j/src/main/java/ro/fortsoft/pf4j/util/DirectoryFilter.java b/pf4j/src/main/java/ro/fortsoft/pf4j/util/DirectoryFilter.java
new file mode 100644 (file)
index 0000000..54e1a95
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * 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.util;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.io.FilenameFilter;
+
+/**
+ * @author Decebal Suiu
+ */
+public class DirectoryFilter implements FileFilter, FilenameFilter {
+
+    /**
+     * Accepts any file ending in .jar. The case of the filename is ignored.
+     */
+    public boolean accept(File file) {
+        return file.isDirectory();
+    }
+
+    public boolean accept(File dir, String name) {
+        return accept(new File(dir, name));
+    }
+
+}
diff --git a/pf4j/src/main/java/ro/fortsoft/pf4j/util/ExtensionFilter.java b/pf4j/src/main/java/ro/fortsoft/pf4j/util/ExtensionFilter.java
new file mode 100644 (file)
index 0000000..22b999f
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * 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.util;
+
+import java.io.File;
+import java.io.FilenameFilter;
+
+/**
+ * @author Decebal Suiu
+ */
+public class ExtensionFilter implements FilenameFilter {
+
+    private String extension;
+
+    public ExtensionFilter(String extension) {
+        this.extension = extension;
+    }
+
+    /**
+     * Accepts any file ending in extension. The case of the filename is ignored.
+     */
+    public boolean accept(File file) {
+        // perform a case insensitive check.
+        return file.getName().toUpperCase().endsWith(extension.toUpperCase());
+    }
+
+    public boolean accept(File dir, String name) {
+        return accept(new File(dir, name));
+    }
+
+}
diff --git a/pf4j/src/main/java/ro/fortsoft/pf4j/util/JarFilter.java b/pf4j/src/main/java/ro/fortsoft/pf4j/util/JarFilter.java
new file mode 100644 (file)
index 0000000..60c8859
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * 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.util;
+
+/**
+ * File filter that accepts all files ending with .JAR.
+ * This filter is case insensitive.
+ *
+ * @author Decebal Suiu
+ */
+public class JarFilter extends ExtensionFilter {
+
+    /**
+     * The extension that this filter will search for.
+     */
+    private static final String JAR_EXTENSION = ".JAR";
+
+    public JarFilter() {
+        super(JAR_EXTENSION);
+    }
+
+}
diff --git a/pf4j/src/main/java/ro/fortsoft/pf4j/util/UberClassLoader.java b/pf4j/src/main/java/ro/fortsoft/pf4j/util/UberClassLoader.java
new file mode 100644 (file)
index 0000000..013c2a1
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * 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.util;
+
+import java.io.IOException;
+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;
+
+/**
+ * A class loader that has multiple loaders and uses them for loading classes and resources.
+ * 
+ * @author Decebal Suiu
+ */
+public class UberClassLoader extends ClassLoader {
+
+       private Set<ClassLoader> loaders = new HashSet<ClassLoader>();
+
+       public void addLoader(ClassLoader loader) {
+               loaders.add(loader);
+       }
+
+       @Override
+       public Class<?> findClass(String name) throws ClassNotFoundException {
+               for (ClassLoader loader : loaders) {
+                       try {
+                               return loader.loadClass(name);
+                       } catch (ClassNotFoundException e) {
+                               // try next
+                       }
+               }
+               
+               throw new ClassNotFoundException(name);
+       }
+
+       @Override
+       public URL findResource(String name) {
+               for (ClassLoader loader : loaders) {
+                       URL url = loader.getResource(name);
+                       if (url != null) {
+                               return url;
+                       }
+               }
+               
+               return null;
+       }
+
+       @Override
+       protected Enumeration<URL> findResources(String name) throws IOException {
+               List<URL> resources = new ArrayList<URL>();
+               for (ClassLoader loader : loaders) {
+                       resources.addAll(Collections.list(loader.getResources(name)));
+               }
+               
+               return Collections.enumeration(resources);
+       }
+       
+}
diff --git a/pf4j/src/main/java/ro/fortsoft/pf4j/util/Unzip.java b/pf4j/src/main/java/ro/fortsoft/pf4j/util/Unzip.java
new file mode 100644 (file)
index 0000000..4a2c9a3
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * 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.util;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This class extracts the containt of the plugin archive into a directory.
+ * It's a class for only the internal use.
+ *
+ * @author Decebal Suiu
+ */
+public class Unzip {
+
+       private static final Logger LOG = LoggerFactory.getLogger(Unzip.class);
+
+    /**
+     * Holds the destination directory.
+     * File will be unzipped into the destination directory.
+     */
+    private File destination;
+
+    /**
+     * Holds path to zip file.
+     */
+    private File source;
+
+    public Unzip() {
+    }
+
+    public Unzip(File source, File destination) {
+        this.source = source;
+        this.destination = destination;
+    }
+
+    public void setSource(File source) {
+        this.source = source;
+    }
+
+    public void setDestination(File destination) {
+        this.destination = destination;
+    }
+
+    public void extract() throws IOException {
+        LOG.debug("Extract content of " + source + " to " + destination);
+
+        // delete destination file if exists
+        removeDirectory(destination);
+
+       ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(source));
+           ZipEntry zipEntry = null;
+
+       while ((zipEntry = zipInputStream.getNextEntry()) != null) {
+               try {
+                       File file = new File(destination, zipEntry.getName());
+
+                       // create intermediary directories - sometimes zip don't add them
+                       File dir = new File(file.getParent());
+                       dir.mkdirs();
+
+                       if (zipEntry.isDirectory()) {
+                           file.mkdirs();
+                       } else {
+                           byte[] buffer = new byte[1024];
+                           int length = 0;
+                           FileOutputStream fos = new FileOutputStream(file);
+
+                           while ((length = zipInputStream.read(buffer)) >= 0) {
+                               fos.write(buffer, 0, length);
+                           }
+
+                           fos.close();
+                }
+           } catch (FileNotFoundException e) {
+               LOG.error("File '" + zipEntry.getName() + "' not found");
+           }
+           }
+
+       zipInputStream.close();
+    }
+
+    private boolean removeDirectory(File directory) {
+        if (!directory.exists()) {
+            return true;
+        }
+
+        if (!directory.isDirectory()) {
+            return false;
+        }
+
+        File[] files = directory.listFiles();
+        for (File file : files) {
+            if (file.isDirectory()) {
+                removeDirectory(file);
+            } else {
+                file.delete();
+            }
+        }
+
+        return directory.delete();
+    }
+
+}
diff --git a/pf4j/src/main/java/ro/fortsoft/pf4j/util/ZipFilter.java b/pf4j/src/main/java/ro/fortsoft/pf4j/util/ZipFilter.java
new file mode 100644 (file)
index 0000000..4b10de3
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * 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.util;
+
+/**
+ * File filter that accepts all files ending with .ZIP.
+ * This filter is case insensitive.
+ *
+ * @author Decebal Suiu
+ */
+public class ZipFilter extends ExtensionFilter {
+
+    /**
+     * The extension that this filter will search for.
+     */
+    private static final String ZIP_EXTENSION = ".ZIP";
+
+    public ZipFilter() {
+        super(ZIP_EXTENSION);
+    }
+
+}
diff --git a/pom.xml b/pom.xml
index a8d45f9438f8c44b1d266e241fe120322ecead7e..aa9c67d7010fd9fd73c660a126a8469d9708f7a4 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -2,7 +2,7 @@
 <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">
     
     <modelVersion>4.0.0</modelVersion>
-    <groupId>org.pf4j</groupId>
+    <groupId>ro.fortsoft.pf4j</groupId>
     <artifactId>pom</artifactId>
     <version>0.1-SNAPSHOT</version>
     <packaging>pom</packaging>