| /******************************************************************************* |
| * Copyright (c) 2008, 2009 Code 9 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: |
| * Code 9 - initial API and implementation |
| * IBM - ongoing development |
| ******************************************************************************/ |
| package org.eclipse.equinox.p2.publisher.eclipse; |
| |
| import java.io.File; |
| import java.util.*; |
| import org.eclipse.core.runtime.*; |
| import org.eclipse.equinox.internal.p2.publisher.eclipse.ExecutablesDescriptor; |
| import org.eclipse.equinox.internal.provisional.p2.core.Version; |
| import org.eclipse.equinox.internal.provisional.p2.metadata.IInstallableUnit; |
| import org.eclipse.equinox.internal.provisional.p2.metadata.MetadataFactory; |
| import org.eclipse.equinox.internal.provisional.p2.metadata.MetadataFactory.InstallableUnitDescription; |
| import org.eclipse.equinox.p2.publisher.*; |
| import org.eclipse.equinox.p2.publisher.actions.VersionAdvice; |
| |
| /** |
| * Create IUs and CUs that represent the entire launcher for an application. This includes |
| * the executable, the launcher fragments as well as the CUs required to install and configure |
| * these elements. |
| */ |
| public class ApplicationLauncherAction extends AbstractPublisherAction { |
| |
| private String flavor; |
| private String[] configSpecs; |
| private File location; |
| private String executableName; |
| private Version version; |
| private String id; |
| |
| /** |
| * Returns the id of the top level IU published by this action for the given id and flavor. |
| * @param id the id of the application being published |
| * @param flavor the flavor being published |
| * @return the if for ius published by this action |
| */ |
| public static String computeIUId(String id, String flavor) { |
| return flavor + id + ".application"; //$NON-NLS-1$ |
| } |
| |
| public ApplicationLauncherAction(String id, Version version, String flavor, String executableName, File location, String[] configSpecs) { |
| this.flavor = flavor; |
| this.configSpecs = configSpecs; |
| this.id = id; |
| this.version = version; |
| this.executableName = executableName; |
| this.location = location; |
| } |
| |
| public IStatus perform(IPublisherInfo info, IPublisherResult results, IProgressMonitor monitor) { |
| // Create the basic actions and run them putting the IUs in a temporary result |
| Collection actions = createActions(info); |
| createAdvice(info, results); |
| IPublisherResult innerResult = new PublisherResult(); |
| MultiStatus finalStatus = new MultiStatus(ApplicationLauncherAction.class.getName(), 0, "publishing result", null); //$NON-NLS-1$ |
| for (Iterator i = actions.iterator(); i.hasNext();) { |
| if (monitor.isCanceled()) |
| return Status.CANCEL_STATUS; |
| finalStatus.merge(((IPublisherAction) i.next()).perform(info, innerResult, monitor)); |
| } |
| if (!finalStatus.isOK()) |
| return finalStatus; |
| // merge the IUs into the final result as non-roots and create a parent IU that captures them all |
| results.merge(innerResult, IPublisherResult.MERGE_ALL_NON_ROOT); |
| publishApplicationLauncherIU(innerResult.getIUs(null, IPublisherResult.ROOT), results); |
| return Status.OK_STATUS; |
| } |
| |
| /** |
| * Create advice needed by the actions related to and following this action |
| */ |
| private void createAdvice(IPublisherInfo info, IPublisherResult results) { |
| createLauncherAdvice(info, results); |
| } |
| |
| /** |
| * Create and register advice that will tell people what versions of the launcher bundle and |
| * fragments are in use in this particular result. |
| */ |
| private void createLauncherAdvice(IPublisherInfo info, IPublisherResult results) { |
| Collection ius = getIUs(results.getIUs(null, null), EquinoxLauncherCUAction.ORG_ECLIPSE_EQUINOX_LAUNCHER); |
| VersionAdvice advice = new VersionAdvice(); |
| boolean found = false; |
| for (Iterator i = ius.iterator(); i.hasNext();) { |
| IInstallableUnit iu = (IInstallableUnit) i.next(); |
| // skip over source bundles and fragments |
| // TODO should we use the source property here rather than magic name matching? |
| if (iu.getId().endsWith(".source") || iu.isFragment()) //$NON-NLS-1$ |
| continue; |
| advice.setVersion(IInstallableUnit.NAMESPACE_IU_ID, iu.getId(), iu.getVersion()); |
| found = true; |
| } |
| if (found) |
| info.addAdvice(advice); |
| } |
| |
| private Collection getIUs(Collection ius, String prefix) { |
| Set result = new HashSet(); |
| for (Iterator iterator = ius.iterator(); iterator.hasNext();) { |
| IInstallableUnit tmp = (IInstallableUnit) iterator.next(); |
| if (tmp.getId().startsWith(prefix)) |
| result.add(tmp); |
| } |
| return result; |
| } |
| |
| private void publishApplicationLauncherIU(Collection children, IPublisherResult result) { |
| InstallableUnitDescription descriptor = createParentIU(children, computeIUId(id, flavor), version); |
| descriptor.setSingleton(true); |
| IInstallableUnit rootIU = MetadataFactory.createInstallableUnit(descriptor); |
| if (rootIU == null) |
| return; |
| result.addIU(rootIU, IPublisherResult.ROOT); |
| } |
| |
| private Collection createActions(IPublisherInfo info) { |
| Collection actions = new ArrayList(); |
| actions.add(new EquinoxLauncherCUAction(flavor, configSpecs)); |
| actions.addAll(createExecutablesActions(configSpecs)); |
| return actions; |
| } |
| |
| protected Collection createExecutablesActions(String[] configSpecs) { |
| Collection actions = new ArrayList(configSpecs.length); |
| for (int i = 0; i < configSpecs.length; i++) { |
| ExecutablesDescriptor executables = computeExecutables(configSpecs[i]); |
| IPublisherAction action = new EquinoxExecutableAction(executables, configSpecs[i], id, version, flavor); |
| actions.add(action); |
| } |
| return actions; |
| } |
| |
| protected ExecutablesDescriptor computeExecutables(String configSpec) { |
| // See if we know about an executables feature then use it as the source |
| ExecutablesDescriptor result = ExecutablesDescriptor.createExecutablesFromFeature(location, configSpec); |
| if (result != null) |
| return result; |
| // otherwise, assume that we are running against an Eclipse install and do the default thing |
| String os = AbstractPublisherAction.parseConfigSpec(configSpec)[1]; |
| return ExecutablesDescriptor.createDescriptor(os, executableName, location); |
| } |
| } |