From: Cherian Mathew Date: Tue, 9 Sep 2014 12:47:39 +0000 (+0000) Subject: P2 update implementation and editor version extraction X-Git-Tag: 3.6.0~456 X-Git-Url: https://dev.e-taxonomy.eu/gitweb/taxeditor.git/commitdiff_plain/49c6e8c340be57457e9866bc93ee640a6cce0dc6 P2 update implementation and editor version extraction ApplicationWorkbenchAdvisor : clean up ApplicationWorkbenchWindowAdvisor : added update of editor to startup P2Util : replaced older class with a new one which handles background update of editor UpdateHandler : handles modal update of editor when requested InstallNewSoftwareHandler, PreloadingRepositoryHandler : handlers for installing new software and preloading repositories (not used yet) ApplicationUtil : added new methods to retrieve editor version number TaxonomicEditorPlugin : added new methods for retrieving provisioning elements build.properties, pom.xml, plugin_en.properties, plugin.properties, plugin_de.properties : setup dynamic properties (version number , build date) to be replaced via maven plugin.xml, MANIFEST.MF : added new dependencies for p2 update mechanism p2.inf : deleted since we now setup update repositories programmatically --- diff --git a/.gitattributes b/.gitattributes index 34da68eeb..768289917 100644 --- a/.gitattributes +++ b/.gitattributes @@ -14,7 +14,6 @@ eu.etaxonomy.taxeditor.application/icons/256color_48x48.gif -text eu.etaxonomy.taxeditor.application/icons/256color_48x48.ico -text eu.etaxonomy.taxeditor.application/icons/edit_16x16.gif -text eu.etaxonomy.taxeditor.application/icons/specimen_derivate-16x16-32.png -text -eu.etaxonomy.taxeditor.application/p2.inf -text eu.etaxonomy.taxeditor.application/plugin.xml -text eu.etaxonomy.taxeditor.application/plugin_customization.ini -text eu.etaxonomy.taxeditor.application/pom.xml -text @@ -27,7 +26,6 @@ eu.etaxonomy.taxeditor.application/src/main/java/eu/etaxonomy/taxeditor/Applicat eu.etaxonomy.taxeditor.application/src/main/java/eu/etaxonomy/taxeditor/OpenExternalAboutPlatformHandler.java -text eu.etaxonomy.taxeditor.application/src/main/java/eu/etaxonomy/taxeditor/OpenExternalHelpHandler.java -text eu.etaxonomy.taxeditor.application/src/main/java/eu/etaxonomy/taxeditor/OpenExternalParserHelpHandler.java -text -eu.etaxonomy.taxeditor.application/src/main/java/eu/etaxonomy/taxeditor/P2Util.java -text eu.etaxonomy.taxeditor.application/src/main/java/eu/etaxonomy/taxeditor/SaveAllHandler.java -text eu.etaxonomy.taxeditor.application/src/main/java/eu/etaxonomy/taxeditor/SaveHandler.java -text eu.etaxonomy.taxeditor.application/src/main/java/eu/etaxonomy/taxeditor/TaxonomicEditorPlugin.java -text @@ -37,6 +35,10 @@ eu.etaxonomy.taxeditor.application/src/main/java/eu/etaxonomy/taxeditor/perspect eu.etaxonomy.taxeditor.application/src/main/java/eu/etaxonomy/taxeditor/perspective/PolytomousKey.java -text eu.etaxonomy.taxeditor.application/src/main/java/eu/etaxonomy/taxeditor/perspective/Taxonomic.java -text eu.etaxonomy.taxeditor.application/src/main/java/eu/etaxonomy/taxeditor/perspective/Uses.java -text +eu.etaxonomy.taxeditor.application/src/main/java/eu/etaxonomy/taxeditor/update/InstallNewSoftwareHandler.java -text +eu.etaxonomy.taxeditor.application/src/main/java/eu/etaxonomy/taxeditor/update/P2Util.java -text +eu.etaxonomy.taxeditor.application/src/main/java/eu/etaxonomy/taxeditor/update/PreloadingRepositoryHandler.java -text +eu.etaxonomy.taxeditor.application/src/main/java/eu/etaxonomy/taxeditor/update/UpdateHandler.java -text eu.etaxonomy.taxeditor.application/src/main/resources/log4j.properties -text eu.etaxonomy.taxeditor.bulkeditor/.classpath -text eu.etaxonomy.taxeditor.bulkeditor/.project -text diff --git a/eu.etaxonomy.taxeditor.application/META-INF/MANIFEST.MF b/eu.etaxonomy.taxeditor.application/META-INF/MANIFEST.MF index 4406e8226..0c9d0d78d 100644 --- a/eu.etaxonomy.taxeditor.application/META-INF/MANIFEST.MF +++ b/eu.etaxonomy.taxeditor.application/META-INF/MANIFEST.MF @@ -28,4 +28,6 @@ Require-Bundle: org.eclipse.ui, org.eclipse.equinox.p2.ui.sdk, org.eclipse.equinox.p2.updatechecker, org.eclipse.equinox.p2.operations, - org.eclipse.help.ui + org.eclipse.help.ui, + org.eclipse.equinox.p2.metadata;bundle-version="2.1.0", + org.eclipse.equinox.p2.engine;bundle-version="2.1.1" diff --git a/eu.etaxonomy.taxeditor.application/OSGI-INF/l10n/plugin.properties b/eu.etaxonomy.taxeditor.application/OSGI-INF/l10n/plugin.properties index 9e64cfd64..0e667dcc1 100644 --- a/eu.etaxonomy.taxeditor.application/OSGI-INF/l10n/plugin.properties +++ b/eu.etaxonomy.taxeditor.application/OSGI-INF/l10n/plugin.properties @@ -1,5 +1,5 @@ productName=EDIT Taxonomic Editor -productBlurb=EDIT Taxonomic Editor\n\Version: 3.3\n\n\Copyright (C) 2009 EDIT\n\European Distributed Institute of Taxonomy\n\http://www.e-taxonomy.eu +productBlurb=EDIT Taxonomic Editor\n\Version: {0}\nBuild Date: {1}\n\n\Copyright (C) 2009 EDIT\n\European Distributed Institute of Taxonomy\n\http://www.e-taxonomy.eu extension.name = Taxonomic Editor perspective.name = Taxonomic diff --git a/eu.etaxonomy.taxeditor.application/OSGI-INF/l10n/plugin_de.properties b/eu.etaxonomy.taxeditor.application/OSGI-INF/l10n/plugin_de.properties index 2283ab3b7..e044ff1d2 100644 --- a/eu.etaxonomy.taxeditor.application/OSGI-INF/l10n/plugin_de.properties +++ b/eu.etaxonomy.taxeditor.application/OSGI-INF/l10n/plugin_de.properties @@ -1,5 +1,5 @@ productName=EDIT Taxonomischer Editor -productBlurb=EDIT Taxonomischer Editor\n\Version: 3.3\n\n\Copyright (C) 2009 EDIT\n\European Distributed Institute of Taxonomy\n\http://www.e-taxonomy.eu +productBlurb=EDIT Taxonomischer Editor\n\Version: {0}\nBuild Date: {1}\n\n\Copyright (C) 2009 EDIT\n\European Distributed Institute of Taxonomy\n\http://www.e-taxonomy.eu extension.name = Taxonomischer Editor perspective.name = Taxonomisch diff --git a/eu.etaxonomy.taxeditor.application/OSGI-INF/l10n/plugin_en.properties b/eu.etaxonomy.taxeditor.application/OSGI-INF/l10n/plugin_en.properties index 9e64cfd64..0e667dcc1 100644 --- a/eu.etaxonomy.taxeditor.application/OSGI-INF/l10n/plugin_en.properties +++ b/eu.etaxonomy.taxeditor.application/OSGI-INF/l10n/plugin_en.properties @@ -1,5 +1,5 @@ productName=EDIT Taxonomic Editor -productBlurb=EDIT Taxonomic Editor\n\Version: 3.3\n\n\Copyright (C) 2009 EDIT\n\European Distributed Institute of Taxonomy\n\http://www.e-taxonomy.eu +productBlurb=EDIT Taxonomic Editor\n\Version: {0}\nBuild Date: {1}\n\n\Copyright (C) 2009 EDIT\n\European Distributed Institute of Taxonomy\n\http://www.e-taxonomy.eu extension.name = Taxonomic Editor perspective.name = Taxonomic diff --git a/eu.etaxonomy.taxeditor.application/build.properties b/eu.etaxonomy.taxeditor.application/build.properties index af4a4e99e..cccbe07e1 100644 --- a/eu.etaxonomy.taxeditor.application/build.properties +++ b/eu.etaxonomy.taxeditor.application/build.properties @@ -7,7 +7,6 @@ bin.includes = META-INF/,\ plugin_customization.ini,\ icons/,\ OSGI-INF/l10n/plugin.properties,\ - splash.bmp,\ - p2.inf,\ + splash.bmp,\ OSGI-INF/l10n/plugin_de.properties,\ OSGI-INF/l10n/plugin_en.properties diff --git a/eu.etaxonomy.taxeditor.application/p2.inf b/eu.etaxonomy.taxeditor.application/p2.inf deleted file mode 100644 index cdeccf81b..000000000 --- a/eu.etaxonomy.taxeditor.application/p2.inf +++ /dev/null @@ -1,3 +0,0 @@ -instructions.configure=\ - addRepository(type:0,location:http${#58}//wp5.e-taxonomy.eu/taxeditor/update);\ - addRepository(type:1,location:http${#58}//wp5.e-taxonomy.eu/taxeditor/update); \ No newline at end of file diff --git a/eu.etaxonomy.taxeditor.application/plugin.xml b/eu.etaxonomy.taxeditor.application/plugin.xml index 4921f4a52..1e27e9f47 100644 --- a/eu.etaxonomy.taxeditor.application/plugin.xml +++ b/eu.etaxonomy.taxeditor.application/plugin.xml @@ -245,16 +245,14 @@ name="eu.etaxonomy.taxeditor.ui.help.separator1" visible="true"> + - - - + style="push"/> @@ -341,8 +339,19 @@ id="eu.etaxonomy.taxeditor.application.help.aboutPlatform" name="%command.name.0"> + + + + - + + + name="EDIT Taxonomic Editor"> diff --git a/eu.etaxonomy.taxeditor.application/pom.xml b/eu.etaxonomy.taxeditor.application/pom.xml index b40d53fbe..20e1dfcca 100644 --- a/eu.etaxonomy.taxeditor.application/pom.xml +++ b/eu.etaxonomy.taxeditor.application/pom.xml @@ -1,18 +1,34 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> - - eu.etaxonomy - taxeditor-parent - 3.3.8-SNAPSHOT - + + eu.etaxonomy + taxeditor-parent + 3.3.8-SNAPSHOT + - 4.0.0 - eu.etaxonomy.taxeditor.application - eclipse-plugin - - Application - All plugins are combined into this application. - http://dev.e-taxonomy.eu/trac/wiki/TaxonomicEditor + 4.0.0 + eu.etaxonomy.taxeditor.application + eclipse-plugin + Application + All plugins are combined into this application. + http://dev.e-taxonomy.eu/trac/wiki/TaxonomicEditor + + + ${maven.build.timestamp} + yyyy-MM-dd HH:mm + + + + + + . + + about.mappings + + true + + + diff --git a/eu.etaxonomy.taxeditor.application/src/main/java/eu/etaxonomy/taxeditor/ApplicationUtil.java b/eu.etaxonomy.taxeditor.application/src/main/java/eu/etaxonomy/taxeditor/ApplicationUtil.java index 105f62e2d..d9974abae 100644 --- a/eu.etaxonomy.taxeditor.application/src/main/java/eu/etaxonomy/taxeditor/ApplicationUtil.java +++ b/eu.etaxonomy.taxeditor.application/src/main/java/eu/etaxonomy/taxeditor/ApplicationUtil.java @@ -1,15 +1,18 @@ // $Id$ /** * Copyright (C) 2007 EDIT -* European Distributed Institute of Taxonomy +* European Distributed Institute of Taxonomy * http://www.e-taxonomy.eu -* +* * The contents of this file are subject to the Mozilla Public License Version 1.1 * See LICENSE.TXT at the top of this package for the full license terms. */ package eu.etaxonomy.taxeditor; +import org.eclipse.core.runtime.Platform; +import org.osgi.framework.Bundle; + import eu.etaxonomy.taxeditor.model.AbstractUtility; /** @@ -21,6 +24,35 @@ import eu.etaxonomy.taxeditor.model.AbstractUtility; */ public class ApplicationUtil extends AbstractUtility { + + private static final String BETA_PREFIX = "[BETA]"; + + /** + * @return + */ + public static String getVersion() { + Bundle bundle = Platform.getBundle("eu.etaxonomy.taxeditor.application"); + String version = bundle.getHeaders().get(org.osgi.framework.Constants.BUNDLE_VERSION); + // Checking if this is a beta (snapshot) version + if(version ==null || version.isEmpty()) { + return ""; + } + String[] parts = version.split("\\."); + if(parts.length <= 3) { + // this is a stable version + return version; + } else { + return BETA_PREFIX + version; + } + + } + + /** + * @return + */ + public static boolean isStable() { + return !getVersion().startsWith(BETA_PREFIX); + } /** *

