/***************************************************************************** * Copyright (c) 2006-2013, Cloudsmith Inc. * The code, documentation and other materials contained herein have been * licensed under the Eclipse Public License - v 1.0 by the copyright holder * listed above, as the Initial Contributor under such license. The text of * such license is available at www.eclipse.org. *****************************************************************************/ package org.eclipse.buckminster.installer; import java.io.File; import java.net.MalformedURLException; import java.net.URI; import java.net.URL; import java.util.Iterator; import org.eclipse.buckminster.cmdline.AbstractCommand; import org.eclipse.buckminster.cmdline.Headless; import org.eclipse.buckminster.cmdline.UsageException; import org.eclipse.buckminster.runtime.Buckminster; import org.eclipse.buckminster.runtime.BuckminsterException; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.SubMonitor; import org.eclipse.equinox.internal.p2.director.ProfileChangeRequest; import org.eclipse.equinox.p2.core.IProvisioningAgent; import org.eclipse.equinox.p2.core.IProvisioningAgentProvider; import org.eclipse.equinox.p2.engine.IEngine; import org.eclipse.equinox.p2.engine.IProfile; import org.eclipse.equinox.p2.engine.IProfileRegistry; import org.eclipse.equinox.p2.engine.IProvisioningPlan; import org.eclipse.equinox.p2.engine.ProvisioningContext; import org.eclipse.equinox.p2.metadata.IInstallableUnit; import org.eclipse.equinox.p2.metadata.Version; import org.eclipse.equinox.p2.planner.IPlanner; import org.eclipse.equinox.p2.query.IQuery; import org.eclipse.equinox.p2.query.IQueryResult; import org.eclipse.equinox.p2.query.IQueryable; import org.eclipse.equinox.p2.query.QueryUtil; import org.eclipse.equinox.p2.repository.metadata.IMetadataRepositoryManager; import org.eclipse.osgi.util.NLS; @SuppressWarnings("restriction") public class Install extends AbstractCommand { static ProvisioningContext createContext(IProvisioningAgent agent, URI site) { URI[] repoLocations = new URI[] { site }; ProvisioningContext context = new ProvisioningContext(agent); context.setArtifactRepositories(repoLocations); return context; } static IQueryResult<IInstallableUnit> getRootIUs(IProvisioningAgent agent, URI site, IProfile profile, String iuName, Version version, IProgressMonitor monitor) throws CoreException { if (!iuName.endsWith(".feature.group")) //$NON-NLS-1$ iuName = iuName + ".feature.group"; //$NON-NLS-1$ IQuery<IInstallableUnit> query = QueryUtil.createIUQuery(iuName, version); SubMonitor subMon = SubMonitor.convert(monitor, 100); IQueryable<IInstallableUnit> queryable; IMetadataRepositoryManager repoManager = (IMetadataRepositoryManager) agent.getService(IMetadataRepositoryManager.SERVICE_NAME); if (site == null) { queryable = repoManager; subMon.worked(80); } else queryable = repoManager.loadRepository(site, subMon.newChild(80)); IQueryResult<IInstallableUnit> roots = queryable.query(QueryUtil.createLatestQuery(query), subMon.newChild(10)); if (roots.isEmpty()) roots = profile.query(query, subMon.newChild(10)); if (roots.isEmpty()) throw BuckminsterException.fromMessage(NLS.bind(Messages.no_suitable_feature_version_found_matching_0, iuName)); return roots; } static URI normalizeToURI(String surl) { URL url; try { url = new URL(surl); } catch (MalformedURLException e) { try { url = new File(surl).toURI().toURL(); } catch (MalformedURLException e2) { throw new IllegalArgumentException(NLS.bind(Messages.URL_0_malformed, surl)); } } return URI.create(url.toString()); } static int planAndExecute(IProvisioningAgent agent, IProfile profile, ProfileChangeRequest request, ProvisioningContext context, IProgressMonitor monitor) throws CoreException { IPlanner planner = (IPlanner) agent.getService(IPlanner.SERVICE_NAME); IProvisioningPlan plan = planner.getProvisioningPlan(request, context, monitor); IStatus status = plan.getStatus(); if (status.getSeverity() == IStatus.CANCEL) return Headless.EXIT_FORCED; if (status.getSeverity() == IStatus.ERROR) throw new CoreException(status); IEngine engine = (IEngine) agent.getService(IEngine.SERVICE_NAME); status = engine.perform(plan, monitor); if (status.getSeverity() == IStatus.CANCEL) return Headless.EXIT_FORCED; if (status.getSeverity() == IStatus.ERROR) throw new CoreException(status); return Headless.EXIT_OK; } private URI site; private Version version; private String feature; @Override protected void handleUnparsed(String[] unparsed) throws Exception { int len = unparsed.length; if (len > 3) throw new UsageException(Messages.too_many_arguments); if (len > 0) { String p2Repos = unparsed[0]; if (p2Repos.endsWith("/headless-site.xml")) //$NON-NLS-1$ p2Repos = p2Repos.substring(0, p2Repos.length() - 18); else if (p2Repos.endsWith("/site.xml")) //$NON-NLS-1$ p2Repos = p2Repos.substring(0, p2Repos.length() - 9); site = normalizeToURI(p2Repos); } if (len > 1) feature = unparsed[1]; if (len > 2) version = Version.parseVersion(unparsed[2]); } @Override protected int run(IProgressMonitor monitor) throws Exception { if (site == null) throw new UsageException(Messages.no_site_provided); if (feature == null) throw new UsageException(Messages.no_feature_id_provided); Buckminster bucky = Buckminster.getDefault(); IProvisioningAgentProvider agentProvider = bucky.getService(IProvisioningAgentProvider.class); IProvisioningAgent agent = agentProvider.createAgent(null); String profileId = bucky.getBundle().getBundleContext().getProperty("eclipse.p2.profile"); //$NON-NLS-1$ if (profileId == null) { profileId = "Buckminster"; //$NON-NLS-1$ System.setProperty("eclipse.p2.profile", profileId); //$NON-NLS-1$ } IProfileRegistry profileRegistry = (IProfileRegistry) agent.getService(IProfileRegistry.SERVICE_NAME); try { IProfile profile = profileRegistry.getProfile(profileId); IQueryResult<IInstallableUnit> rootArr = getRootIUs(agent, site, profile, feature, version, monitor); // Add as root IU's to a request ProfileChangeRequest request = new ProfileChangeRequest(profile); for (Iterator<IInstallableUnit> iter = rootArr.iterator(); iter.hasNext();) request.setInstallableUnitProfileProperty(iter.next(), IProfile.PROP_PROFILE_ROOT_IU, Boolean.TRUE.toString()); request.addAll(rootArr.toUnmodifiableSet()); return planAndExecute(agent, profile, request, createContext(agent, site), monitor); } finally { agent.stop(); bucky.ungetService(agentProvider); } } }