001/* 002 * Copyright 2010-2015 Institut Pasteur. 003 * 004 * This file is part of Icy. 005 * 006 * Icy is free software: you can redistribute it and/or modify 007 * it under the terms of the GNU General Public License as published by 008 * the Free Software Foundation, either version 3 of the License, or 009 * (at your option) any later version. 010 * 011 * Icy is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 014 * GNU General Public License for more details. 015 * 016 * You should have received a copy of the GNU General Public License 017 * along with Icy. If not, see <http://www.gnu.org/licenses/>. 018 */ 019package icy.plugin; 020 021import icy.gui.frame.progress.AnnounceFrame; 022import icy.gui.frame.progress.CancelableProgressFrame; 023import icy.gui.frame.progress.ProgressFrame; 024import icy.gui.plugin.PluginUpdateFrame; 025import icy.main.Icy; 026import icy.network.NetworkUtil; 027import icy.system.thread.ThreadUtil; 028 029import java.util.ArrayList; 030import java.util.List; 031 032/** 033 * Plugin updater class. 034 * 035 * @author Stephane.D 036 */ 037public class PluginUpdater 038{ 039 private static final int ANNOUNCE_SHOWTIME = 15; 040 041 // internal 042 private static boolean silent; 043 private static boolean checking = false; 044 private static Runnable checker = new Runnable() 045 { 046 @Override 047 public void run() 048 { 049 processCheckUpdate(); 050 } 051 }; 052 053 /** 054 * return true if we are currently checking for update 055 */ 056 public static boolean isCheckingForUpdate() 057 { 058 return checking || ThreadUtil.hasWaitingBgSingleTask(checker); 059 } 060 061 /** 062 * Do the check update process 063 */ 064 public static void checkUpdate(boolean silent) 065 { 066 if (!isCheckingForUpdate()) 067 { 068 PluginUpdater.silent = silent; 069 ThreadUtil.bgRunSingle(checker); 070 } 071 } 072 073 /** 074 * @deprecated Use {@link #checkUpdate(boolean)} instead 075 */ 076 @Deprecated 077 public static void checkUpdate(boolean showProgress, boolean auto) 078 { 079 checkUpdate(!showProgress || auto); 080 } 081 082 /** 083 * Get update for the specified plugin. 084 * 085 * @param plugin 086 * local plugin we are looking update for 087 * @return 088 * plugin descriptor of update if any (null if no update) 089 */ 090 public static PluginDescriptor getUpdate(PluginDescriptor plugin) 091 { 092 // don't check update for kernel plugin 093 if (plugin.isKernelPlugin()) 094 return null; 095 096 // find equivalent online plugins 097 final List<PluginDescriptor> onlinePlugins = PluginRepositoryLoader.getPlugins(plugin.getClassName()); 098 final PluginDescriptor onlinePlugin; 099 100 // get the last version found 101 if (onlinePlugins.size() > 0) 102 { 103 PluginDescriptor lastVersion = null; 104 105 for (PluginDescriptor currentVersion : onlinePlugins) 106 if ((lastVersion == null) || currentVersion.isNewer(lastVersion)) 107 lastVersion = currentVersion; 108 109 onlinePlugin = lastVersion; 110 } 111 else 112 // not found in repositories 113 onlinePlugin = null; 114 115 // we have an update available ? 116 if ((onlinePlugin != null) && onlinePlugin.getVersion().isGreater(plugin.getVersion())) 117 return onlinePlugin; 118 119 // random forced update 120 // if (Random.nextBoolean()) 121 // return onlinePlugin; 122 123 return null; 124 } 125 126 /** 127 * Update the specified list of plugins. 128 */ 129 public static void updatePlugins(List<PluginDescriptor> plugins, boolean showProgress) 130 { 131 try 132 { 133 // update plugins with ordered dependencies 134 for (PluginDescriptor plugin : PluginInstaller.orderDependencies(plugins)) 135 PluginInstaller.install(plugin, showProgress); 136 } 137 finally 138 { 139 PluginLoader.reloadAsynch(); 140 } 141 } 142 143 /** 144 * Check for plugins update process (synchronized method) 145 */ 146 public static synchronized void processCheckUpdate() 147 { 148 checking = true; 149 try 150 { 151 final List<PluginDescriptor> toInstallPlugins = new ArrayList<PluginDescriptor>(); 152 final List<PluginDescriptor> localPlugins = PluginLoader.getPlugins(false); 153 final ProgressFrame checkingFrame; 154 155 if (!silent && !Icy.getMainInterface().isHeadLess()) 156 checkingFrame = new CancelableProgressFrame("checking for plugins update..."); 157 else 158 checkingFrame = null; 159 try 160 { 161 // reload online plugins from all active repositories 162 PluginRepositoryLoader.reload(); 163 // wait for basic infos 164 PluginRepositoryLoader.waitLoaded(); 165 166 if (PluginRepositoryLoader.failed()) 167 { 168 if (!silent && !Icy.getMainInterface().isHeadLess()) 169 { 170 if (!NetworkUtil.hasInternetAccess()) 171 new AnnounceFrame("You are not connected to internet.", 10); 172 else 173 new AnnounceFrame("Can't access the repositories... You should verify your connection.", 174 10); 175 } 176 177 return; 178 } 179 180 for (PluginDescriptor localPlugin : localPlugins) 181 { 182 // find update 183 final PluginDescriptor onlinePlugin = getUpdate(localPlugin); 184 185 // update found, add to the list 186 if (onlinePlugin != null) 187 { 188 // we load complete descriptor so we will have the changeslog 189 onlinePlugin.loadDescriptor(); 190 toInstallPlugins.add(onlinePlugin); 191 } 192 } 193 194 // TODO: incorrect java version cannot be fixed with plugin udpate ! 195 final List<PluginDescriptor> onlinePlugins = PluginRepositoryLoader.getPlugins(); 196 197 for (PluginDescriptor onlinePlugin : onlinePlugins) 198 { 199 // we found a plugin which is installed but not correctly loaded 200 // so we try to reinstall it 201 if (onlinePlugin.isInstalled() && !PluginLoader.isLoaded(onlinePlugin.getClassName())) 202 { 203 // we load complete descriptor so we will have the changeslog 204 onlinePlugin.loadDescriptor(); 205 toInstallPlugins.add(onlinePlugin); 206 } 207 } 208 } 209 finally 210 { 211 if (checkingFrame != null) 212 checkingFrame.close(); 213 } 214 215 // some updates availables ? 216 if (!toInstallPlugins.isEmpty()) 217 { 218 // silent update or headless mode 219 if (silent || Icy.getMainInterface().isHeadLess()) 220 { 221 // automatically install all updates (orderer depending dependencies) 222 updatePlugins(toInstallPlugins, true); 223 } 224 else 225 { 226 // show announcement for 15 seconds 227 new AnnounceFrame(toInstallPlugins.size() + " plugin update are available", "View", new Runnable() 228 { 229 @Override 230 public void run() 231 { 232 // show pluginInstaller frame 233 new PluginUpdateFrame(toInstallPlugins); 234 } 235 }, ANNOUNCE_SHOWTIME); 236 } 237 } 238 else 239 { 240 // inform that there is no plugin update available 241 if (!silent && !Icy.getMainInterface().isHeadLess()) 242 new AnnounceFrame("No plugin udpate available", 10); 243 } 244 } 245 finally 246 { 247 checking = false; 248 } 249 } 250}