getPluginId

* @@ -29,5 +61,7 @@ public class ApplicationUtil extends AbstractUtility { public static String getPluginId(){ return TaxonomicEditorPlugin.PLUGIN_ID; } - + + + } diff --git a/eu.etaxonomy.taxeditor.application/src/main/java/eu/etaxonomy/taxeditor/ApplicationWorkbenchAdvisor.java b/eu.etaxonomy.taxeditor.application/src/main/java/eu/etaxonomy/taxeditor/ApplicationWorkbenchAdvisor.java index 18ac99ecf..fc694b221 100644 --- a/eu.etaxonomy.taxeditor.application/src/main/java/eu/etaxonomy/taxeditor/ApplicationWorkbenchAdvisor.java +++ b/eu.etaxonomy.taxeditor.application/src/main/java/eu/etaxonomy/taxeditor/ApplicationWorkbenchAdvisor.java @@ -1,21 +1,13 @@ package eu.etaxonomy.taxeditor; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.rmi.activation.Activator; - import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.jface.dialogs.ErrorDialog; -import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.application.IWorkbenchConfigurer; import org.eclipse.ui.application.IWorkbenchWindowConfigurer; import org.eclipse.ui.application.WorkbenchAdvisor; import org.eclipse.ui.application.WorkbenchWindowAdvisor; import org.eclipse.ui.statushandlers.AbstractStatusHandler; import org.eclipse.ui.statushandlers.StatusAdapter; -import org.eclipse.ui.statushandlers.StatusManager; import eu.etaxonomy.taxeditor.model.MessagingUtils; @@ -35,12 +27,13 @@ public class ApplicationWorkbenchAdvisor extends WorkbenchAdvisor { * @see org.eclipse.ui.application.WorkbenchAdvisor#createWorkbenchWindowAdvisor(org.eclipse.ui.application.IWorkbenchWindowConfigurer) */ /** {@inheritDoc} */ - public WorkbenchWindowAdvisor createWorkbenchWindowAdvisor( + @Override + public WorkbenchWindowAdvisor createWorkbenchWindowAdvisor( IWorkbenchWindowConfigurer configurer) { return new ApplicationWorkbenchWindowAdvisor(configurer); } - + /* * (non-Javadoc) * @see org.eclipse.ui.application.WorkbenchAdvisor#getInitialWindowPerspectiveId() @@ -50,75 +43,26 @@ public class ApplicationWorkbenchAdvisor extends WorkbenchAdvisor { * * @return a {@link java.lang.String} object. */ - public String getInitialWindowPerspectiveId() { + @Override + public String getInitialWindowPerspectiveId() { return "eu.etaxonomy.taxeditor.application.perspective.taxonomic"; } - + /* * (non-Javadoc) * @see org.eclipse.ui.application.WorkbenchAdvisor#initialize(org.eclipse.ui.application.IWorkbenchConfigurer) */ /** {@inheritDoc} */ - public void initialize(IWorkbenchConfigurer configurer) { + @Override + public void initialize(IWorkbenchConfigurer configurer) { super.initialize(configurer); - + // Remembers the user's view layout, window size, window location etc. // for the next time application is started configurer.setSaveAndRestore(true); - } - - /* (non-Javadoc) - * @see org.eclipse.ui.application.WorkbenchAdvisor#preStartup() - */ - /** {@inheritDoc} */ - @Override - public void preStartup() { - // TODO Auto-generated method stub - super.preStartup(); - // XXX check for updates before starting up. - // If an update is performed, restart. -// if (P2Util.checkForUpdates()) -// PlatformUI.getWorkbench().restart(); } - -/** - * see: https://bugs.eclipse.org/bugs/show_bug.cgi?id=234252 - */ -// public void initialize(IWorkbenchConfigurer configurer) { -// -// WorkbenchAdapterBuilder.registerAdapters(); -// -// final String ICONS_PATH = "icons/full/"; -// final String PATH_OBJECT = ICONS_PATH + "obj16/"; -// Bundle ideBundle = Platform.getBundle(IDEWorkbenchPlugin.IDE_WORKBENCH); -// declareWorkbenchImage(configurer, ideBundle, -// IDE.SharedImages.IMG_OBJ_PROJECT, PATH_OBJECT + "prj_obj.gif", -// true); -// declareWorkbenchImage(configurer, ideBundle, -// IDE.SharedImages.IMG_OBJ_PROJECT_CLOSED, PATH_OBJECT -// + "cprj_obj.gif", true); -// -// } -// -// private void declareWorkbenchImage(IWorkbenchConfigurer configurer_p, -// Bundle ideBundle, String symbolicName, String path, boolean shared) { -// URL url = ideBundle.getEntry(path); -// ImageDescriptor desc = ImageDescriptor.createFromURL(url); -// configurer_p.declareImage(symbolicName, desc, shared); -// } -// -// public IAdaptable getDefaultPageInput() { -// IWorkspace workspace = ResourcesPlugin.getWorkspace(); -// return workspace.getRoot(); -// } - -// @Override -// public void eventLoopException(Throwable exception) { -// super.eventLoopException(exception); -// StoreUtil.messageDialog("Unexpected error", null, exception.getMessage(), exception); -// } - - + + /* (non-Javadoc) * @see org.eclipse.ui.application.WorkbenchAdvisor#getWorkbenchErrorHandler() */ @@ -129,21 +73,21 @@ public class ApplicationWorkbenchAdvisor extends WorkbenchAdvisor { } return cdmStatusHandler; } - + /** - * Custom status handler for handling scenarios which are + * Custom status handler for handling scenarios which are * not handled by the editor (e.g. runtime exceptions). - * + * * The default {@link org.eclipse.ui.statushandlers.WorkbenchErrorHandler} * is not used or extended because we need a handler for specific scenarios * which displays a custom built error dialog. - * + * * @author cmathew * */ class CdmStatusHandler extends AbstractStatusHandler { - + /* (non-Javadoc) * @see org.eclipse.ui.statushandlers.AbstractStatusHandler#handle(org.eclipse.ui.statushandlers.StatusAdapter, int) */ @@ -151,27 +95,27 @@ public class ApplicationWorkbenchAdvisor extends WorkbenchAdvisor { public void handle(StatusAdapter statusAdapter, int style) { if(statusAdapter.getStatus().matches(IStatus.ERROR)) { - - IStatus status = statusAdapter.getStatus(); - Throwable t = statusAdapter.getStatus().getException(); + + IStatus status = statusAdapter.getStatus(); + Throwable t = statusAdapter.getStatus().getException(); // NOTE : Currently we only allow RuntimeExceptions since - // allowing all kinds of exceptions would also include - // those in generated status objects coming from from logging triggers + // allowing all kinds of exceptions would also include + // those in generated status objects coming from from logging triggers // leading to a recursive infinite loop of : - // initial exception thrown -> status handling -> dialog opening + logging of status -> + // initial exception thrown -> status handling -> dialog opening + logging of status -> // status handling -> dialog opening + logging of status ... and so on - if(t != null && t instanceof RuntimeException) { - MessagingUtils.errorDialog("Unexpected error", - null, - MessagingUtils.UNEXPECTED_ERROR_MESSAGE, - statusAdapter.getStatus().getPlugin(), + if(t != null && t instanceof RuntimeException) { + MessagingUtils.errorDialog("Unexpected error", + null, + MessagingUtils.UNEXPECTED_ERROR_MESSAGE, + statusAdapter.getStatus().getPlugin(), t, - true); - } + true); + } } } } - - + + } diff --git a/eu.etaxonomy.taxeditor.application/src/main/java/eu/etaxonomy/taxeditor/ApplicationWorkbenchWindowAdvisor.java b/eu.etaxonomy.taxeditor.application/src/main/java/eu/etaxonomy/taxeditor/ApplicationWorkbenchWindowAdvisor.java index b6ed686bf..a15b83e5f 100644 --- a/eu.etaxonomy.taxeditor.application/src/main/java/eu/etaxonomy/taxeditor/ApplicationWorkbenchWindowAdvisor.java +++ b/eu.etaxonomy.taxeditor.application/src/main/java/eu/etaxonomy/taxeditor/ApplicationWorkbenchWindowAdvisor.java @@ -1,22 +1,18 @@ package eu.etaxonomy.taxeditor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.equinox.internal.p2.core.Activator; -import org.eclipse.equinox.p2.core.IProvisioningAgent; -import org.eclipse.equinox.p2.core.IProvisioningAgentProvider; -import org.eclipse.equinox.p2.core.ProvisionException; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.application.ActionBarAdvisor; import org.eclipse.ui.application.IActionBarConfigurer; import org.eclipse.ui.application.IWorkbenchWindowConfigurer; import org.eclipse.ui.application.WorkbenchWindowAdvisor; -import org.osgi.framework.ServiceReference; import eu.etaxonomy.taxeditor.model.MessagingUtils; +import eu.etaxonomy.taxeditor.preference.IPreferenceKeys; import eu.etaxonomy.taxeditor.preference.PreferencesUtil; import eu.etaxonomy.taxeditor.store.CdmStore; import eu.etaxonomy.taxeditor.ui.dialog.LoginDialog; +import eu.etaxonomy.taxeditor.update.P2Util; /** *

ApplicationWorkbenchWindowAdvisor class.

@@ -52,7 +48,7 @@ public class ApplicationWorkbenchWindowAdvisor extends WorkbenchWindowAdvisor { configurer.setShowCoolBar(true); configurer.setShowStatusLine(true); configurer.setShowPerspectiveBar(true); - configurer.setTitle("EDIT Taxonomic Editor"); + configurer.setTitle("EDIT Taxonomic Editor " + ApplicationUtil.getVersion()); configurer.setShowProgressIndicator(true); } @@ -67,8 +63,14 @@ public class ApplicationWorkbenchWindowAdvisor extends WorkbenchWindowAdvisor { CdmStore.connect(); } - PreferencesUtil.checkDefaultLanguage(); + try { + if(PreferencesUtil.getPreferenceStore().getBoolean(IPreferenceKeys.ALLOW_AUTO_UPDATE_AT_STARTUP)) { + P2Util.checkForUpdates(); + } + } catch (Exception e) { + MessagingUtils.error(this.getClass(), e); + } } private int authenticate(){ @@ -77,33 +79,5 @@ public class ApplicationWorkbenchWindowAdvisor extends WorkbenchWindowAdvisor { LoginDialog loginDialog = new LoginDialog(shell); return loginDialog.open(); } - - private void automaticUpdate(){ - - ServiceReference sr = Activator.context.getServiceReference(IProvisioningAgentProvider.SERVICE_NAME); - IProvisioningAgentProvider agentProvider = null; - if (sr == null) { - return; - } - agentProvider = (IProvisioningAgentProvider) Activator.context.getService(sr); - IProvisioningAgent agent = null; - try { - agent = agentProvider.createAgent(null);//new URI("file:/Applications/eclipse36/p2")); - if (agent == null) { - MessagingUtils.error(this.getClass(), "No provisioning agent found. This application is not set up for updates.", null); - return; - } - - IStatus status = P2Util.checkForUpdates(agent, null); - - MessagingUtils.info(status); - } catch (ProvisionException e) { - MessagingUtils.error(getClass(), e); - } finally { - if(agent != null) { - agent.stop(); - } - } - } } diff --git a/eu.etaxonomy.taxeditor.application/src/main/java/eu/etaxonomy/taxeditor/P2Util.java b/eu.etaxonomy.taxeditor.application/src/main/java/eu/etaxonomy/taxeditor/P2Util.java deleted file mode 100644 index 90191fea7..000000000 --- a/eu.etaxonomy.taxeditor.application/src/main/java/eu/etaxonomy/taxeditor/P2Util.java +++ /dev/null @@ -1,88 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009 IBM Corporation and others. - * 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: - * IBM Corporation - initial API and implementation - ******************************************************************************/ - -package eu.etaxonomy.taxeditor; - -import org.apache.log4j.Logger; -import org.eclipse.core.internal.runtime.Log; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.OperationCanceledException; -import org.eclipse.core.runtime.SubMonitor; -import org.eclipse.equinox.p2.core.IProvisioningAgent; -import org.eclipse.equinox.p2.operations.ProvisioningJob; -import org.eclipse.equinox.p2.operations.ProvisioningSession; -import org.eclipse.equinox.p2.operations.UpdateOperation; - -import eu.etaxonomy.taxeditor.store.StoreUtil; - -/** - * This class shows an example for checking for updates and performing the - * update synchronously. It is up to the caller to run this in a job if - * a background update check is desired. This is a reasonable way to run an - * operation when user intervention is not required. Another approach is - * to separately perform the resolution and provisioning steps, deciding - * whether to perform these synchronously or in a job. - * - * Any p2 operation can be run modally (synchronously), or the job - * can be requested and scheduled by the caller. - * - * @see UpdateOperation#resolveModal(IProgressMonitor) - * @see UpdateOperation#getResolveJob(IProgressMonitor) - * @see UpdateOperation#getProvisioningJob(IProgressMonitor) - * @see UpdateOperation#resolveModal(IProgressMonitor) - * @see UpdateOperation#getResolveJob(IProgressMonitor) - * @see UpdateOperation#getProvisioningJob(IProgressMonitor) - * @see UpdateOperation#resolveModal(IProgressMonitor) - * @see UpdateOperation#getResolveJob(IProgressMonitor) - * @see UpdateOperation#getProvisioningJob(IProgressMonitor) - * @author n.hoffmann - * @version $Id: $ - */ -public class P2Util { - - private static final Logger logger = Logger.getLogger(P2Util.class); - - // XXX Check for updates to this application and return a status. - static IStatus checkForUpdates(IProvisioningAgent agent, IProgressMonitor monitor) throws OperationCanceledException { - ProvisioningSession session = new ProvisioningSession(agent); - - // the default update operation looks for updates to the currently - // running profile, using the default profile root marker. To change - // which installable units are being updated, use the more detailed - // constructors. - UpdateOperation operation = new UpdateOperation(session); - SubMonitor sub = SubMonitor.convert(monitor, - "Checking for application updates...", 200); - IStatus status = operation.resolveModal(sub.newChild(100)); - - if (status.getCode() == UpdateOperation.STATUS_NOTHING_TO_UPDATE) { - return status; - } - if (status.getSeverity() == IStatus.CANCEL) - throw new OperationCanceledException(); - - if (status.getSeverity() != IStatus.ERROR) { - // More complex status handling might include showing the user what updates - // are available if there are multiples, differentiating patches vs. updates, etc. - // In this example, we simply update as suggested by the operation. - ProvisioningJob job = operation.getProvisioningJob(null); - if(job == null){ - return status; - } - - status = job.runModal(sub.newChild(100)); - if (status.getSeverity() == IStatus.CANCEL) - throw new OperationCanceledException(); - } - return status; - } -} diff --git a/eu.etaxonomy.taxeditor.application/src/main/java/eu/etaxonomy/taxeditor/TaxonomicEditorPlugin.java b/eu.etaxonomy.taxeditor.application/src/main/java/eu/etaxonomy/taxeditor/TaxonomicEditorPlugin.java index 50d279ef7..3d2a3330d 100644 --- a/eu.etaxonomy.taxeditor.application/src/main/java/eu/etaxonomy/taxeditor/TaxonomicEditorPlugin.java +++ b/eu.etaxonomy.taxeditor.application/src/main/java/eu/etaxonomy/taxeditor/TaxonomicEditorPlugin.java @@ -1,6 +1,11 @@ package eu.etaxonomy.taxeditor; import org.apache.log4j.Logger; +import org.eclipse.equinox.p2.core.IProvisioningAgent; +import org.eclipse.equinox.p2.engine.IProfileRegistry; +import org.eclipse.equinox.p2.operations.ProvisioningSession; +import org.eclipse.equinox.p2.ui.Policy; +import org.eclipse.equinox.p2.ui.ProvisioningUI; import org.eclipse.ui.plugin.AbstractUIPlugin; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; @@ -37,8 +42,11 @@ public class TaxonomicEditorPlugin extends AbstractUIPlugin { private ServiceRegistration policyRegistration; + private ProvisioningSession session; + private ProvisioningUI ui; + // private CloudPolicy policy; - + /** * The constructor */ @@ -50,24 +58,27 @@ public class TaxonomicEditorPlugin extends AbstractUIPlugin { * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext) */ /** {@inheritDoc} */ - public void start(BundleContext context) throws Exception { + @Override + public void start(BundleContext context) throws Exception { super.start(context); - + plugin = this; bundleContext = context; - + packageAdminRef = bundleContext.getServiceReference(PackageAdmin.class.getName()); packageAdmin = (PackageAdmin) bundleContext.getService(packageAdminRef); - + logger.debug("Taxonomic Editor started."); } private Bundle getBundle(String symbolicName) { - if (packageAdmin == null) - return null; + if (packageAdmin == null) { + return null; + } Bundle[] bundles = packageAdmin.getBundles(symbolicName, null); - if (bundles == null) - return null; + if (bundles == null) { + return null; + } // Return the first bundle that is not installed or uninstalled for (int i = 0; i < bundles.length; i++) { if ((bundles[i].getState() & (Bundle.INSTALLED | Bundle.UNINSTALLED)) == 0) { @@ -76,16 +87,17 @@ public class TaxonomicEditorPlugin extends AbstractUIPlugin { } return null; } - + /* * (non-Javadoc) * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext) */ /** {@inheritDoc} */ + @Override public void stop(BundleContext context) throws Exception { - plugin = null; - super.stop(context); - MessagingUtils.info("Taxonomic Editor stopped."); + plugin = null; + super.stop(context); + MessagingUtils.info("Taxonomic Editor stopped."); } /** @@ -94,9 +106,27 @@ public class TaxonomicEditorPlugin extends AbstractUIPlugin { * @return the shared instance */ public static TaxonomicEditorPlugin getDefault() { - return plugin; + return plugin; } - - - + + public static BundleContext getContext() { + return bundleContext; + } + + public ProvisioningUI getProvisioningUI() { + + if (ui == null) { + ServiceReference reference = bundleContext.getServiceReference(IProvisioningAgent.SERVICE_NAME); + IProvisioningAgent agent = (IProvisioningAgent) bundleContext.getService(reference); + session = new ProvisioningSession(agent); + Policy policy = null;// = (Policy) ServiceHelper.getService(ProvUIActivator.getContext(), Policy.class.getName()); + if (policy == null) { + policy = new Policy(); + } + ui = new ProvisioningUI(session, IProfileRegistry.SELF, policy); + } + return ui; + } + + } diff --git a/eu.etaxonomy.taxeditor.application/src/main/java/eu/etaxonomy/taxeditor/update/InstallNewSoftwareHandler.java b/eu.etaxonomy.taxeditor.application/src/main/java/eu/etaxonomy/taxeditor/update/InstallNewSoftwareHandler.java new file mode 100644 index 000000000..f4e8d8a19 --- /dev/null +++ b/eu.etaxonomy.taxeditor.application/src/main/java/eu/etaxonomy/taxeditor/update/InstallNewSoftwareHandler.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright (c) 2008, 2009 IBM Corporation and others. + * 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package eu.etaxonomy.taxeditor.update; + +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.equinox.p2.ui.LoadMetadataRepositoryJob; + +/** + * InstallNewSoftwareHandler invokes the install wizard + * + * @since 3.5 + */ +public class InstallNewSoftwareHandler extends PreloadingRepositoryHandler { + + /** + * The constructor. + */ + public InstallNewSoftwareHandler() { + super(); + } + + protected void doExecute(LoadMetadataRepositoryJob job) { + getProvisioningUI().openInstallWizard(null, null, job); + } + + protected boolean waitForPreload() { + // If the user cannot see repositories, then we may as well wait + // for existing repos to load so that content is available. + // If the user can manipulate the repositories, then we don't wait, + // because we don't know which ones they want to work with. + return !getProvisioningUI().getPolicy().getRepositoriesVisible(); + } + + protected void setLoadJobProperties(Job loadJob) { + super.setLoadJobProperties(loadJob); + // If we are doing a background load, we do not wish to authenticate, as the + // user is unaware that loading was needed + if (!waitForPreload()) { + loadJob.setProperty(LoadMetadataRepositoryJob.SUPPRESS_AUTHENTICATION_JOB_MARKER, Boolean.toString(true)); + loadJob.setProperty(LoadMetadataRepositoryJob.SUPPRESS_REPOSITORY_EVENTS, Boolean.toString(true)); + } + } +} diff --git a/eu.etaxonomy.taxeditor.application/src/main/java/eu/etaxonomy/taxeditor/update/P2Util.java b/eu.etaxonomy.taxeditor.application/src/main/java/eu/etaxonomy/taxeditor/update/P2Util.java new file mode 100644 index 000000000..13ecaafdd --- /dev/null +++ b/eu.etaxonomy.taxeditor.application/src/main/java/eu/etaxonomy/taxeditor/update/P2Util.java @@ -0,0 +1,195 @@ +package eu.etaxonomy.taxeditor.update; + +import java.net.URI; +import java.net.URISyntaxException; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.IJobChangeEvent; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.core.runtime.jobs.JobChangeAdapter; +import org.eclipse.equinox.p2.core.IProvisioningAgent; +import org.eclipse.equinox.p2.operations.ProvisioningJob; +import org.eclipse.equinox.p2.operations.ProvisioningSession; +import org.eclipse.equinox.p2.operations.Update; +import org.eclipse.equinox.p2.operations.UpdateOperation; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.PlatformUI; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceReference; + +import eu.etaxonomy.taxeditor.ApplicationUtil; +import eu.etaxonomy.taxeditor.TaxonomicEditorPlugin; +import eu.etaxonomy.taxeditor.model.MessagingUtils; + +/** + * This class is a utility class for updating the editor from a p2 update site, + * greatly inspired by the links given below. + * + * + * To Do : + * - Allow configurable update sites + * + * Notes : + * - tried to get rid of the popup dialog which warns about unsigned jars using + * -Declipse.p2.unsignedPolicy=allow but this does not work due to + * https://bugs.eclipse.org/bugs/show_bug.cgi?id=391399, so the only solution + * is to sign the jars with an official certificate. + * + * @see http://wiki.eclipse.org/Equinox/p2/Adding_Self-Update_to_an_RCP_Application + * @see http://bugs.eclipse.org/281226 + * @see http://www.vogella.com/tutorials/EclipseP2Update/article.html + */ +public class P2Util { + + //private static String LOCAL_UPDATE_SITE = "file:///home/cmathew/Development/EDIT/taxeditor/eu.etaxonomy.taxeditor/target/repository/"; + private static String EDIT_NIGHTLY_UPDATE_SITE = "http://cybertaxonomy.eu/download/taxeditor/update/nightly/"; + private static String EDIT_STABLE_UPDATE_SITE = "http://cybertaxonomy.eu/download/taxeditor/update/stable/"; + + public static void setUpdateRepositories(UpdateOperation operation) throws URISyntaxException { + String updateSite = EDIT_NIGHTLY_UPDATE_SITE; + if(ApplicationUtil.isStable()) { + updateSite = EDIT_STABLE_UPDATE_SITE; + } + operation.getProvisioningContext().setMetadataRepositories(new URI[]{new URI(updateSite)}); + operation.getProvisioningContext().setArtifactRepositories(new URI[]{new URI(updateSite)}); + } + /** + * + * + */ + public static void checkForUpdates() { + // the main job which performs the update + Job updateJob = new Job("Update Job") { + @Override + public IStatus run(IProgressMonitor monitor) { + return doCheckForUpdates(monitor); + } + }; + updateJob.schedule(); + } + + /** + * @param monitor + * @return + */ + private static IStatus doCheckForUpdates(IProgressMonitor monitor) { + + BundleContext bundleContext = TaxonomicEditorPlugin.getContext(); + ServiceReference reference = bundleContext.getServiceReference(IProvisioningAgent.SERVICE_NAME); + if (reference == null) { + IStatus errorStatus = new Status(IStatus.ERROR, TaxonomicEditorPlugin.PLUGIN_ID, + "No provisioning agent found. This application is not set up for updates."); + return errorStatus; + } + + final IProvisioningAgent agent = (IProvisioningAgent) bundleContext.getService(reference); + IStatus updateStatus; + try { + updateStatus = P2Util.checkForUpdates(agent, monitor); + MessagingUtils.info(updateStatus); + } finally { + bundleContext.ungetService(reference); + } + return updateStatus; + } + + /** + * @param agent + * @param monitor + * @return + * @throws OperationCanceledException + */ + static IStatus checkForUpdates(IProvisioningAgent agent, final IProgressMonitor monitor) { + ProvisioningSession session = new ProvisioningSession(agent); + // the default update operation looks for updates to the currently + // running profile, using the default profile root marker. To change + // which installable units are being updated, use the more detailed + // constructors. + final UpdateOperation operation = new UpdateOperation(session); + try { + setUpdateRepositories(operation); + } catch (URISyntaxException e) { + MessagingUtils.errorDialog("Invalid update site URI", + operation, + "The update site URI has an invalid syntax", + TaxonomicEditorPlugin.PLUGIN_ID, + e, + false); + return null; + } + + final IStatus status = operation.resolveModal(monitor); + + if (status.getCode() == UpdateOperation.STATUS_NOTHING_TO_UPDATE) { + return status; + } + + if (status.isOK() && status.getSeverity() != IStatus.ERROR) { + // We need this block of code to be in async execution + // since the confirm dialogs work only on the UI thread + Display.getDefault().asyncExec(new Runnable() { + @Override + public void run() { + String updates = ""; + Update[] possibleUpdates = operation + .getPossibleUpdates(); + for (Update update : possibleUpdates) { + updates += update + "\n"; + } + + boolean doInstall = MessagingUtils.confirmDialog("Updates available", "Do you want to install the available updates ?"); + // We may need to think whether we still run in async mode once + // the user agrees to update. Maybe be reasonable to change to blocking + // from this point until the update is complete. + + // More complex status handling might include showing the user what + // updates are available if there are multiples, differentiating + // patches vs. updates, etc. In this example, we simply update as + // suggested by the operation. + if(doInstall) { + ProvisioningJob provisioningJob = operation.getProvisioningJob(monitor); + if (provisioningJob == null) { + MessagingUtils.messageDialog("Error in performing update", + operation, + "ProvisioningJob could not be created." + System.getProperty("line.separator") + + "Either this application does not support p2 software installation or this application has been launched from within the Eclipse IDE", + null, + false); + + } else { + // register a job change listener to track + // installation progress and notify user upon success + provisioningJob + .addJobChangeListener(new JobChangeAdapter() { + @Override + public void done(IJobChangeEvent event) { + if (event.getResult().isOK()) { + // We need this block of code to be in async execution + // since the confirm dialogs work only on the UI thread + Display.getDefault().asyncExec(new Runnable() { + @Override + public void run() { + boolean restart = MessagingUtils.confirmDialog( + "Updates installed, restart?", + "Updates have been installed successfully, do you want to restart?"); + if (restart) { + PlatformUI.getWorkbench().restart(); + } + } + }); + } + super.done(event); + } + }); + provisioningJob.schedule(); + } + } + } + }); + } + return status; + } +} diff --git a/eu.etaxonomy.taxeditor.application/src/main/java/eu/etaxonomy/taxeditor/update/PreloadingRepositoryHandler.java b/eu.etaxonomy.taxeditor.application/src/main/java/eu/etaxonomy/taxeditor/update/PreloadingRepositoryHandler.java new file mode 100644 index 000000000..716482c93 --- /dev/null +++ b/eu.etaxonomy.taxeditor.application/src/main/java/eu/etaxonomy/taxeditor/update/PreloadingRepositoryHandler.java @@ -0,0 +1,104 @@ +/******************************************************************************* + * Copyright (c) 2008, 2009 IBM Corporation and others. + * 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package eu.etaxonomy.taxeditor.update; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.runtime.jobs.IJobChangeEvent; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.core.runtime.jobs.JobChangeAdapter; +import org.eclipse.equinox.p2.ui.LoadMetadataRepositoryJob; +import org.eclipse.equinox.p2.ui.ProvisioningUI; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.PlatformUI; + +/** + * PreloadingRepositoryHandler provides background loading of + * repositories before executing the provisioning handler. + * + * @since 3.5 + */ +abstract class PreloadingRepositoryHandler extends AbstractHandler { + + /** + * The constructor. + */ + public PreloadingRepositoryHandler() { + // constructor + } + + /** + * Execute the command. + */ + public Object execute(ExecutionEvent event) { + doExecuteAndLoad(); + return null; + } + + void doExecuteAndLoad() { + if (preloadRepositories()) { + //cancel any load that is already running + Job.getJobManager().cancel(LoadMetadataRepositoryJob.LOAD_FAMILY); + final LoadMetadataRepositoryJob loadJob = new LoadMetadataRepositoryJob(getProvisioningUI()); + setLoadJobProperties(loadJob); + if (waitForPreload()) { + loadJob.addJobChangeListener(new JobChangeAdapter() { + public void done(IJobChangeEvent event) { + if (PlatformUI.isWorkbenchRunning()) + if (event.getResult().isOK()) { + PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() { + public void run() { + doExecute(loadJob); + } + }); + } + } + }); + loadJob.setUser(true); + loadJob.schedule(); + + } else { + loadJob.setSystem(true); + loadJob.setUser(false); + loadJob.schedule(); + doExecute(null); + } + } else { + doExecute(null); + } + } + + protected abstract void doExecute(LoadMetadataRepositoryJob job); + + protected boolean preloadRepositories() { + return true; + } + + protected boolean waitForPreload() { + return true; + } + + protected void setLoadJobProperties(Job loadJob) { + loadJob.setProperty(LoadMetadataRepositoryJob.ACCUMULATE_LOAD_ERRORS, Boolean.toString(true)); + } + + protected ProvisioningUI getProvisioningUI() { + return ProvisioningUI.getDefaultUI(); + } + + /** + * Return a shell appropriate for parenting dialogs of this handler. + * @return a Shell + */ + protected Shell getShell() { + return PlatformUI.getWorkbench().getModalDialogShellProvider().getShell(); + } +} diff --git a/eu.etaxonomy.taxeditor.application/src/main/java/eu/etaxonomy/taxeditor/update/UpdateHandler.java b/eu.etaxonomy.taxeditor.application/src/main/java/eu/etaxonomy/taxeditor/update/UpdateHandler.java new file mode 100644 index 000000000..27db567c5 --- /dev/null +++ b/eu.etaxonomy.taxeditor.application/src/main/java/eu/etaxonomy/taxeditor/update/UpdateHandler.java @@ -0,0 +1,77 @@ +/******************************************************************************* + * Copyright (c) 2007, 2009 IBM Corporation and others. + * 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package eu.etaxonomy.taxeditor.update; + +import java.net.URISyntaxException; + +import org.eclipse.equinox.internal.p2.ui.dialogs.UpdateSingleIUWizard; +import org.eclipse.equinox.p2.operations.RepositoryTracker; +import org.eclipse.equinox.p2.operations.UpdateOperation; +import org.eclipse.equinox.p2.ui.LoadMetadataRepositoryJob; +import org.eclipse.jface.wizard.WizardDialog; + +import eu.etaxonomy.taxeditor.TaxonomicEditorPlugin; +import eu.etaxonomy.taxeditor.model.MessagingUtils; + +/** + * UpdateHandler invokes the check for updates UI + * + * @since 3.4 + */ +public class UpdateHandler extends PreloadingRepositoryHandler { + + boolean hasNoRepos = false; + + @Override + protected void doExecute(LoadMetadataRepositoryJob job) { +// if (hasNoRepos) { +// return; +// } + UpdateOperation operation = getProvisioningUI().getUpdateOperation(null, null); + try { + P2Util.setUpdateRepositories(operation); + } catch (URISyntaxException e) { + MessagingUtils.errorDialog("Invalid update site URI", + operation, + "The update site URI has an invalid syntax", + TaxonomicEditorPlugin.PLUGIN_ID, + e, + false); + return; + } + + // check for updates + operation.resolveModal(null); + if (getProvisioningUI().getPolicy().continueWorkingWithOperation(operation, getShell())) { + if (UpdateSingleIUWizard.validFor(operation)) { + // Special case for only updating a single root + UpdateSingleIUWizard wizard = new UpdateSingleIUWizard(getProvisioningUI(), operation); + WizardDialog dialog = new WizardDialog(getShell(), wizard); + dialog.create(); + dialog.open(); + } else { + // Open the normal version of the update wizard + getProvisioningUI().openUpdateWizard(false, operation, job); + } + } + } + + @Override + protected boolean preloadRepositories() { + hasNoRepos = false; + RepositoryTracker repoMan = getProvisioningUI().getRepositoryTracker(); + if (repoMan.getKnownRepositories(getProvisioningUI().getSession()).length == 0) { + hasNoRepos = true; + return false; + } + return super.preloadRepositories(); + } +}