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:///path/.../to/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_SNAPSHOT_UPDATE_SITE
= "http://cybertaxonomy.eu/download/taxeditor/update/snapshot/";
50 private static String EDIT_STABLE_UPDATE_SITE
= "http://cybertaxonomy.eu/download/taxeditor/update/stable/";
52 public static void setUpdateRepositories(UpdateOperation operation
) throws URISyntaxException
{
53 String updateSite
= EDIT_NIGHTLY_UPDATE_SITE
;
54 if(ApplicationUtil
.isStable()) {
55 updateSite
= EDIT_STABLE_UPDATE_SITE
;
57 operation
.getProvisioningContext().setMetadataRepositories(new URI
[]{new URI(updateSite
)});
58 operation
.getProvisioningContext().setArtifactRepositories(new URI
[]{new URI(updateSite
)});
64 public static void checkForUpdates() {
65 // the main job which performs the update
66 Job updateJob
= new Job("Update Job") {
68 public IStatus
run(IProgressMonitor monitor
) {
69 return doCheckForUpdates(monitor
);
79 private static IStatus
doCheckForUpdates(IProgressMonitor monitor
) {
81 BundleContext bundleContext
= TaxonomicEditorPlugin
.getContext();
82 ServiceReference reference
= bundleContext
.getServiceReference(IProvisioningAgent
.SERVICE_NAME
);
83 if (reference
== null) {
84 IStatus errorStatus
= new Status(IStatus
.ERROR
, TaxonomicEditorPlugin
.PLUGIN_ID
,
85 "No provisioning agent found. This application is not set up for updates.");
89 final IProvisioningAgent agent
= (IProvisioningAgent
) bundleContext
.getService(reference
);
92 updateStatus
= P2Util
.checkForUpdates(agent
, monitor
);
93 MessagingUtils
.info(updateStatus
);
95 bundleContext
.ungetService(reference
);
104 * @throws OperationCanceledException
106 static IStatus
checkForUpdates(IProvisioningAgent agent
, final IProgressMonitor monitor
) {
107 ProvisioningSession session
= new ProvisioningSession(agent
);
108 // the default update operation looks for updates to the currently
109 // running profile, using the default profile root marker. To change
110 // which installable units are being updated, use the more detailed
112 final UpdateOperation operation
= new UpdateOperation(session
);
114 setUpdateRepositories(operation
);
115 } catch (URISyntaxException e
) {
116 MessagingUtils
.errorDialog("Invalid update site URI",
118 "The update site URI has an invalid syntax",
119 TaxonomicEditorPlugin
.PLUGIN_ID
,
125 final IStatus status
= operation
.resolveModal(monitor
);
127 if (status
.getCode() == UpdateOperation
.STATUS_NOTHING_TO_UPDATE
) {
131 if (status
.isOK() && status
.getSeverity() != IStatus
.ERROR
) {
132 // We need this block of code to be in async execution
133 // since the confirm dialogs work only on the UI thread
134 Display
.getDefault().asyncExec(new Runnable() {
138 Update
[] possibleUpdates
= operation
139 .getPossibleUpdates();
140 for (Update update
: possibleUpdates
) {
141 updates
+= update
+ "\n";
144 boolean doInstall
= MessagingUtils
.confirmDialog("Updates available", "Do you want to install the available updates ?");
145 // We may need to think whether we still run in async mode once
146 // the user agrees to update. Maybe be reasonable to change to blocking
147 // from this point until the update is complete.
149 // More complex status handling might include showing the user what
150 // updates are available if there are multiples, differentiating
151 // patches vs. updates, etc. In this example, we simply update as
152 // suggested by the operation.
154 ProvisioningJob provisioningJob
= operation
.getProvisioningJob(monitor
);
155 if (provisioningJob
== null) {
156 MessagingUtils
.messageDialog("Error in performing update",
158 "ProvisioningJob could not be created." + System
.getProperty("line.separator") +
159 "Either this application does not support p2 software installation or this application has been launched from within the Eclipse IDE",
164 // register a job change listener to track
165 // installation progress and notify user upon success
167 .addJobChangeListener(new JobChangeAdapter() {
169 public void done(IJobChangeEvent event
) {
170 if (event
.getResult().isOK()) {
171 // We need this block of code to be in async execution
172 // since the confirm dialogs work only on the UI thread
173 Display
.getDefault().asyncExec(new Runnable() {
176 boolean restart
= MessagingUtils
.confirmDialog(
177 "Updates installed, restart?",
178 "Updates have been installed successfully, do you want to restart?");
180 PlatformUI
.getWorkbench().restart();
188 provisioningJob
.schedule();