Commit 4cdab6a2 authored by Guus der Kinderen's avatar Guus der Kinderen Committed by daryl herzmann

OF-1425: Allow a min Java version to be defined for a plugin. (#915)

parent b669b608
......@@ -23,6 +23,7 @@ import org.dom4j.io.SAXReader;
import org.jivesoftware.admin.AdminConsole;
import org.jivesoftware.database.DbConnectionManager;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.util.JavaSpecVersion;
import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.util.LocaleUtils;
import org.jivesoftware.util.Version;
......@@ -453,6 +454,18 @@ public class PluginManager
}
}
// See if the plugin specifies a minimum version of Java required to run.
if ( metadata.getMinJavaVersion() != null )
{
final JavaSpecVersion runtimeVersion = new JavaSpecVersion( System.getProperty( "java.specification.version" ) );
if ( metadata.getMinJavaVersion().isNewerThan( runtimeVersion ) )
{
Log.warn( "Ignoring plugin '{}': requires Java specification version {}. Openfire is currently running in Java {}.", canonicalName, metadata.getMinJavaVersion(), System.getProperty( "java.specification.version" ) );
failureToLoadCount.put( canonicalName, Integer.MAX_VALUE ); // Don't retry - this cannot be recovered from.
return false;
}
}
// Properties to be used to load external resources. When set, plugin is considered to run in DEV mode.
final String devModeClassesDir = System.getProperty( canonicalName + ".classes" );
final String devModewebRoot = System.getProperty( canonicalName + ".webRoot" );
......@@ -1218,4 +1231,4 @@ public class PluginManager
{
return pluginMonitor.isTaskRunning();
}
}
\ No newline at end of file
}
......@@ -16,6 +16,7 @@
package org.jivesoftware.openfire.container;
import org.jivesoftware.util.JavaSpecVersion;
import org.jivesoftware.util.Version;
import java.net.URL;
......@@ -83,6 +84,11 @@ public class PluginMetadata
*/
private final Version priorToServerVersion;
/**
* Minimum Java (specification) version (inclusive( required by this plugin as specified in plugin.xml.
*/
private final JavaSpecVersion minJavaVersion;
/**
* Constructs a metadata object based on a plugin.
*
......@@ -104,8 +110,9 @@ public class PluginMetadata
PluginMetadataHelper.getReadme( pluginDir ),
PluginMetadataHelper.getLicense( pluginDir ),
PluginMetadataHelper.getMinServerVersion( pluginDir ),
PluginMetadataHelper.getPriorToServerVersion( pluginDir )
);
PluginMetadataHelper.getPriorToServerVersion( pluginDir ),
PluginMetadataHelper.getMinJavaVersion( pluginDir )
);
}
/**
......@@ -129,13 +136,15 @@ public class PluginMetadata
PluginMetadataHelper.getReadme( plugin ),
PluginMetadataHelper.getLicense( plugin ),
PluginMetadataHelper.getMinServerVersion( plugin ),
PluginMetadataHelper.getPriorToServerVersion( plugin )
PluginMetadataHelper.getPriorToServerVersion( plugin ),
PluginMetadataHelper.getMinJavaVersion( plugin )
);
}
public PluginMetadata( String name, String canonicalName, String description, Version version, String author,
URL icon, URL changelog, URL readme, String license,
Version minServerVersion, Version priorToServerVersion )
Version minServerVersion, Version priorToServerVersion, JavaSpecVersion minJavaVersion )
{
this.name = name;
this.canonicalName = canonicalName;
......@@ -148,6 +157,7 @@ public class PluginMetadata
this.license = license;
this.minServerVersion = minServerVersion;
this.priorToServerVersion = priorToServerVersion;
this.minJavaVersion = minJavaVersion;
}
public String getName()
......@@ -205,6 +215,11 @@ public class PluginMetadata
return priorToServerVersion;
}
public JavaSpecVersion getMinJavaVersion()
{
return minJavaVersion;
}
public String getHashCode() {
return String.valueOf( hashCode() );
}
......
......@@ -21,6 +21,7 @@ import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.jivesoftware.admin.AdminConsole;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.util.JavaSpecVersion;
import org.jivesoftware.util.Version;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -315,6 +316,41 @@ public class PluginMetadataHelper
return new Version( value );
}
/**
* Returns the minimum Java specification version this plugin needs to run. The value is retrieved from the
* plugin.xml file of the plugin. If the value could not be found, <tt>null</tt> will be returned.
*
* Note that this method will return data only for plugins that have successfully been installed. To obtain data
* from plugin (directories) that have not (yet) been installed, refer to the overloaded method that takes a Path
* argument.
*
* @param plugin The plugin (cannot be null)
* @return the plugin's minimum Java version (possibly null).
*/
public static JavaSpecVersion getMinJavaVersion( Plugin plugin )
{
return getMinJavaVersion( XMPPServer.getInstance().getPluginManager().getPluginPath( plugin ) );
}
/**
* Returns the minimum Java specification version this plugin needs to run. The value is retrieved from the
* plugin.xml file of the plugin. If the value could not be found, <tt>null</tt> will be returned.
*
* @param pluginDir the path of the plugin directory.
* @return the plugin's minimum Java version (possibly null).
*/
public static JavaSpecVersion getMinJavaVersion( Path pluginDir )
{
final String value = getElementValue( pluginDir, "/plugin/minJavaVersion" );
if ( value == null || value.trim().isEmpty() )
{
return null;
}
return new JavaSpecVersion( value );
}
/**
* Returns the database schema key of a plugin, if it exists. The value is retrieved from the plugin.xml file of the
* plugin. If the value could not be found, <tt>null</tt> will be returned.
......
......@@ -18,6 +18,7 @@ package org.jivesoftware.openfire.update;
import org.dom4j.Element;
import org.jivesoftware.openfire.container.PluginMetadata;
import org.jivesoftware.util.JavaSpecVersion;
import org.jivesoftware.util.Version;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -127,6 +128,13 @@ public class AvailablePlugin extends PluginMetadata
priorToServerVersion = new Version( priorToServerVersionValue );
}
JavaSpecVersion minJavaVersion = null;
String minJavaVersionValue = plugin.attributeValue( "minJavaVersion" );
if ( minJavaVersionValue != null && !minJavaVersionValue.isEmpty() )
{
minJavaVersion = new JavaSpecVersion( minJavaVersionValue );
}
long fileSize = -1;
String fileSizeValue = plugin.attributeValue("fileSize");
if ( fileSizeValue != null && !fileSizeValue.isEmpty() )
......@@ -148,6 +156,7 @@ public class AvailablePlugin extends PluginMetadata
license,
minServerVersion,
priorToServerVersion,
minJavaVersion,
downloadUrl,
fileSize
);
......@@ -155,7 +164,8 @@ public class AvailablePlugin extends PluginMetadata
}
public AvailablePlugin( String name, String canonicalName, String description, Version latestVersion, String author,
URL icon, URL changelog, URL readme, String license,
Version minServerVersion, Version priorToServerVersion, URL downloadUrl, long fileSize ) {
Version minServerVersion, Version priorToServerVersion, JavaSpecVersion minJavaVersion,
URL downloadUrl, long fileSize ) {
super(
name,
canonicalName,
......@@ -167,7 +177,8 @@ public class AvailablePlugin extends PluginMetadata
readme,
license,
minServerVersion,
priorToServerVersion
priorToServerVersion,
minJavaVersion
);
this.downloadURL = downloadUrl;
this.fileSize = fileSize;
......
/*
* Copyright (C) 2017 Ignite Realtime Foundation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License 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.jivesoftware.util;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Holds version information for Java specification (a major and minor version, eg: 1.8).
*
* @author Guus der Kinderen, guus.der.kinderen@gmail.com
*/
public final class JavaSpecVersion implements Comparable<JavaSpecVersion> {
private static final Pattern PATTERN = Pattern.compile("(\\d+)\\.(\\d+)");
/**
* The major number (ie 1.x).
*/
private final int major;
/**
* The minor version number (ie x.8).
*/
private final int minor;
/**
* Create a new version information object.
*
* @param major the major release number.
* @param minor the minor release number.
*/
public JavaSpecVersion( int major, int minor ) {
this.major = major;
this.minor = minor;
}
/**
* Create a new version from a simple version string (e.g. "1.8")
*
* @param source the version string
*/
public JavaSpecVersion( CharSequence source ) {
if (source != null) {
Matcher matcher = PATTERN.matcher(source);
if (matcher.matches()) {
major = Integer.parseInt(matcher.group(1));
minor = Integer.parseInt(matcher.group(2));
} else {
this.major = this.minor = 0;
}
} else {
this.major = this.minor = 0;
}
}
/**
* Returns the version number of this instance of Openfire as a
* String (ie major.minor.revision).
*
* @return The version as a string
*/
public String getVersionString() {
return major + "." + minor;
}
/**
* Obtain the major release number for this product.
*
* @return The major release number 1.x.x
*/
public int getMajor() {
return major;
}
/**
* Obtain the minor release number for this product.
*
* @return The minor release number x.1.x
*/
public int getMinor() {
return minor;
}
/**
* Convenience method for comparing versions
*
* @param otherVersion a verion to comapr against
*/
public boolean isNewerThan(JavaSpecVersion otherVersion) {
return this.compareTo(otherVersion) > 0;
}
@Override
public int compareTo(JavaSpecVersion that) {
if (that == null) {
return 1;
}
int result = Integer.compare(getMajor(), that.getMajor());
if (result == 0) {
result = Integer.compare(getMinor(), that.getMinor());
}
return result;
}
@Override
public boolean equals(Object o) {
if (o == this) {
return true;
}
if (!(o instanceof JavaSpecVersion )) {
return false;
}
JavaSpecVersion other = (JavaSpecVersion) o;
return Objects.equals(major, other.major)
&& Objects.equals(minor, other.minor);
}
@Override
public int hashCode() {
return Objects.hash(major, minor);
}
@Override
public String toString() {
return getVersionString();
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment