/******************************************************************************* * Copyright (c) 2015 Mentor Graphics 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: * Mentor Graphics - initial API and implementation *******************************************************************************/ package com.codesourcery.internal.installer; import java.util.ArrayList; import java.util.Iterator; import java.util.Stack; import org.eclipse.equinox.p2.engine.IProfile; import org.eclipse.equinox.p2.metadata.IInstallableUnit; import org.eclipse.equinox.p2.metadata.IRequirement; import org.eclipse.equinox.p2.metadata.IVersionedId; import org.eclipse.equinox.p2.query.IQueryResult; import org.eclipse.equinox.p2.query.QueryUtil; /** * This class provides utility methods for a profile. */ public class ProfileAdapter { /** Profile */ private IProfile profile; /** * Constructor * * @param profile Profile */ public ProfileAdapter(IProfile profile) { this.profile = profile; } /** * @return The profile */ public IProfile getProfile() { return profile; } /** * Returns installable units from a profile. * * @param versions Versions for installable units * @return Installable units */ public IInstallableUnit[] findUnits(IVersionedId[] versions) { ArrayList<IInstallableUnit> units = new ArrayList<IInstallableUnit>(); for (IVersionedId version : versions) { IQueryResult<IInstallableUnit> query = getProfile().query(QueryUtil.createIUQuery(version), null); Iterator<IInstallableUnit> iter = query.iterator(); while (iter.hasNext()) { units.add(iter.next()); } } return units.toArray(new IInstallableUnit[units.size()]); } /** * Returns the latest version of an installable unit in a profile. * * @param id Installable unit identifier * @return Latest version found or <code>null</code> */ public IInstallableUnit findUnit(String id) { IInstallableUnit unit = null; if (getProfile() != null) { IQueryResult<IInstallableUnit> query = getProfile().query(QueryUtil.createIUQuery(id), null); Iterator<IInstallableUnit> iter = query.iterator(); while (iter.hasNext()) { IInstallableUnit foundUnit = iter.next(); if ((unit == null) || (unit.getVersion().compareTo(unit.getVersion()) > 0)) { unit = foundUnit; } } } return unit; } /** * Returns all root IU's that require a specified IU in a profile. * * Note: This method does not work in all cases. * @param unit Unit to get dependents for * @return Dependent units * * Note: This routine is known to have problems as it doesn't check for 'strict' dependencies. */ public IInstallableUnit[] findAllDependentIUs(IInstallableUnit unit) { // Dependent units ArrayList<IInstallableUnit> dependents = new ArrayList<IInstallableUnit>(); // The units left to calculate dependencies for Stack<IInstallableUnit> unitsToCalculate = new Stack<IInstallableUnit>(); // Start with getting dependencies for specified unit unitsToCalculate.push(unit); // Get the units in the profile IQueryResult<IInstallableUnit> profileUnitsQuery = getProfile().query(QueryUtil.createIUAnyQuery(), null); IInstallableUnit[] profileUnits = profileUnitsQuery.toArray(IInstallableUnit.class); // While there are units to get dependents for while (!unitsToCalculate.empty()) { // Get units dependent on the specified unit IInstallableUnit[] children = findDependentIUs(unitsToCalculate.pop(), profileUnits); for (IInstallableUnit child : children) { if (!dependents.contains(child)) { // Add the unit as a dependent dependents.add(child); // Push so it's root dependencies are also calculated unitsToCalculate.add(child); } } } return dependents.toArray(new IInstallableUnit[dependents.size()]); } /** * Returns root IU's from a set that require the specified unit. * * Note: This method does not work in all cases. * @param unit Unit to get dependencies for * @param candidates The set of units to find dependents * @return Dependent units */ public IInstallableUnit[] findDependentIUs(IInstallableUnit unit, IInstallableUnit[] candidates) { ArrayList<IInstallableUnit> dependentRoots = new ArrayList<IInstallableUnit>(); final String TRUE = Boolean.TRUE.toString(); for (IInstallableUnit candidate : candidates) { // If root installable unit String rootProperty = getProfile().getInstallableUnitProperty(candidate, IProfile.PROP_PROFILE_ROOT_IU); if (TRUE.equals(rootProperty)) { // Get candidate unit requirements Iterator<IRequirement> requirements = candidate.getRequirements().iterator(); while (requirements.hasNext()) { IRequirement requirement = requirements.next(); // If unit satisfies the candidate requirement, the candidate // is dependent on the unit if (unit.satisfies(requirement)) { if (!dependentRoots.contains(candidate)) { dependentRoots.add(candidate); } break; } } } } return dependentRoots.toArray(new IInstallableUnit[dependentRoots.size()]); } }