1 package eu
.etaxonomy
.taxeditor
.update
;
4 import java
.net
.URISyntaxException
;
6 import org
.eclipse
.core
.runtime
.IProgressMonitor
;
7 import org
.eclipse
.core
.runtime
.IStatus
;
8 import org
.eclipse
.core
.runtime
.OperationCanceledException
;
9 import org
.eclipse
.core
.runtime
.Status
;
10 import org
.eclipse
.core
.runtime
.jobs
.IJobChangeEvent
;
11 import org
.eclipse
.core
.runtime
.jobs
.Job
;
12 import org
.eclipse
.core
.runtime
.jobs
.JobChangeAdapter
;
13 import org
.eclipse
.equinox
.internal
.p2
.ui
.model
.ElementUtils
;
14 import org
.eclipse
.equinox
.internal
.p2
.ui
.model
.MetadataRepositoryElement
;
15 import org
.eclipse
.equinox
.p2
.core
.IProvisioningAgent
;
16 import org
.eclipse
.equinox
.p2
.operations
.ProvisioningJob
;
17 import org
.eclipse
.equinox
.p2
.operations
.ProvisioningSession
;
18 import org
.eclipse
.equinox
.p2
.operations
.Update
;
19 import org
.eclipse
.equinox
.p2
.operations
.UpdateOperation
;
20 import org
.eclipse
.equinox
.p2
.ui
.ProvisioningUI
;
21 import org
.eclipse
.swt
.widgets
.Display
;
22 import org
.eclipse
.ui
.PlatformUI
;
23 import org
.osgi
.framework
.BundleContext
;
24 import org
.osgi
.framework
.ServiceReference
;
26 import eu
.etaxonomy
.taxeditor
.ApplicationUtil
;
27 import eu
.etaxonomy
.taxeditor
.TaxonomicEditorPlugin
;
28 import eu
.etaxonomy
.taxeditor
.model
.MessagingUtils
;
31 * This class is a utility class for updating the editor from a p2 update site,
32 * greatly inspired by the links given below.
36 * - Allow configurable update sites
39 * - tried to get rid of the popup dialog which warns about unsigned jars using
40 * -Declipse.p2.unsignedPolicy=allow but this does not work due to
41 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=391399, so the only solution
42 * is to sign the jars with an official certificate.
44 * @see http://wiki.eclipse.org/Equinox/p2/Adding_Self-Update_to_an_RCP_Application
45 * @see http://bugs.eclipse.org/281226
46 * @see http://www.vogella.com/tutorials/EclipseP2Update/article.html
50 //private static String LOCAL_UPDATE_SITE = "file:///path/.../to/Development/EDIT/taxeditor/eu.etaxonomy.taxeditor/target/repository/";
51 private static String EDIT_NIGHTLY_UPDATE_SITE
= "http://cybertaxonomy.eu/download/taxeditor/update/nightly/";
52 private static String EDIT_NIGHTLY_UPDATE_SITE_NAME
= "Taxonomic Editor Nightly";
54 private static String EDIT_SNAPSHOT_UPDATE_SITE
= "http://cybertaxonomy.eu/download/taxeditor/update/snapshot/";
55 private static String EDIT_SNAPSHOT_UPDATE_SITE_NAME
= "Taxonomic Editor Snapshot";
57 private static String EDIT_STABLE_UPDATE_SITE
= "http://cybertaxonomy.eu/download/taxeditor/update/stable/";
58 private static String EDIT_STABLE_UPDATE_SITE_NAME
= "Taxonomic Editor Stable";
60 @SuppressWarnings("restriction")
61 public static void setDefaultUpdateRepositories() {
62 String updateSite
= EDIT_NIGHTLY_UPDATE_SITE
;
63 String updateSiteName
= EDIT_NIGHTLY_UPDATE_SITE_NAME
;
65 if(ApplicationUtil
.isStable()) {
66 updateSite
= EDIT_STABLE_UPDATE_SITE
;
67 updateSiteName
= EDIT_STABLE_UPDATE_SITE_NAME
;
70 final MetadataRepositoryElement element
= new MetadataRepositoryElement(null, new URI(updateSite
), true);
71 element
.setNickname(updateSiteName
);
72 ElementUtils
.updateRepositoryUsingElements(ProvisioningUI
.getDefaultUI(),new MetadataRepositoryElement
[] {element
}, null);
73 } catch (URISyntaxException e
) {
74 MessagingUtils
.errorDialog("Invalid update site URI",
76 "The update site URI has an invalid syntax",
77 TaxonomicEditorPlugin
.PLUGIN_ID
,
87 public static void checkForUpdates() {
88 // the main job which performs the update
89 Job updateJob
= new Job("Update Job") {
91 public IStatus
run(IProgressMonitor monitor
) {
92 return doCheckForUpdates(monitor
);
102 private static IStatus
doCheckForUpdates(IProgressMonitor monitor
) {
104 BundleContext bundleContext
= TaxonomicEditorPlugin
.getContext();
105 ServiceReference reference
= bundleContext
.getServiceReference(IProvisioningAgent
.SERVICE_NAME
);
106 if (reference
== null) {
107 IStatus errorStatus
= new Status(IStatus
.ERROR
, TaxonomicEditorPlugin
.PLUGIN_ID
,
108 "No provisioning agent found. This application is not set up for updates.");
112 final IProvisioningAgent agent
= (IProvisioningAgent
) bundleContext
.getService(reference
);
113 IStatus updateStatus
;
115 updateStatus
= P2Util
.checkForUpdates(agent
, monitor
);
116 MessagingUtils
.info(updateStatus
);
118 bundleContext
.ungetService(reference
);
127 * @throws OperationCanceledException
129 static IStatus
checkForUpdates(IProvisioningAgent agent
, final IProgressMonitor monitor
) {
130 ProvisioningSession session
= new ProvisioningSession(agent
);
131 // the default update operation looks for updates to the currently
132 // running profile, using the default profile root marker. To change
133 // which installable units are being updated, use the more detailed
135 final UpdateOperation operation
= new UpdateOperation(session
);
137 // setUpdateRepositories(operation);
138 // } catch (URISyntaxException e) {
139 // MessagingUtils.errorDialog("Invalid update site URI",
141 // "The update site URI has an invalid syntax",
142 // TaxonomicEditorPlugin.PLUGIN_ID,
148 final IStatus status
= operation
.resolveModal(monitor
);
150 if (status
.getCode() == UpdateOperation
.STATUS_NOTHING_TO_UPDATE
) {
154 if (status
.isOK() && status
.getSeverity() != IStatus
.ERROR
) {
155 // We need this block of code to be in async execution
156 // since the confirm dialogs work only on the UI thread
157 Display
.getDefault().asyncExec(new Runnable() {
161 Update
[] possibleUpdates
= operation
162 .getPossibleUpdates();
163 for (Update update
: possibleUpdates
) {
164 updates
+= update
+ "\n";
167 boolean doInstall
= MessagingUtils
.confirmDialog("Updates available", "Do you want to install the available updates ?");
168 // We may need to think whether we still run in async mode once
169 // the user agrees to update. Maybe be reasonable to change to blocking
170 // from this point until the update is complete.
172 // More complex status handling might include showing the user what
173 // updates are available if there are multiples, differentiating
174 // patches vs. updates, etc. In this example, we simply update as
175 // suggested by the operation.
177 ProvisioningJob provisioningJob
= operation
.getProvisioningJob(monitor
);
178 if (provisioningJob
== null) {
179 MessagingUtils
.messageDialog("Error in performing update",
181 "ProvisioningJob could not be created." + System
.getProperty("line.separator") +
182 "Either this application does not support p2 software installation or this application has been launched from within the Eclipse IDE",
187 // register a job change listener to track
188 // installation progress and notify user upon success
190 .addJobChangeListener(new JobChangeAdapter() {
192 public void done(IJobChangeEvent event
) {
193 if (event
.getResult().isOK()) {
194 // We need this block of code to be in async execution
195 // since the confirm dialogs work only on the UI thread
196 Display
.getDefault().asyncExec(new Runnable() {
199 boolean restart
= MessagingUtils
.confirmDialog(
200 "Updates installed, restart?",
201 "Updates have been installed successfully, do you want to restart?");
203 PlatformUI
.getWorkbench().restart();
211 provisioningJob
.schedule();