X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.project%2Fsrc%2Forg%2Fsimantics%2Fproject%2Fmanagement%2Finstall%2FInstallUpdateProductOperation.java;fp=bundles%2Forg.simantics.project%2Fsrc%2Forg%2Fsimantics%2Fproject%2Fmanagement%2Finstall%2FInstallUpdateProductOperation.java;h=1a53276a7f088adb1c84c64d8ebcefe5c0cb73b9;hp=6e8b45d37547807b67a54ec486d385720661142e;hb=0ae2b770234dfc3cbb18bd38f324125cf0faca07;hpb=24e2b34260f219f0d1644ca7a138894980e25b14 diff --git a/bundles/org.simantics.project/src/org/simantics/project/management/install/InstallUpdateProductOperation.java b/bundles/org.simantics.project/src/org/simantics/project/management/install/InstallUpdateProductOperation.java index 6e8b45d37..1a53276a7 100644 --- a/bundles/org.simantics.project/src/org/simantics/project/management/install/InstallUpdateProductOperation.java +++ b/bundles/org.simantics.project/src/org/simantics/project/management/install/InstallUpdateProductOperation.java @@ -1,280 +1,280 @@ -/******************************************************************************* - * Copyright (c) 2007, 2010 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 - * Code 9 - ongoing development - * Sonatype, Inc. - ongoing development - *******************************************************************************/ -package org.simantics.project.management.install; - -import java.net.URI; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; - -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.SubMonitor; -import org.eclipse.equinox.internal.p2.core.helpers.ServiceHelper; -import org.eclipse.equinox.internal.p2.director.ProfileChangeRequest; -import org.eclipse.equinox.internal.provisional.p2.director.IDirector; -import org.eclipse.equinox.internal.provisional.p2.installer.IInstallOperation; -import org.eclipse.equinox.internal.provisional.p2.installer.InstallDescription; -import org.eclipse.equinox.p2.core.IProvisioningAgent; -import org.eclipse.equinox.p2.core.ProvisionException; -import org.eclipse.equinox.p2.engine.IProfile; -import org.eclipse.equinox.p2.engine.IProfileRegistry; -import org.eclipse.equinox.p2.metadata.IInstallableUnit; -import org.eclipse.equinox.p2.metadata.IVersionedId; -import org.eclipse.equinox.p2.metadata.Version; -import org.eclipse.equinox.p2.metadata.VersionRange; -import org.eclipse.equinox.p2.query.IQuery; -import org.eclipse.equinox.p2.query.IQueryResult; -import org.eclipse.equinox.p2.query.QueryUtil; -import org.eclipse.equinox.p2.repository.artifact.IArtifactRepositoryManager; -import org.eclipse.equinox.p2.repository.metadata.IMetadataRepositoryManager; -import org.eclipse.osgi.service.environment.EnvironmentInfo; -import org.eclipse.osgi.util.NLS; -import org.simantics.project.internal.Activator; - -/** - * This operation performs installation or update of an Eclipse-based product. - */ -@SuppressWarnings("restriction") -public class InstallUpdateProductOperation implements IInstallOperation { - - private IArtifactRepositoryManager artifactRepoMan; - private IProvisioningAgent agent; - private IDirector director; - private final InstallDescription installDescription; - private boolean isInstall = true; - private IMetadataRepositoryManager metadataRepoMan; - private IProfileRegistry profileRegistry; - private IStatus result; - - public InstallUpdateProductOperation(IProvisioningAgent agent, InstallDescription description) { - this.agent = agent; - this.installDescription = description; - } - - /** - * Determine what top level installable units should be installed by the director - */ - private Collection computeUnitsToInstall() throws CoreException { - ArrayList units = new ArrayList(); - IVersionedId roots[] = installDescription.getRoots(); - for (int i = 0; i < roots.length; i++) { - IVersionedId root = roots[i]; - IInstallableUnit iu = findUnit(root); - if (iu != null) - units.add(iu); - } - return units; - } - - /** - * This profile is being updated; return the units to uninstall from the profile. - */ - private IQueryResult computeUnitsToUninstall(IProfile p) { - return p.query(QueryUtil.createIUAnyQuery(), null); - } - - /** - * Create and return the profile into which units will be installed. - */ - private IProfile createProfile() throws ProvisionException { - IProfile profile = getProfile(); - if (profile == null) { - Map properties = new HashMap(); - properties.put(IProfile.PROP_INSTALL_FOLDER, installDescription.getInstallLocation().toString()); - EnvironmentInfo info = (EnvironmentInfo) ServiceHelper.getService(Activator.getDefault().getBundle().getBundleContext(), EnvironmentInfo.class.getName()); - String env = "osgi.os=" + info.getOS() + ",osgi.ws=" + info.getWS() + ",osgi.arch=" + info.getOSArch(); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - properties.put(IProfile.PROP_ENVIRONMENTS, env); - properties.put(IProfile.PROP_NAME, installDescription.getProductName()); - properties.putAll(installDescription.getProfileProperties()); - IPath location = installDescription.getBundleLocation(); - if (location != null) - properties.put(IProfile.PROP_CACHE, location.toOSString()); - profile = profileRegistry.addProfile(getProfileId(), properties); - } - return profile; - } - - /** - * Performs the actual product install or update. - */ - private void doInstall(SubMonitor monitor) throws CoreException { - prepareMetadataRepositories(); - prepareArtifactRepositories(); - IProfile p = createProfile(); - Collection toInstall = computeUnitsToInstall(); - monitor.worked(5); - - IStatus s; - ProfileChangeRequest request = new ProfileChangeRequest(p); - if (isInstall) { - monitor.setTaskName(NLS.bind("Installing", installDescription.getProductName())); - request.addAll(toInstall); - s = director.provision(request, null, monitor.newChild(90)); - } else { - monitor.setTaskName(NLS.bind("Updating", installDescription.getProductName())); - IQueryResult toUninstall = computeUnitsToUninstall(p); - request.removeAll(toUninstall.toUnmodifiableSet()); - request.addAll(toInstall); - s = director.provision(request, null, monitor.newChild(90)); - } - if (!s.isOK()) - throw new CoreException(s); - } - - /** - * Returns an exception of severity error with the given error message. - */ - private CoreException fail(String message) { - return fail(message, null); - } - - /** - * Returns an exception of severity error with the given error message. - */ - private CoreException fail(String message, Throwable throwable) { - return new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, message, throwable)); - } - - /** - * Finds and returns the installable unit with the given id, and optionally the - * given version. - */ - private IInstallableUnit findUnit(IVersionedId spec) throws CoreException { - String id = spec.getId(); - if (id == null) - throw fail("No id"); - Version version = spec.getVersion(); - VersionRange range = VersionRange.emptyRange; - if (version != null && !version.equals(Version.emptyVersion)) - range = new VersionRange(version, true, version, true); - IQuery query = QueryUtil.createIUQuery(id, range); - Iterator matches = metadataRepoMan.query(query, null).iterator(); - // pick the newest match - IInstallableUnit newest = null; - while (matches.hasNext()) { - IInstallableUnit candidate = matches.next(); - if (newest == null || (newest.getVersion().compareTo(candidate.getVersion()) < 0)) - newest = candidate; - } - if (newest == null) - throw fail("IU not found " + id); - return newest; - } - - /** - * Returns the profile being installed into. - */ - private IProfile getProfile() { - return profileRegistry.getProfile(getProfileId()); - } - - /** - * Returns the id of the profile to use for install/update based on this operation's install description. - */ - private String getProfileId() { - IPath location = installDescription.getInstallLocation(); - if (location != null) - return location.toString(); - return installDescription.getProductName(); - } - - /** - * Returns the result of the install operation, or null if - * no install operation has been run. - */ - public IStatus getResult() { - return result; - } - - private Object getService(String name) throws CoreException { - Object service = agent.getService(name); - if (service == null) - throw fail("No service " + name); - return service; - } - - /* (non-Javadoc) - * @see org.eclipse.equinox.internal.provisional.p2.installer.IInstallOperation#install(org.eclipse.core.runtime.IProgressMonitor) - */ - public IStatus install(IProgressMonitor pm) { - SubMonitor monitor = SubMonitor.convert(pm, "Preparing", 100); - try { - try { - preInstall(); - isInstall = getProfile() == null; - doInstall(monitor); - result = new Status(IStatus.OK, Activator.PLUGIN_ID, isInstall ? "Install Complete" : "Update Complete", null); - monitor.setTaskName("Cleanup"); - } finally { - postInstall(); - } - } catch (CoreException e) { - result = e.getStatus(); - } finally { - monitor.done(); - } - return result; - } - - /** - * Returns whether this operation represents the product being installed - * for the first time, in a new profile. - */ - public boolean isFirstInstall() { - return isInstall; - } - - private void postInstall() { - //nothing to do - } - - private void preInstall() throws CoreException { - //obtain required services - director = (IDirector) getService(IDirector.SERVICE_NAME); - metadataRepoMan = (IMetadataRepositoryManager) getService(IMetadataRepositoryManager.SERVICE_NAME); - artifactRepoMan = (IArtifactRepositoryManager) getService(IArtifactRepositoryManager.SERVICE_NAME); - profileRegistry = (IProfileRegistry) getService(IProfileRegistry.SERVICE_NAME); - } - - private void prepareArtifactRepositories() throws ProvisionException { - URI[] repos = installDescription.getArtifactRepositories(); - if (repos == null) - return; - - // Repositories must be registered before they are loaded - // This is to avoid them being possibly overridden with the configuration as a referenced repository - for (int i = 0; i < repos.length; i++) { - artifactRepoMan.addRepository(repos[i]); - artifactRepoMan.loadRepository(repos[i], null); - } - } - - private void prepareMetadataRepositories() throws ProvisionException { - URI[] repos = installDescription.getMetadataRepositories(); - if (repos == null) - return; - - // Repositories must be registered before they are loaded - // This is to avoid them being possibly overridden with the configuration as a referenced repository - for (int i = 0; i < repos.length; i++) { - metadataRepoMan.addRepository(repos[i]); - metadataRepoMan.loadRepository(repos[i], null); - } - } -} +/******************************************************************************* + * Copyright (c) 2007, 2010 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 + * Code 9 - ongoing development + * Sonatype, Inc. - ongoing development + *******************************************************************************/ +package org.simantics.project.management.install; + +import java.net.URI; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.SubMonitor; +import org.eclipse.equinox.internal.p2.core.helpers.ServiceHelper; +import org.eclipse.equinox.internal.p2.director.ProfileChangeRequest; +import org.eclipse.equinox.internal.provisional.p2.director.IDirector; +import org.eclipse.equinox.internal.provisional.p2.installer.IInstallOperation; +import org.eclipse.equinox.internal.provisional.p2.installer.InstallDescription; +import org.eclipse.equinox.p2.core.IProvisioningAgent; +import org.eclipse.equinox.p2.core.ProvisionException; +import org.eclipse.equinox.p2.engine.IProfile; +import org.eclipse.equinox.p2.engine.IProfileRegistry; +import org.eclipse.equinox.p2.metadata.IInstallableUnit; +import org.eclipse.equinox.p2.metadata.IVersionedId; +import org.eclipse.equinox.p2.metadata.Version; +import org.eclipse.equinox.p2.metadata.VersionRange; +import org.eclipse.equinox.p2.query.IQuery; +import org.eclipse.equinox.p2.query.IQueryResult; +import org.eclipse.equinox.p2.query.QueryUtil; +import org.eclipse.equinox.p2.repository.artifact.IArtifactRepositoryManager; +import org.eclipse.equinox.p2.repository.metadata.IMetadataRepositoryManager; +import org.eclipse.osgi.service.environment.EnvironmentInfo; +import org.eclipse.osgi.util.NLS; +import org.simantics.project.internal.Activator; + +/** + * This operation performs installation or update of an Eclipse-based product. + */ +@SuppressWarnings("restriction") +public class InstallUpdateProductOperation implements IInstallOperation { + + private IArtifactRepositoryManager artifactRepoMan; + private IProvisioningAgent agent; + private IDirector director; + private final InstallDescription installDescription; + private boolean isInstall = true; + private IMetadataRepositoryManager metadataRepoMan; + private IProfileRegistry profileRegistry; + private IStatus result; + + public InstallUpdateProductOperation(IProvisioningAgent agent, InstallDescription description) { + this.agent = agent; + this.installDescription = description; + } + + /** + * Determine what top level installable units should be installed by the director + */ + private Collection computeUnitsToInstall() throws CoreException { + ArrayList units = new ArrayList(); + IVersionedId roots[] = installDescription.getRoots(); + for (int i = 0; i < roots.length; i++) { + IVersionedId root = roots[i]; + IInstallableUnit iu = findUnit(root); + if (iu != null) + units.add(iu); + } + return units; + } + + /** + * This profile is being updated; return the units to uninstall from the profile. + */ + private IQueryResult computeUnitsToUninstall(IProfile p) { + return p.query(QueryUtil.createIUAnyQuery(), null); + } + + /** + * Create and return the profile into which units will be installed. + */ + private IProfile createProfile() throws ProvisionException { + IProfile profile = getProfile(); + if (profile == null) { + Map properties = new HashMap(); + properties.put(IProfile.PROP_INSTALL_FOLDER, installDescription.getInstallLocation().toString()); + EnvironmentInfo info = (EnvironmentInfo) ServiceHelper.getService(Activator.getDefault().getBundle().getBundleContext(), EnvironmentInfo.class.getName()); + String env = "osgi.os=" + info.getOS() + ",osgi.ws=" + info.getWS() + ",osgi.arch=" + info.getOSArch(); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + properties.put(IProfile.PROP_ENVIRONMENTS, env); + properties.put(IProfile.PROP_NAME, installDescription.getProductName()); + properties.putAll(installDescription.getProfileProperties()); + IPath location = installDescription.getBundleLocation(); + if (location != null) + properties.put(IProfile.PROP_CACHE, location.toOSString()); + profile = profileRegistry.addProfile(getProfileId(), properties); + } + return profile; + } + + /** + * Performs the actual product install or update. + */ + private void doInstall(SubMonitor monitor) throws CoreException { + prepareMetadataRepositories(); + prepareArtifactRepositories(); + IProfile p = createProfile(); + Collection toInstall = computeUnitsToInstall(); + monitor.worked(5); + + IStatus s; + ProfileChangeRequest request = new ProfileChangeRequest(p); + if (isInstall) { + monitor.setTaskName(NLS.bind("Installing", installDescription.getProductName())); + request.addAll(toInstall); + s = director.provision(request, null, monitor.newChild(90)); + } else { + monitor.setTaskName(NLS.bind("Updating", installDescription.getProductName())); + IQueryResult toUninstall = computeUnitsToUninstall(p); + request.removeAll(toUninstall.toUnmodifiableSet()); + request.addAll(toInstall); + s = director.provision(request, null, monitor.newChild(90)); + } + if (!s.isOK()) + throw new CoreException(s); + } + + /** + * Returns an exception of severity error with the given error message. + */ + private CoreException fail(String message) { + return fail(message, null); + } + + /** + * Returns an exception of severity error with the given error message. + */ + private CoreException fail(String message, Throwable throwable) { + return new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, message, throwable)); + } + + /** + * Finds and returns the installable unit with the given id, and optionally the + * given version. + */ + private IInstallableUnit findUnit(IVersionedId spec) throws CoreException { + String id = spec.getId(); + if (id == null) + throw fail("No id"); + Version version = spec.getVersion(); + VersionRange range = VersionRange.emptyRange; + if (version != null && !version.equals(Version.emptyVersion)) + range = new VersionRange(version, true, version, true); + IQuery query = QueryUtil.createIUQuery(id, range); + Iterator matches = metadataRepoMan.query(query, null).iterator(); + // pick the newest match + IInstallableUnit newest = null; + while (matches.hasNext()) { + IInstallableUnit candidate = matches.next(); + if (newest == null || (newest.getVersion().compareTo(candidate.getVersion()) < 0)) + newest = candidate; + } + if (newest == null) + throw fail("IU not found " + id); + return newest; + } + + /** + * Returns the profile being installed into. + */ + private IProfile getProfile() { + return profileRegistry.getProfile(getProfileId()); + } + + /** + * Returns the id of the profile to use for install/update based on this operation's install description. + */ + private String getProfileId() { + IPath location = installDescription.getInstallLocation(); + if (location != null) + return location.toString(); + return installDescription.getProductName(); + } + + /** + * Returns the result of the install operation, or null if + * no install operation has been run. + */ + public IStatus getResult() { + return result; + } + + private Object getService(String name) throws CoreException { + Object service = agent.getService(name); + if (service == null) + throw fail("No service " + name); + return service; + } + + /* (non-Javadoc) + * @see org.eclipse.equinox.internal.provisional.p2.installer.IInstallOperation#install(org.eclipse.core.runtime.IProgressMonitor) + */ + public IStatus install(IProgressMonitor pm) { + SubMonitor monitor = SubMonitor.convert(pm, "Preparing", 100); + try { + try { + preInstall(); + isInstall = getProfile() == null; + doInstall(monitor); + result = new Status(IStatus.OK, Activator.PLUGIN_ID, isInstall ? "Install Complete" : "Update Complete", null); + monitor.setTaskName("Cleanup"); + } finally { + postInstall(); + } + } catch (CoreException e) { + result = e.getStatus(); + } finally { + monitor.done(); + } + return result; + } + + /** + * Returns whether this operation represents the product being installed + * for the first time, in a new profile. + */ + public boolean isFirstInstall() { + return isInstall; + } + + private void postInstall() { + //nothing to do + } + + private void preInstall() throws CoreException { + //obtain required services + director = (IDirector) getService(IDirector.SERVICE_NAME); + metadataRepoMan = (IMetadataRepositoryManager) getService(IMetadataRepositoryManager.SERVICE_NAME); + artifactRepoMan = (IArtifactRepositoryManager) getService(IArtifactRepositoryManager.SERVICE_NAME); + profileRegistry = (IProfileRegistry) getService(IProfileRegistry.SERVICE_NAME); + } + + private void prepareArtifactRepositories() throws ProvisionException { + URI[] repos = installDescription.getArtifactRepositories(); + if (repos == null) + return; + + // Repositories must be registered before they are loaded + // This is to avoid them being possibly overridden with the configuration as a referenced repository + for (int i = 0; i < repos.length; i++) { + artifactRepoMan.addRepository(repos[i]); + artifactRepoMan.loadRepository(repos[i], null); + } + } + + private void prepareMetadataRepositories() throws ProvisionException { + URI[] repos = installDescription.getMetadataRepositories(); + if (repos == null) + return; + + // Repositories must be registered before they are loaded + // This is to avoid them being possibly overridden with the configuration as a referenced repository + for (int i = 0; i < repos.length; i++) { + metadataRepoMan.addRepository(repos[i]); + metadataRepoMan.loadRepository(repos[i], null); + } + } +}