| /******************************************************************************* |
| * Copyright (c) 2009 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 |
| *******************************************************************************/ |
| package org.eclipse.equinox.internal.p2.director; |
| |
| import java.util.*; |
| import org.eclipse.equinox.p2.metadata.*; |
| import org.eclipse.equinox.p2.query.QueryUtil; |
| |
| public class AttachmentHelper { |
| private static final IInstallableUnitFragment[] NO_FRAGMENTS = new IInstallableUnitFragment[0]; |
| |
| public static Collection<IInstallableUnit> attachFragments(Iterator<IInstallableUnit> toAttach, Map<IInstallableUnitFragment, List<IInstallableUnit>> fragmentsToIUs) { |
| Map<IInstallableUnit, IInstallableUnitFragment[]> fragmentBindings = new HashMap<IInstallableUnit, IInstallableUnitFragment[]>(); |
| //Build a map inverse of the one provided in input (host --> List of fragments) |
| Map<IInstallableUnit, List<IInstallableUnitFragment>> iusToFragment = new HashMap<IInstallableUnit, List<IInstallableUnitFragment>>(fragmentsToIUs.size()); |
| for (Map.Entry<IInstallableUnitFragment, List<IInstallableUnit>> mapping : fragmentsToIUs.entrySet()) { |
| IInstallableUnitFragment fragment = mapping.getKey(); |
| List<IInstallableUnit> existingMatches = mapping.getValue(); |
| |
| for (IInstallableUnit host : existingMatches) { |
| List<IInstallableUnitFragment> potentialFragments = iusToFragment.get(host); |
| if (potentialFragments == null) { |
| potentialFragments = new ArrayList<IInstallableUnitFragment>(); |
| iusToFragment.put(host, potentialFragments); |
| } |
| potentialFragments.add(fragment); |
| } |
| } |
| |
| for (Map.Entry<IInstallableUnit, List<IInstallableUnitFragment>> entry : iusToFragment.entrySet()) { |
| IInstallableUnit hostIU = entry.getKey(); |
| List<IInstallableUnitFragment> potentialIUFragments = entry.getValue(); |
| ArrayList<IInstallableUnitFragment> applicableFragments = new ArrayList<IInstallableUnitFragment>(); |
| for (IInstallableUnitFragment potentialFragment : potentialIUFragments) { |
| if (hostIU.equals(potentialFragment)) |
| continue; |
| |
| // Check to make sure the host meets the requirements of the fragment |
| Collection<IRequirement> reqsFromFragment = potentialFragment.getHost(); |
| boolean match = true; |
| boolean requirementMatched = false; |
| for (Iterator<IRequirement> iterator = reqsFromFragment.iterator(); iterator.hasNext() && match == true;) { |
| IRequirement reqs = iterator.next(); |
| requirementMatched = false; |
| if (hostIU.satisfies(reqs)) |
| requirementMatched = true; |
| if (requirementMatched == false) { |
| match = false; |
| break; |
| } |
| |
| } |
| if (match) { |
| applicableFragments.add(potentialFragment); |
| } |
| } |
| |
| IInstallableUnitFragment theFragment = null; |
| int specificityLevel = 0; |
| LinkedList<IInstallableUnitFragment> fragments = new LinkedList<IInstallableUnitFragment>(); |
| for (IInstallableUnitFragment fragment : applicableFragments) { |
| if (isTranslation(fragment)) { |
| fragments.add(fragment); |
| continue; |
| } |
| if (fragment.getHost().size() > specificityLevel) { |
| theFragment = fragment; |
| specificityLevel = fragment.getHost().size(); |
| } |
| } |
| if (theFragment != null) |
| fragments.addFirst(theFragment); |
| if (!fragments.isEmpty()) |
| fragmentBindings.put(hostIU, fragments.toArray(new IInstallableUnitFragment[fragments.size()])); |
| } |
| //build the collection of resolved IUs |
| Collection<IInstallableUnit> result = new HashSet<IInstallableUnit>(); |
| while (toAttach.hasNext()) { |
| IInstallableUnit iu = toAttach.next(); |
| if (iu == null) |
| continue; |
| //just return fragments as they are |
| if (QueryUtil.isFragment(iu)) { |
| result.add(iu); |
| continue; |
| } |
| //return a new IU that combines the IU with its bound fragments |
| IInstallableUnitFragment[] fragments = fragmentBindings.get(iu); |
| if (fragments == null) |
| fragments = NO_FRAGMENTS; |
| result.add(MetadataFactory.createResolvedInstallableUnit(iu, fragments)); |
| } |
| return result; |
| } |
| |
| private static boolean isTranslation(IInstallableUnitFragment fragment) { |
| for (IProvidedCapability capability : fragment.getProvidedCapabilities()) { |
| // TODO make the constant in the TranslationSupport class public and use it |
| if ("org.eclipse.equinox.p2.localization".equals(capability.getNamespace())) //$NON-NLS-1$ |
| return true; |
| } |
| return false; |
| } |
| } |