/******************************************************************************* * Copyright (c) 2014 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 org.eclipse.equinox.p2.metadata.IVersionedId; import com.codesourcery.installer.IInstallComponent; import com.codesourcery.installer.IInstallConstraint; import com.codesourcery.installer.Installer; /** * Default implementation of an install constraint. */ public class InstallConstraint implements IInstallConstraint { /** Constraint roots */ private IVersionedId[] roots; /** Constraint type */ private Constraint constraint; /** Source for constraint or <code>null</code> */ private IInstallComponent source; /** Targets for constraint */ private IInstallComponent[] targets; /** * Constructor * * @param roots Roots for constraint. If the constraint requires a source, * it must be the first element. * @param constraint Constraint type */ public InstallConstraint(IVersionedId[] roots, Constraint constraint) { this.roots = roots; this.constraint = constraint; } /** * Returns the roots for the constraint. * * @return Roots */ private IVersionedId[] getRoots() { return roots; } @Override public IInstallComponent getSource() { if (source == null) { // Source is only supported for requires constraint if (getConstraint() == Constraint.REQUIRES) { if ((getRoots() != null) && (getRoots().length != 0)) { source = RepositoryManager.getDefault().getInstallComponent(getRoots()[0].getId()); } } } return source; } @Override public IInstallComponent[] getTargets() { if (targets == null) { ArrayList<IInstallComponent> components = new ArrayList<IInstallComponent>(); for (IVersionedId root : getRoots()) { if ((getSource() != null) && getSource().getInstallUnit().getId().equals(root.getId())) continue; IInstallComponent component = RepositoryManager.getDefault().getInstallComponent(root.getId()); // If component has been loaded if (component != null) { components.add(component); } } targets = components.toArray(new IInstallComponent[components.size()]); } return targets; } @Override public Constraint getConstraint() { return constraint; } /** * Returns if an install component is a member of an install component * for a given installable unit. * * @param component Install component to check * @param id Identifier of installable unit * @return <code>true</code> if install component is member */ private boolean isMemberOf(IInstallComponent component, String id) { boolean member = false; IInstallComponent parent = component.getParent(); while (parent != null) { if (parent.getInstallUnit().getId().equals(id)) { member = true; break; } parent = parent.getParent(); } return member; } /** * Finds the constraint roots included in a set of install components. * * @param components Install components * @param checkMembers <code>true</code> to also check install component members * @return Included state of install roots */ private boolean[] findComponents(IInstallComponent[] components, boolean checkMembers) { IVersionedId[] roots = getRoots(); boolean[] found = new boolean[roots.length]; for (int index = 0; index < roots.length; index ++) { for (IInstallComponent component : components) { String id = component.getInstallUnit().getId(); String rootId = roots[index].getId(); if (id.equals(rootId)) { found[index] = true; break; } if (checkMembers && isMemberOf(component, rootId)) { found[index] = true; break; } } } return found; } @Override public boolean validate(IInstallComponent[] components) { boolean[] found; boolean result = true; switch (getConstraint()) { // One component must be included case ONE_OF: // If not an upgrade if (!Installer.getDefault().getInstallManager().getInstallMode().isUpgrade()) { found = findComponents(components, false); boolean oneSelected = false; for (boolean one : found) { if (one) { oneSelected = true; break; } } // One of the required components must be included if (!oneSelected) { result = false; } } break; // One component requires one or more other components case REQUIRES: // Check if the source is included or any of its children found = findComponents(components, true); if (found[0]) { // Check if all required targets are included found = findComponents(components, false); for (int index = 1; index < found.length; index ++) { if (!found[index]) { result = false; } } } break; // Only one component can be included case ONLY_ONE: found = findComponents(components, true); int count = 0; for (boolean one : found) { if (one) { count ++; } } if (count > 1) { result = false; } break; }; return result; } }