]> source.dussan.org Git - pf4j.git/commitdiff
Add an optional requires manifest value
authorJames Moger <james.moger@gitblit.com>
Sat, 12 Apr 2014 16:10:56 +0000 (12:10 -0400)
committerJames Moger <james.moger@gitblit.com>
Sat, 12 Apr 2014 23:35:45 +0000 (19:35 -0400)
As integrators of pf4j evovle their extension APIs it will become
a requirement to specify a minimum system version for loading plugins.
Loading & starting a newer plugin on an older system could result in
runtime failures due to method signature changes or other class
differences.

This change adds a manifest attribute to specify a 'requires' version
which is a minmum system version.  It also introduces a method to
specify the system version of the plugin manager and logic to disable
plugins on load if the system version is too old.  This works for both
loadPlugins() and loadPlugin().

pf4j/src/main/java/ro/fortsoft/pf4j/DefaultPluginManager.java
pf4j/src/main/java/ro/fortsoft/pf4j/ManifestPluginDescriptorFinder.java
pf4j/src/main/java/ro/fortsoft/pf4j/PluginDescriptor.java
pf4j/src/main/java/ro/fortsoft/pf4j/PluginManager.java
pf4j/src/main/java/ro/fortsoft/pf4j/PluginVersion.java

index c44787ec0c360eea15f39820f0f11f7f53920986..970ae2d71b42d2b371cd2356bb69e4197d7a55c9 100644 (file)
@@ -89,6 +89,11 @@ public class DefaultPluginManager implements PluginManager {
      */
     private RuntimeMode runtimeMode;
 
+    /**
+     * The system version used for comparisons to the plugin requires attribute.
+     */
+    private PluginVersion systemVersion = PluginVersion.DEFAULT;
+
     /**
      * The plugins directory is supplied by System.getProperty("pf4j.pluginsDir", "plugins").
      */
@@ -110,6 +115,16 @@ public class DefaultPluginManager implements PluginManager {
         initialize();
     }
 
+    @Override
+    public void setSystemVersion(PluginVersion version) {
+       systemVersion = version;
+    }
+
+    @Override
+    public PluginVersion getSystemVersion() {
+       return systemVersion;
+    }
+
        @Override
     public List<PluginWrapper> getPlugins() {
         return new ArrayList<PluginWrapper>(plugins.values());
@@ -461,6 +476,16 @@ public class DefaultPluginManager implements PluginManager {
             return true;
         }
 
+        PluginVersion requires = pluginWrapper.getDescriptor().getRequires();
+               PluginVersion system = getSystemVersion();
+               if (!system.isDefault() && !system.atLeast(requires)) {
+                       log.warn(String.format("Failed to enable plugin `{}:{}` because it requires a minimum system version of %s",
+                                       pluginWrapper.getPluginId(),
+                                       pluginWrapper.getDescriptor().getVersion(),
+                                       requires));
+            return false;
+        }
+
         try {
             if (disabledPlugins.remove(pluginId)) {
                 FileUtils.writeLines(disabledPlugins, new File(pluginsDirectory, "disabled.txt"));
@@ -724,6 +749,18 @@ public class DefaultPluginManager implements PluginManager {
             pluginWrapper.setPluginState(PluginState.DISABLED);
         }
 
+        // optionally enforce minimum system version requirements
+        PluginVersion requires = pluginWrapper.getDescriptor().getRequires();
+               PluginVersion system = getSystemVersion();
+               if (!system.isDefault() && !system.atLeast(requires)) {
+                       log.warn(String.format("Disabling plugin '%s:%s' because it requires a minimum system version of %s",
+                                       pluginWrapper.getPluginId(),
+                                       pluginWrapper.getDescriptor().getVersion(),
+                                       requires));
+            pluginWrapper.setPluginState(PluginState.DISABLED);
+            disabledPlugins.add(pluginWrapper.getPluginId());
+        }
+
         log.debug("Created wrapper '{}' for plugin '{}'", pluginWrapper, pluginPath);
 
         String pluginId = pluginDescriptor.getPluginId();
index 2de42f51bbd498b977d15cdf117ea53c9eebe403..7f802d10e939c5b1920ba3e9728c73025d5d118b 100644 (file)
@@ -103,6 +103,11 @@ public class ManifestPluginDescriptorFinder implements PluginDescriptorFinder {
         String dependencies = attrs.getValue("Plugin-Dependencies");
         pluginDescriptor.setDependencies(dependencies);
 
+        String requires = attrs.getValue("Plugin-Requires");
+        if (StringUtils.isNotEmpty(requires)) {
+               pluginDescriptor.setRequires(PluginVersion.createVersion(requires));
+        }
+
                return pluginDescriptor;
        }
 
index cb91f7d67c6d07e9acc4b78e4b4aafa764843500..aa05b523fec8c74dffbbde3df840320125860a25 100644 (file)
@@ -28,10 +28,12 @@ public class PluginDescriptor {
        private String pluginDescription;
     private String pluginClass;
     private PluginVersion version;
+    private PluginVersion requires;
     private String provider;
     private List<PluginDependency> dependencies;
 
     public PluginDescriptor() {
+       requires = PluginVersion.DEFAULT;
         dependencies = new ArrayList<PluginDependency>();
     }
 
@@ -63,6 +65,13 @@ public class PluginDescriptor {
         return version;
     }
 
+    /**
+     * Returns the requires of this plugin.
+     */
+    public PluginVersion getRequires() {
+        return requires;
+    }
+
     /**
      * Returns the provider name of this plugin.
      */
@@ -106,6 +115,10 @@ public class PluginDescriptor {
         this.provider = provider;
     }
 
+    void setRequires(PluginVersion requires) {
+        this.requires = requires;
+    }
+
     void setDependencies(String dependencies) {
        if (dependencies != null) {
                dependencies = dependencies.trim();
index daf6fbf40f5375903f9c9e06ef2082f3353d0193..81abe7c8475f3ae052cdbaa60071070f06890ee7 100644 (file)
@@ -141,4 +141,20 @@ public interface PluginManager {
 
     public void removePluginStateListener(PluginStateListener listener);
 
+    /**
+     * Set the system version.  This is used to compare against the plugin
+     * requires attribute.  The default system version is 0.0.0 which
+     * disables all version checking.
+     *
+     * @default 0.0.0
+     * @param version
+     */
+    public void setSystemVersion(PluginVersion version);
+
+    /**
+     * Returns the system version.
+     *
+     * * @return the system version
+     */
+    public PluginVersion getSystemVersion();
 }
index 6ffd2847690f76fa986ec337b786cab217dba5b3..7cfc94b766b0715fe2376124cb4452ea9e580793 100644 (file)
@@ -1,22 +1,22 @@
 /*
  * 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 ro.fortsoft.pf4j.util.StringUtils;
-
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
+import ro.fortsoft.pf4j.util.StringUtils;
+
 /**
  * Represents the version of a Plugin and allows versions to be compared.
  * Version following semantic defined by <a href="http://semver.org/">Semantic Versioning</a> document.
@@ -33,6 +33,8 @@ import java.util.regex.Pattern;
  */
 public class PluginVersion implements Comparable<PluginVersion> {
 
+       public static final PluginVersion DEFAULT = new PluginVersion(0, 0, 0);
+
     private static final String FORMAT = "(\\d+)\\.(\\d+)(?:\\.)?(\\d*)(\\.|-|\\+)?([0-9A-Za-z-.]*)?";
     private static final Pattern PATTERN = Pattern.compile(FORMAT);
 
@@ -95,6 +97,7 @@ public class PluginVersion implements Comparable<PluginVersion> {
                return qualifier;
        }
 
+       @Override
        public String toString() {
         StringBuffer sb = new StringBuffer(50);
         sb.append(major);
@@ -135,6 +138,14 @@ public class PluginVersion implements Comparable<PluginVersion> {
         return 0;
     }
 
+    public boolean isDefault() {
+       return compareTo(DEFAULT) == 0;
+    }
+
+    public boolean atLeast(PluginVersion v) {
+       return compareTo(v) <= 0;
+    }
+
     // for test only
     public static void main(String[] args) {
         PluginVersion v = PluginVersion.createVersion("1.2.3-SNAPSHOT");