/* * Created on 20 mai 2004 * Created by Olivier Chalouhi * * Copyright (C) 2004, 2005, 2006 Aelitis SAS, All rights Reserved * * This program 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 2 of the License. * * This program 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 ( see the LICENSE file ). * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * AELITIS, SAS au capital de 46,603.30 euros, * 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France. */ package org.gudy.azureus2.ui.swt.updater2; import java.io.File; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.List; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import org.eclipse.swt.SWT; import org.gudy.azureus2.core3.config.COConfigurationManager; import org.gudy.azureus2.core3.internat.MessageText; import org.gudy.azureus2.core3.logging.*; import org.gudy.azureus2.core3.util.Constants; import org.gudy.azureus2.core3.util.Debug; import org.gudy.azureus2.core3.util.FileUtil; import org.gudy.azureus2.core3.util.SystemProperties; import org.gudy.azureus2.core3.util.SystemTime; import org.gudy.azureus2.plugins.update.UpdatableComponent; import org.gudy.azureus2.plugins.update.Update; import org.gudy.azureus2.plugins.update.UpdateChecker; import org.gudy.azureus2.plugins.update.UpdateInstaller; import org.gudy.azureus2.plugins.utils.resourcedownloader.ResourceDownloader; import org.gudy.azureus2.plugins.utils.resourcedownloader.ResourceDownloaderException; import org.gudy.azureus2.plugins.utils.resourcedownloader.ResourceDownloaderFactory; import org.gudy.azureus2.plugins.utils.resourcedownloader.ResourceDownloaderAdapter; import org.gudy.azureus2.pluginsimpl.local.utils.resourcedownloader.ResourceDownloaderFactoryImpl; import org.gudy.azureus2.pluginsimpl.local.PluginInitializer; /** * @author Olivier Chalouhi * */ public class SWTUpdateChecker implements UpdatableComponent { private static final LogIDs LOGID = LogIDs.GUI; private static final String OSX_APP = "/" + SystemProperties.getApplicationName() + ".app"; public static void initialize() { PluginInitializer.getDefaultInterface().getUpdateManager().registerUpdatableComponent(new SWTUpdateChecker(),true); } public SWTUpdateChecker() { } public void checkForUpdate(final UpdateChecker checker) { try{ SWTVersionGetter versionGetter = new SWTVersionGetter( checker ); boolean update_required = System.getProperty("azureus.skipSWTcheck") == null && versionGetter.needsUpdate(); if ( update_required ){ int update_prevented_version = COConfigurationManager.getIntParameter( "swt.update.prevented.version", -1 ); try{ URL swt_url = SWT.class.getClassLoader().getResource("org/eclipse/swt/SWT.class"); if ( swt_url != null ){ String url_str = swt_url.toExternalForm(); if ( url_str.startsWith("jar:file:")){ File jar_file = FileUtil.getJarFileFromURL(url_str); String expected_location; if ( Constants.isOSX ){ expected_location = checker.getCheckInstance().getManager().getInstallDir() + OSX_APP + "/Contents/Resources/Java"; }else{ expected_location = checker.getCheckInstance().getManager().getInstallDir(); } File expected_dir = new File( expected_location ); File jar_file_dir = jar_file.getParentFile(); // sanity check if ( expected_dir.exists() && jar_file_dir.exists() ){ expected_dir = expected_dir.getCanonicalFile(); jar_file_dir = jar_file_dir.getCanonicalFile(); if ( expected_dir.equals( jar_file_dir )){ // everything looks ok if ( update_prevented_version != -1 ){ update_prevented_version = -1; COConfigurationManager.setParameter( "swt.update.prevented.version", update_prevented_version ); } }else{ // we need to periodically remind the user there's a problem as they need to realise that // it is causing ALL updates (core/plugin) to fail String alert = MessageText.getString( "swt.alert.cant.update", new String[]{ String.valueOf( versionGetter.getCurrentVersion()), String.valueOf( versionGetter.getLatestVersion()), jar_file_dir.toString(), expected_dir.toString()}); checker.reportProgress( alert ); long last_prompt = COConfigurationManager.getLongParameter( "swt.update.prevented.version.time", 0 ); long now = SystemTime.getCurrentTime(); boolean force = now < last_prompt || now - last_prompt > 7*24*60*60*1000; if ( !checker.getCheckInstance().isAutomatic()){ force = true; } if ( force || update_prevented_version != versionGetter.getCurrentVersion()){ Logger.log( new LogAlert(LogAlert.REPEATABLE, LogEvent.LT_ERROR, alert )); update_prevented_version = versionGetter.getCurrentVersion(); COConfigurationManager.setParameter( "swt.update.prevented.version", update_prevented_version ); COConfigurationManager.setParameter( "swt.update.prevented.version.time", now ); } } } } } }catch( Throwable e ){ Debug.printStackTrace(e); } if ( update_prevented_version == versionGetter.getCurrentVersion()){ Logger.log(new LogEvent(LOGID, LogEvent.LT_ERROR, "SWT update aborted due to previously reported issues regarding its install location" )); checker.failed(); checker.getCheckInstance().cancel(); return; } String[] mirrors = versionGetter.getMirrors(); ResourceDownloader swtDownloader = null; ResourceDownloaderFactory factory = ResourceDownloaderFactoryImpl.getSingleton(); List downloaders = new ArrayList(); for(int i = 0 ; i < mirrors.length ; i++) { try { downloaders.add(factory.getSuffixBasedDownloader(factory.create(new URL(mirrors[i])))); } catch(MalformedURLException e) { //Do nothing if (Logger.isEnabled()) Logger.log(new LogEvent(LOGID, LogEvent.LT_WARNING, "Cannot use URL " + mirrors[i] + " (not valid)")); } } ResourceDownloader[] resourceDownloaders = (ResourceDownloader[]) downloaders.toArray(new ResourceDownloader[downloaders.size()]); swtDownloader = factory.getRandomDownloader(resourceDownloaders); // get the size so its cached up try{ swtDownloader.getSize(); }catch( ResourceDownloaderException e ){ Debug.printStackTrace( e ); } final Update update = checker.addUpdate("SWT Library for " + versionGetter.getPlatform(), new String[] {"SWT is the graphical library used by " + Constants.APP_NAME}, "" + versionGetter.getLatestVersion(), swtDownloader, Update.RESTART_REQUIRED_YES ); update.setDescriptionURL(versionGetter.getInfoURL()); swtDownloader.addListener(new ResourceDownloaderAdapter() { public boolean completed( ResourceDownloader downloader, InputStream data) { //On completion, process the InputStream to store temp files return processData(checker,update,downloader,data); } public void failed( ResourceDownloader downloader, ResourceDownloaderException e ) { Debug.out( downloader.getName() + " failed", e ); update.complete( false ); } }); } }catch( Throwable e ){ Logger.log(new LogAlert(LogAlert.UNREPEATABLE, "SWT Version check failed", e)); checker.failed(); }finally{ checker.completed(); } } private boolean processData( UpdateChecker checker, Update update, ResourceDownloader rd, InputStream data ) { ZipInputStream zip = null; try { data = update.verifyData( data, true ); rd.reportActivity( "Data verified successfully" ); UpdateInstaller installer = checker.createInstaller(); zip = new ZipInputStream(data); ZipEntry entry = null; while((entry = zip.getNextEntry()) != null) { String name = entry.getName(); // all jars if ( name.endsWith( ".jar" )){ installer.addResource(name,zip,false); if ( Constants.isOSX ){ installer.addMoveAction(name,installer.getInstallDir() + OSX_APP + "/Contents/Resources/Java/" + name); }else{ installer.addMoveAction(name,installer.getInstallDir() + File.separator + name); } }else if ( name.endsWith(".jnilib") && Constants.isOSX ){ //on OS X, any .jnilib installer.addResource(name,zip,false); installer.addMoveAction(name,installer.getInstallDir() + OSX_APP + "/Contents/Resources/Java/dll/" + name); }else if ( name.equals("java_swt")){ //on OS X, java_swt (the launcher to start SWT applications) installer.addResource(name,zip,false); installer.addMoveAction(name,installer.getInstallDir() + OSX_APP + "/Contents/MacOS/" + name); installer.addChangeRightsAction("755",installer.getInstallDir() + OSX_APP + "/Contents/MacOS/" + name); }else if( name.endsWith( ".dll" ) || name.endsWith( ".so" ) || name.indexOf( ".so." ) != -1 ) { // native stuff for windows and linux installer.addResource(name,zip,false); installer.addMoveAction(name,installer.getInstallDir() + File.separator + name); }else if ( name.equals("javaw.exe.manifest") || name.equals( "azureus.sig" )){ // silently ignore this one }else{ Debug.outNoStack( "SWTUpdate: ignoring zip entry '" + name + "'" ); } } update.complete( true ); } catch(Throwable e) { update.complete( false ); Logger.log(new LogAlert(LogAlert.UNREPEATABLE, "SWT Update failed", e)); return false; }finally{ if ( zip != null ){ try{ zip.close(); }catch( Throwable e ){ } } } return true; } public String getName() { return( "SWT library" ); } public int getMaximumCheckTime() { return( 30 ); // !!!! TODO: fix this } }