/***************************************************************************** * 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.pde.internal.actor; import java.util.Collections; import java.util.Map; import org.eclipse.buckminster.core.CorePlugin; import org.eclipse.buckminster.core.TargetPlatform; import org.eclipse.buckminster.core.actor.AbstractActor; import org.eclipse.buckminster.core.actor.IActionContext; import org.eclipse.buckminster.core.actor.IPerformManager; import org.eclipse.buckminster.core.common.model.ExpandingProperties; import org.eclipse.buckminster.core.cspec.PathGroup; import org.eclipse.buckminster.core.cspec.model.Action; import org.eclipse.buckminster.core.cspec.model.Attribute; import org.eclipse.buckminster.core.cspec.model.CSpec; import org.eclipse.buckminster.core.cspec.model.ComponentIdentifier; import org.eclipse.buckminster.core.cspec.model.ComponentRequest; import org.eclipse.buckminster.core.ctype.IComponentType; import org.eclipse.buckminster.core.helpers.FilterUtils; import org.eclipse.buckminster.core.metadata.IResolution; import org.eclipse.buckminster.core.metadata.WorkspaceInfo; import org.eclipse.buckminster.core.metadata.model.IModelCache; import org.eclipse.buckminster.core.metadata.model.Resolution; import org.eclipse.buckminster.core.version.VersionHelper; import org.eclipse.buckminster.osgi.filter.Filter; import org.eclipse.buckminster.osgi.filter.FilterFactory; import org.eclipse.buckminster.pde.IPDEConstants; import org.eclipse.buckminster.pde.Messages; import org.eclipse.buckminster.runtime.BuckminsterException; import org.eclipse.buckminster.runtime.MonitorUtils; 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.Path; import org.eclipse.core.runtime.Status; import org.eclipse.osgi.service.resolver.BundleDescription; import org.eclipse.osgi.util.NLS; import org.eclipse.pde.core.plugin.IPluginModelBase; import org.eclipse.pde.core.plugin.PluginRegistry; import org.osgi.framework.InvalidSyntaxException; /** * @author Thomas Hallgren */ public class FragmentsActor extends AbstractActor { public static final String ID = "copyTargetFragments"; //$NON-NLS-1$ public static final String PROP_FRAGMENT_ATTRIBUTE = "fragment.attribute"; //$NON-NLS-1$ @Override public boolean isUpToDate(Action action, IModelCache ctx, long prerequisiteAge, long oldestTarget) throws CoreException { ComponentIdentifier cid = action.getCSpec().getComponentIdentifier(); IPath outputDir = action.getProductBase(); if (outputDir == null) throw BuckminsterException.fromMessage(NLS.bind(Messages.missing_product_base_in_0_actor, ID)); Map<String, ? extends Object> properties = ctx.getProperties(); outputDir = new Path(ExpandingProperties.expand(properties, outputDir.toPortableString(), 0)); IPluginModelBase plugin = PluginRegistry.findModel(cid.getName()); if (plugin == null) return true; BundleDescription bundle = plugin.getBundleDescription(); if (bundle == null) return true; BundleDescription[] fragments = bundle.getFragments(); if (fragments == null || fragments.length == 0) return true; int count = 0; for (BundleDescription fragment : fragments) { String fragmentName = fragment.getName(); if (fragmentName.contains(".compatibility") || fragmentName.endsWith(".test") || fragmentName.endsWith(".dummy")) //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ // // Compatibility fragments must be explicitly brought in using // a product or a feature // continue; ComponentRequest request = new ComponentRequest(fragmentName, IComponentType.OSGI_BUNDLE, VersionHelper.exactRange(fragment.getVersion())); String filterStr = fragment.getPlatformFilter(); if (filterStr != null) { try { Filter filter = FilterFactory.newInstance(fragment.getPlatformFilter()); filter = FilterUtils.replaceAttributeNames(filter, "osgi", TargetPlatform.TARGET_PREFIX); //$NON-NLS-1$ if (!filter.matches(properties)) continue; } catch (InvalidSyntaxException e) { throw BuckminsterException.wrap(e); } } IResolution res = WorkspaceInfo.getResolution(request, false); if (res == null) continue; count++; } if (count == 0) return true; String[] fragFiles = outputDir.toFile().list(); return (fragFiles != null && fragFiles.length >= count); } @Override protected IStatus internalPerform(IActionContext ctx, IProgressMonitor monitor) throws CoreException { ComponentIdentifier cid = ctx.getCSpec().getComponentIdentifier(); IPath outputDir = ctx.getAction().getProductBase(); if (outputDir == null) throw BuckminsterException.fromMessage(NLS.bind(Messages.missing_product_base_in_0_actor, ID)); Map<String, ? extends Object> properties = ctx.getProperties(); outputDir = new Path(ExpandingProperties.expand(properties, outputDir.toPortableString(), 0)); IPluginModelBase launcherPlugin = PluginRegistry.findModel(cid.getName()); if (launcherPlugin == null) { MonitorUtils.complete(monitor); return Status.OK_STATUS; } BundleDescription bundle = launcherPlugin.getBundleDescription(); if (bundle == null) { MonitorUtils.complete(monitor); return Status.OK_STATUS; } BundleDescription[] fragments = bundle.getFragments(); if (fragments == null || fragments.length == 0) { MonitorUtils.complete(monitor); return Status.OK_STATUS; } String fragmentAttribute = (String) properties.get(PROP_FRAGMENT_ATTRIBUTE); if (fragmentAttribute == null) fragmentAttribute = IPDEConstants.ATTRIBUTE_BUNDLE_JAR; monitor.beginTask(null, 100 + 100 * fragments.length); IPerformManager performManager = CorePlugin.getPerformManager(); try { for (BundleDescription fragment : fragments) { String fragmentName = fragment.getName(); if (fragmentName.contains(".compatibility")) //$NON-NLS-1$ // // Compatibility fragments must be explicitly brought in // using // a product or a feature // continue; ComponentRequest request = new ComponentRequest(fragmentName, IComponentType.OSGI_BUNDLE, VersionHelper.exactRange(fragment .getVersion())); String filterStr = fragment.getPlatformFilter(); if (filterStr != null) { try { Filter filter = FilterFactory.newInstance(fragment.getPlatformFilter()); filter = FilterUtils.replaceAttributeNames(filter, "osgi", TargetPlatform.TARGET_PREFIX); //$NON-NLS-1$ if (!filter.matches(properties)) continue; } catch (InvalidSyntaxException e) { throw BuckminsterException.wrap(e); } } Resolution res = WorkspaceInfo.getResolution(request, false); if (res == null) { MonitorUtils.worked(monitor, 100); continue; } // Obtain the bundle.jars attribute from the cspec. Make sure // the action is executed // (if it indeed is an action) // CSpec cspec = res.getCSpec(); Attribute bundleJar = cspec.getAttribute(fragmentAttribute); performManager.perform(Collections.singletonList(bundleJar), ctx.getGlobalContext(), MonitorUtils.subMonitor(monitor, 70)); // Copy the path groups to the given destination // PathGroup[] groups = bundleJar.getPathGroups(ctx, null); IProgressMonitor copyMon = MonitorUtils.subMonitor(monitor, 30); copyMon.beginTask(null, groups.length * 100); for (PathGroup pathGroup : groups) pathGroup.copyTo(outputDir, MonitorUtils.subMonitor(copyMon, 100)); copyMon.done(); } return Status.OK_STATUS; } finally { monitor.done(); } } }