/* * Copyright (c) 2009 Andrejs Jermakovics. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Andrejs Jermakovics - initial implementation */ package it.unibz.instasearch.jobs; import it.unibz.instasearch.InstaSearchPlugin; import it.unibz.instasearch.actions.ShowExceptionAction; import it.unibz.instasearch.ui.InstaSearchUI; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import org.apache.commons.httpclient.Credentials; import org.apache.commons.httpclient.HostConfiguration; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpException; import org.apache.commons.httpclient.HttpStatus; import org.apache.commons.httpclient.UsernamePasswordCredentials; import org.apache.commons.httpclient.auth.AuthScope; import org.apache.commons.httpclient.methods.GetMethod; import org.eclipse.core.net.proxy.IProxyData; import org.eclipse.core.net.proxy.IProxyService; import org.eclipse.core.resources.WorkspaceJob; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.IAction; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.progress.IProgressConstants; /** * A job that checks for new updates of the plugin * */ public class CheckUpdatesJob extends WorkspaceJob { // return code constants public static final int UPDATE_AVAILABLE_CODE = 1; public static final int NO_UPDATE_AVAILABLE_CODE = 2; private boolean updateAvailable; public CheckUpdatesJob() { super("InstaSearch Update Check"); setPriority(DECORATE); setProperty(IProgressConstants.ICON_PROPERTY, InstaSearchPlugin.getImageDescriptor("update")); setProperty(IProgressConstants.NO_IMMEDIATE_ERROR_PROMPT_PROPERTY, Boolean.TRUE); setProperty(IProgressConstants.KEEPONE_PROPERTY, Boolean.TRUE); } @Override public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException { try { checkForUpdates(monitor); if( ! isSystem() ) PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() { public void run() { IAction action; if( isUpdateAvailable() ) action = createUpdateNotificationAction(); else action = createNoUpdateNotificationAction(); action.run(); } }); //setProperty(IProgressConstants.ACTION_PROPERTY, action); } catch (Exception e) { IAction action = new ShowExceptionAction(e, "Error Checking Updates"); setProperty(IProgressConstants.ACTION_PROPERTY, action); if (!isSystem()) setProperty(IProgressConstants.KEEP_PROPERTY, Boolean.TRUE); if( ! isSystem() ) { InstaSearchPlugin.log(e); return new Status(IStatus.ERROR, InstaSearchPlugin.getPluginId(), 0, action.getText(), e); } } int returnCode = isUpdateAvailable() ? UPDATE_AVAILABLE_CODE : NO_UPDATE_AVAILABLE_CODE; return new Status(IStatus.OK, InstaSearchPlugin.getPluginId(), returnCode, "Done", null); } private boolean checkForUpdates(IProgressMonitor monitor) throws HttpException, IOException, URISyntaxException { updateAvailable = false; String versionCheckUrl = InstaSearchPlugin.getUpdateLocation(); String v = InstaSearchPlugin.getVersion(); HttpClient httpClient = new HttpClient(); configureProxy(httpClient, versionCheckUrl); GetMethod getMethod = new GetMethod(versionCheckUrl + "?v="+v); int statusCode = httpClient.executeMethod(getMethod); if (statusCode != HttpStatus.SC_OK) return updateAvailable; String response = getMethod.getResponseBodyAsString(); getMethod.releaseConnection(); if( "y".equals(response) ) updateAvailable = true; return updateAvailable; } /** * @param httpClient * @param versionCheckUrl * @throws URISyntaxException */ private void configureProxy(HttpClient httpClient, String versionCheckUrl) throws URISyntaxException { IProxyService proxyService = InstaSearchPlugin.getDefault().getProxyService(); if (proxyService != null && proxyService.isProxiesEnabled()) { URI uri = new URI(versionCheckUrl); final IProxyData[] proxiesData = proxyService.select(uri); IProxyData proxy = null; for(IProxyData proxyData: proxiesData) { if( proxyData.getType().equals(IProxyData.HTTP_PROXY_TYPE) ) { proxy = proxyData; break; } } if( proxy == null ) return; HostConfiguration config = httpClient.getHostConfiguration(); config.setProxy(proxy.getHost(), proxy.getPort()); if( proxy.isRequiresAuthentication() ) { Credentials credentials = new UsernamePasswordCredentials(proxy.getUserId(), proxy.getPassword()); AuthScope authScope = new AuthScope(proxy.getHost(), proxy.getPort()); httpClient.getState().setProxyCredentials(authScope, credentials); } } } private IAction createNoUpdateNotificationAction() { String text = "No Update Available"; IAction notificationAction = new Action(text) { public void run() { InstaSearchUI.showMessage("You have the latest version (" + InstaSearchPlugin.getVersion() + ")"); setEnabled(false); } }; notificationAction.setDescription(text); notificationAction.setToolTipText(text); return notificationAction; } /** * Creates an action that offers to update the plugin * @return IAction */ public static IAction createUpdateNotificationAction() { String text = "New Version Available"; IAction notificationAction = new Action("Update") { public void run() { /* MessageDialogWithToggle.openYesNoQuestion(shell, "Update", "There is a new version of InstaSearch available. Update?", "Update automatically", true, InstaSearchPlugin.getDefault().getPreferenceStore(), "AUTO_UPDATE"); */ boolean update = MessageDialog.openQuestion( InstaSearchUI.getActiveShell(), getDescription(), "There is a new version available. Update?"); if( update ) { UpdatePluginJob updateJob = new UpdatePluginJob(); updateJob.schedule(); } } }; notificationAction.setDescription(text); notificationAction.setToolTipText(text); return notificationAction; } /** * Is there an update available for this plugin * The value is set after the job has finished * @return UpdateAvailable */ public boolean isUpdateAvailable() { return updateAvailable; } @Override public boolean belongsTo(Object family) { return family == CheckUpdatesJob.class; } }