/*
* Copyright 2010-2015 Institut Pasteur.
*
* This file is part of Icy.
*
* Icy is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Icy is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Icy. If not, see <http://www.gnu.org/licenses/>.
*/
package icy.plugin;
import icy.gui.frame.progress.AnnounceFrame;
import icy.gui.frame.progress.CancelableProgressFrame;
import icy.gui.frame.progress.ProgressFrame;
import icy.gui.plugin.PluginUpdateFrame;
import icy.main.Icy;
import icy.network.NetworkUtil;
import icy.system.thread.ThreadUtil;
import icy.util.Random;
import java.util.ArrayList;
import java.util.List;
/**
* Plugin updater class.
*
* @author Stephane.D
*/
public class PluginUpdater
{
private static final int ANNOUNCE_SHOWTIME = 15;
// internal
private static boolean silent;
private static boolean checking = false;
private static Runnable checker = new Runnable()
{
@Override
public void run()
{
processCheckUpdate();
}
};
/**
* return true if we are currently checking for update
*/
public static boolean isCheckingForUpdate()
{
return checking || ThreadUtil.hasWaitingBgSingleTask(checker);
}
/**
* Do the check update process
*/
public static void checkUpdate(boolean silent)
{
if (!isCheckingForUpdate())
{
PluginUpdater.silent = silent;
ThreadUtil.bgRunSingle(checker);
}
}
/**
* @deprecated Use {@link #checkUpdate(boolean)} instead
*/
@Deprecated
public static void checkUpdate(boolean showProgress, boolean auto)
{
checkUpdate(!showProgress || auto);
}
/**
* Get update for the specified plugin.
*
* @param plugin
* local plugin we are looking update for
* @return
* plugin descriptor of update if any (null if no update)
*/
public static PluginDescriptor getUpdate(PluginDescriptor plugin)
{
// don't check update for kernel plugin
if (plugin.isKernelPlugin()) return null;
// find equivalent online plugins
final List<PluginDescriptor> onlinePlugins = PluginRepositoryLoader.getPlugins(plugin.getClassName());
final PluginDescriptor onlinePlugin;
// get the last version found
if (onlinePlugins.size() > 0)
{
PluginDescriptor lastVersion = null;
for (PluginDescriptor currentVersion : onlinePlugins)
if ((lastVersion == null) || currentVersion.isNewer(lastVersion))
lastVersion = currentVersion;
onlinePlugin = lastVersion;
}
else
// not found in repositories
onlinePlugin = null;
// we have an update available ?
if ((onlinePlugin != null) && onlinePlugin.getVersion().isGreater(plugin.getVersion()))
return onlinePlugin;
// random forced update
//if (Random.nextBoolean())
// return onlinePlugin;
return null;
}
/**
* Update the specified list of plugins.
*/
public static void updatePlugins(List<PluginDescriptor> plugins, boolean showProgress)
{
try
{
// update plugins with ordered dependencies
for (PluginDescriptor plugin : PluginInstaller.orderDependencies(plugins))
PluginInstaller.install(plugin, showProgress);
}
finally
{
PluginLoader.reloadAsynch();
}
}
/**
* Check for plugins update process (synchronized method)
*/
public static synchronized void processCheckUpdate()
{
checking = true;
try
{
final List<PluginDescriptor> toInstallPlugins = new ArrayList<PluginDescriptor>();
final List<PluginDescriptor> localPlugins = PluginLoader.getPlugins(false);
final ProgressFrame checkingFrame;
if (!silent && !Icy.getMainInterface().isHeadLess())
checkingFrame = new CancelableProgressFrame("checking for plugins update...");
else
checkingFrame = null;
try
{
// reload online plugins from all active repositories
PluginRepositoryLoader.reload();
// wait for basic infos
PluginRepositoryLoader.waitLoaded();
if (PluginRepositoryLoader.failed())
{
if (!silent && !Icy.getMainInterface().isHeadLess())
{
if (!NetworkUtil.hasInternetAccess())
new AnnounceFrame("You are not connected to internet.", 10);
else
new AnnounceFrame("Can't access the repositories... You should verify your connection.", 10);
}
return;
}
for (PluginDescriptor localPlugin : localPlugins)
{
// find update
final PluginDescriptor onlinePlugin = getUpdate(localPlugin);
// update found, add to the list
if (onlinePlugin != null)
{
// we load complete descriptor so we will have the changeslog
onlinePlugin.loadDescriptor();
toInstallPlugins.add(onlinePlugin);
}
}
final List<PluginDescriptor> onlinePlugins = PluginRepositoryLoader.getPlugins();
for (PluginDescriptor onlinePlugin : onlinePlugins)
{
// we found a plugin which is installed but not correctly loaded
// so we try to reinstall it
if (onlinePlugin.isInstalled() && !PluginLoader.isLoaded(onlinePlugin.getClassName()))
{
// we load complete descriptor so we will have the changeslog
onlinePlugin.loadDescriptor();
toInstallPlugins.add(onlinePlugin);
}
}
}
finally
{
if (checkingFrame != null)
checkingFrame.close();
}
// some updates availables ?
if (!toInstallPlugins.isEmpty())
{
// silent update or headless mode
if (silent || Icy.getMainInterface().isHeadLess())
{
// automatically install all updates (orderer depending dependencies)
updatePlugins(toInstallPlugins, true);
}
else
{
// show announcement for 15 seconds
new AnnounceFrame(toInstallPlugins.size() + " plugin update are available", "View", new Runnable()
{
@Override
public void run()
{
// show pluginInstaller frame
new PluginUpdateFrame(toInstallPlugins);
}
}, ANNOUNCE_SHOWTIME);
}
}
else
{
// inform that there is no plugin update available
if (!silent && !Icy.getMainInterface().isHeadLess())
new AnnounceFrame("No plugin udpate available", 10);
}
}
finally
{
checking = false;
}
}
}