Commit fee25623 authored by Guus der Kinderen's avatar Guus der Kinderen

OF-1353: Adding maxServerVersion (and more)

This commit started with the intention of adding a maxServerVersion attribute for plugins, but resulted in a partial rewrite. Changes:
- Removed the License enumeration - now, a simple string is used.
- Split off the admin console page that shows the content of readme and changelog files to a dedicated page, instead of plugin-admin.jsp
- Better define the difference between the plugin (human readable) name ("Avatar Resizer") and its canonical name ("avatarresizer")
- The admin console now shows plugins that have been downloaded/installed, but cannot be loaded. Where possible, an update is suggested.
- Support for maxServerVersion - plugins can now define a version of Openfire in which they will no longer load.
parent f7010088
......@@ -2644,6 +2644,8 @@ plugin.admin.version.available = Version {0} Available
plugin.admin.changelog = Change Log
plugin.admin.update = Update
plugin.admin.updating = Updating
plugin.admin.failed.minserverversion=The version of the plugin that is installed requires Openfire {0} or later versions!
plugin.admin.failed.maxserverversion=The version of the plugin that is installed only works with Openfire {0} or earlier versions!
# System Email
......@@ -2918,6 +2920,8 @@ plugin.available.installation.success = plugin installed successfully.
plugin.available.commercial_plugins = Commercial Plugins
plugin.available.outdated = The list of plugins below requires a newer version of the server.
plugin.available.outdated.update = Update the server now.
plugin.available.deprecated=These plugins that are installed are compatible with older versions of the server only.
plugin.available.autoupdate = Available plugins list auto-updated on
plugin.available.autoupdate.on = Auto update is turned on.
plugin.available.autoupdate.off = Auto update is off.
......
/*
* Copyright 2016 IgniteRealtime.org
*
* 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.openfire.container;
/**
* An enumeration for license agreement types.
*/
public enum License
{
/**
* Distributed using a commercial license.
*/
commercial,
/**
* Distributed using the GNU Public License (GPL).
*/
gpl,
/**
* Distributed using the Apache license.
*/
apache,
/**
* For internal use at an organization only and is not re-distributed.
*/
internal,
/**
* Distributed under another license agreement not covered by one of the other choices. The license agreement
* should be detailed in a Readme or License file that accompanies the code.
*/
other
}
/*
* 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.openfire.container;
import org.jivesoftware.util.Version;
import java.net.URL;
import java.nio.file.Path;
/**
* A bean-like representation of the metadata of a plugin.
*
* @author Guus der Kinderen, guus.der.kinderen@gmail.com
*/
public class PluginMetadata
{
/**
* Human readable name of the plugin.
*/
private final String name;
/**
* Canonical name of the plugin.
*/
private final String canonicalName;
/**
* Description of the plugin as specified in plugin.xml.
*/
private final String description;
/**
* The version of the plugin.
*/
private final Version version;
/**
* Author of the plugin as specified in plugin.xml.
*/
private final String author;
/**
* Icon's location of the plugin.
*/
private final URL icon;
/**
* Changelog location of the latest version of the plugin.
*/
private final URL changelog;
/**
* ReadMe location of the latest version of the plugin.
*/
private final URL readme;
/**
* Type of license of the plugin.
*/
private final String license;
/**
* Minimum server version required by this plugin as specified in plugin.xml.
*/
private final Version minServerVersion;
/**
* Maximum server version required by this plugin as specified in plugin.xml.
*/
private final Version maxServerVersion;
/**
* Constructs a metadata object based on a plugin.
*
* The plugin must be installed in Openfire.
*
* @param pluginDir the path of the plugin directory (cannot be null)
* @return Metadata for the plugin (never null).
*/
public static PluginMetadata getInstance( Path pluginDir )
{
return new PluginMetadata(
PluginMetadataHelper.getName( pluginDir ),
PluginMetadataHelper.getCanonicalName( pluginDir ),
PluginMetadataHelper.getDescription( pluginDir ),
PluginMetadataHelper.getVersion( pluginDir ),
PluginMetadataHelper.getAuthor( pluginDir ),
PluginMetadataHelper.getIcon( pluginDir ),
PluginMetadataHelper.getChangelog( pluginDir ),
PluginMetadataHelper.getReadme( pluginDir ),
PluginMetadataHelper.getLicense( pluginDir ),
PluginMetadataHelper.getMinServerVersion( pluginDir ),
PluginMetadataHelper.getMaxServerVersion( pluginDir )
);
}
/**
* Constructs a metadata object based on a plugin.
*
* The plugin must be installed in Openfire.
*
* @param plugin The plugin (cannot be null)
* @return Metadata for the plugin (never null).
*/
public static PluginMetadata getInstance( Plugin plugin )
{
return new PluginMetadata(
PluginMetadataHelper.getName( plugin ),
PluginMetadataHelper.getCanonicalName( plugin ),
PluginMetadataHelper.getDescription( plugin ),
PluginMetadataHelper.getVersion( plugin ),
PluginMetadataHelper.getAuthor( plugin ),
PluginMetadataHelper.getIcon( plugin ),
PluginMetadataHelper.getChangelog( plugin ),
PluginMetadataHelper.getReadme( plugin ),
PluginMetadataHelper.getLicense( plugin ),
PluginMetadataHelper.getMinServerVersion( plugin ),
PluginMetadataHelper.getMaxServerVersion( plugin )
);
}
public PluginMetadata( String name, String canonicalName, String description, Version version, String author,
URL icon, URL changelog, URL readme, String license,
Version minServerVersion, Version maxServerVersion )
{
this.name = name;
this.canonicalName = canonicalName;
this.description = description;
this.version = version;
this.author = author;
this.icon = icon;
this.changelog = changelog;
this.readme = readme;
this.license = license;
this.minServerVersion = minServerVersion;
this.maxServerVersion = maxServerVersion;
}
public String getName()
{
return name;
}
public String getCanonicalName()
{
return canonicalName;
}
public String getDescription()
{
return description;
}
public Version getVersion()
{
return version;
}
public String getAuthor()
{
return author;
}
public URL getIcon()
{
return icon;
}
public URL getChangelog()
{
return changelog;
}
public URL getReadme()
{
return readme;
}
public String getLicense()
{
return license;
}
public Version getMinServerVersion()
{
return minServerVersion;
}
public Version getMaxServerVersion()
{
return maxServerVersion;
}
public String getHashCode() {
return String.valueOf( hashCode() );
}
}
......@@ -151,12 +151,12 @@ public class PluginMonitor
for ( final Path jarFile : ds )
{
final String fileName = jarFile.getFileName().toString();
final String pluginName = fileName.substring( 0, fileName.length() - 4 ).toLowerCase(); // strip extension.
final String canonicalPluginName = fileName.substring( 0, fileName.length() - 4 ).toLowerCase(); // strip extension.
jarSet.add( pluginName );
jarSet.add( canonicalPluginName );
// See if the JAR has already been exploded.
final Path dir = pluginsDirectory.resolve( pluginName );
final Path dir = pluginsDirectory.resolve( canonicalPluginName );
// See if the JAR is newer than the directory. If so, the plugin needs to be unloaded and then reloaded.
if ( Files.exists( dir ) && Files.getLastModifiedTime( jarFile ).toMillis() > Files.getLastModifiedTime( dir ).toMillis() )
......@@ -174,14 +174,14 @@ public class PluginMonitor
else
{
// Not the first time? Properly unload the plugin.
pluginManager.unloadPlugin( pluginName );
pluginManager.unloadPlugin( canonicalPluginName );
}
}
// If the JAR needs to be exploded, do so.
if ( Files.notExists( dir ) )
{
unzipPlugin( pluginName, jarFile, dir );
unzipPlugin( canonicalPluginName, jarFile, dir );
}
}
}
......@@ -270,10 +270,10 @@ public class PluginMonitor
for ( final Path path : hierarchy )
{
// If the plugin hasn't already been started, start it.
final String pluginName = PluginMetadataHelper.getCanonicalName( path );
if ( pluginManager.getPlugin( pluginName ) == null )
final String canonicalName = PluginMetadataHelper.getCanonicalName( path );
if ( pluginManager.getPlugin( canonicalName ) == null )
{
if ( pluginManager.loadPlugin( path ) )
if ( pluginManager.loadPlugin( canonicalName, path ) )
{
loaded++;
}
......@@ -289,7 +289,7 @@ public class PluginMonitor
// of all plugins that attempt to modify the admin panel.
if ( pluginManager.getPlugin( "admin" ) == null )
{
pluginManager.loadPlugin( dirs.getFirst().get( 0 ) );
pluginManager.loadPlugin( "admin", dirs.getFirst().get( 0 ) );
}
// Hierarchies could be processed in parallel. This is likely to be beneficial during the first
......
This diff is collapsed.
This diff is collapsed.
<%@ page import="org.jivesoftware.util.ParamUtils" %>
<%@ page import="org.jivesoftware.openfire.container.Plugin" %>
<%@ page import="org.jivesoftware.openfire.container.PluginManager" %>
<%@ page import="org.jivesoftware.openfire.container.PluginMetadataHelper" %>
<%@ page import="java.nio.file.Path" %>
<%@ page import="java.io.*" %><%--
- 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.
--%>
<jsp:useBean id="webManager" class="org.jivesoftware.util.WebManager" />
<%
webManager.init(request, response, session, application, out );
final boolean showReadme = ParamUtils.getBooleanParameter( request, "showReadme", false);
final boolean showChangelog = ParamUtils.getBooleanParameter(request, "showChangelog", false);
if (showReadme || showChangelog )
{
final PluginManager pluginManager = webManager.getXMPPServer().getPluginManager();
final String pluginName = ParamUtils.getParameter(request, "plugin" );
final Plugin plugin = pluginManager.getPlugin( pluginName );
if ( plugin != null )
{
final Path filePath;
final Path pluginPath = pluginManager.getPluginPath( plugin );
if ( showChangelog )
{
filePath = pluginPath.resolve( "changelog.html" );
}
else
{
filePath = pluginPath.resolve( "readme.html" );
}
if ( filePath.toFile().exists() )
{
try ( final BufferedReader in = new BufferedReader( new InputStreamReader( new FileInputStream( filePath.toFile() ), "UTF8") ) )
{
String line;
while ((line = in.readLine()) != null)
{
response.getWriter().println( line );
}
}
catch ( IOException ioe )
{
ioe.printStackTrace();
}
}
}
}
%>
\ No newline at end of file
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