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
.p2
.core
.IProvisioningAgent
;
14 import org
.eclipse
.equinox
.p2
.operations
.ProvisioningJob
;
15 import org
.eclipse
.equinox
.p2
.operations
.ProvisioningSession
;
16 import org
.eclipse
.equinox
.p2
.operations
.Update
;
17 import org
.eclipse
.equinox
.p2
.operations
.UpdateOperation
;
18 import org
.eclipse
.swt
.widgets
.Display
;
19 import org
.eclipse
.ui
.PlatformUI
;
20 import org
.osgi
.framework
.BundleContext
;
21 import org
.osgi
.framework
.ServiceReference
;
23 import eu
.etaxonomy
.taxeditor
.ApplicationUtil
;
24 import eu
.etaxonomy
.taxeditor
.TaxonomicEditorPlugin
;
25 import eu
.etaxonomy
.taxeditor
.model
.MessagingUtils
;
28 * This class is a utility class for updating the editor from a p2 update site,
29 * greatly inspired by the links given below.
33 * - Allow configurable update sites
36 * - tried to get rid of the popup dialog which warns about unsigned jars using
37 * -Declipse.p2.unsignedPolicy=allow but this does not work due to
38 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=391399, so the only solution
39 * is to sign the jars with an official certificate.
41 * @see http://wiki.eclipse.org/Equinox/p2/Adding_Self-Update_to_an_RCP_Application
42 * @see http://bugs.eclipse.org/281226
43 * @see http://www.vogella.com/tutorials/EclipseP2Update/article.html
47 //private static String LOCAL_UPDATE_SITE = "file:///home/cmathew/Development/EDIT/taxeditor/eu.etaxonomy.taxeditor/target/repository/";
48 private static String EDIT_NIGHTLY_UPDATE_SITE
= "http://cybertaxonomy.eu/download/taxeditor/update/nightly/";
49 private static String EDIT_STABLE_UPDATE_SITE
= "http://cybertaxonomy.eu/download/taxeditor/update/stable/";
51 public static void setUpdateRepositories(UpdateOperation operation
) throws URISyntaxException
{
52 String updateSite
= EDIT_NIGHTLY_UPDATE_SITE
;
53 if(ApplicationUtil
.isStable()) {
54 updateSite
= EDIT_STABLE_UPDATE_SITE
;
56 operation
.getProvisioningContext().setMetadataRepositories(new URI
[]{new URI(updateSite
)});
57 operation
.getProvisioningContext().setArtifactRepositories(new URI
[]{new URI(updateSite
)});
63 public static void checkForUpdates() {
64 // the main job which performs the update
65 Job updateJob
= new Job("Update Job") {
67 public IStatus
run(IProgressMonitor monitor
) {
68 return doCheckForUpdates(monitor
);
78 private static IStatus
doCheckForUpdates(IProgressMonitor monitor
) {
80 BundleContext bundleContext
= TaxonomicEditorPlugin
.getContext();
81 ServiceReference reference
= bundleContext
.getServiceReference(IProvisioningAgent
.SERVICE_NAME
);
82 if (reference
== null) {
83 IStatus errorStatus
= new Status(IStatus
.ERROR
, TaxonomicEditorPlugin
.PLUGIN_ID
,
84 "No provisioning agent found. This application is not set up for updates.");
88 final IProvisioningAgent agent
= (IProvisioningAgent
) bundleContext
.getService(reference
);
91 updateStatus
= P2Util
.checkForUpdates(agent
, monitor
);
92 MessagingUtils
.info(updateStatus
);
94 bundleContext
.ungetService(reference
);
103 * @throws OperationCanceledException
105 static IStatus
checkForUpdates(IProvisioningAgent agent
, final IProgressMonitor monitor
) {
106 ProvisioningSession session
= new ProvisioningSession(agent
);
107 // the default update operation looks for updates to the currently
108 // running profile, using the default profile root marker. To change
109 // which installable units are being updated, use the more detailed
111 final UpdateOperation operation
= new UpdateOperation(session
);
113 setUpdateRepositories(operation
);
114 } catch (URISyntaxException e
) {
115 MessagingUtils
.errorDialog("Invalid update site URI",
117 "The update site URI has an invalid syntax",
118 TaxonomicEditorPlugin
.PLUGIN_ID
,
124 final IStatus status
= operation
.resolveModal(monitor
);
126 if (status
.getCode() == UpdateOperation
.STATUS_NOTHING_TO_UPDATE
) {
130 if (status
.isOK() && status
.getSeverity() != IStatus
.ERROR
) {
131 // We need this block of code to be in async execution
132 // since the confirm dialogs work only on the UI thread
133 Display
.getDefault().asyncExec(new Runnable() {
137 Update
[] possibleUpdates
= operation
138 .getPossibleUpdates();
139 for (Update update
: possibleUpdates
) {
140 updates
+= update
+ "\n";
143 boolean doInstall
= MessagingUtils
.confirmDialog("Updates available", "Do you want to install the available updates ?");
144 // We may need to think whether we still run in async mode once
145 // the user agrees to update. Maybe be reasonable to change to blocking
146 // from this point until the update is complete.
148 // More complex status handling might include showing the user what
149 // updates are available if there are multiples, differentiating
150 // patches vs. updates, etc. In this example, we simply update as
151 // suggested by the operation.
153 ProvisioningJob provisioningJob
= operation
.getProvisioningJob(monitor
);
154 if (provisioningJob
== null) {
155 MessagingUtils
.messageDialog("Error in performing update",
157 "ProvisioningJob could not be created." + System
.getProperty("line.separator") +
158 "Either this application does not support p2 software installation or this application has been launched from within the Eclipse IDE",
163 // register a job change listener to track
164 // installation progress and notify user upon success
166 .addJobChangeListener(new JobChangeAdapter() {
168 public void done(IJobChangeEvent event
) {
169 if (event
.getResult().isOK()) {
170 // We need this block of code to be in async execution
171 // since the confirm dialogs work only on the UI thread
172 Display
.getDefault().asyncExec(new Runnable() {
175 boolean restart
= MessagingUtils
.confirmDialog(
176 "Updates installed, restart?",
177 "Updates have been installed successfully, do you want to restart?");
179 PlatformUI
.getWorkbench().restart();
187 provisioningJob
.schedule();