blob: 0018ec7ab32eb67b12d8cdd89366085e207b4a73 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2007, 2017 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Todor Boev
*******************************************************************************/
package org.eclipse.equinox.internal.p2.metadata;
import static org.eclipse.equinox.internal.p2.metadata.InstallableUnit.MEMBER_PROVIDED_CAPABILITIES;
import static org.eclipse.equinox.internal.p2.metadata.ProvidedCapability.MEMBER_NAMESPACE;
import static org.eclipse.equinox.internal.p2.metadata.ProvidedCapability.MEMBER_PROPERTIES;
import org.eclipse.core.runtime.Assert;
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
import org.eclipse.equinox.p2.metadata.IProvidedCapability;
import org.eclipse.equinox.p2.metadata.IRequirement;
import org.eclipse.equinox.p2.metadata.expression.ExpressionUtil;
import org.eclipse.equinox.p2.metadata.expression.IExpression;
import org.eclipse.equinox.p2.metadata.expression.IExpressionFactory;
import org.eclipse.equinox.p2.metadata.expression.IFilterExpression;
import org.eclipse.equinox.p2.metadata.expression.IMatchExpression;
/**
* A required capability match represents some external constraint on an
* {@link IInstallableUnit}.
* <p>
* This is a flavor of the general {@link IRequirement} that searches for a
* capability that has {@link IProvidedCapability#getProperties() properties}
* that match a given expression. I.e. this is much more limited that an
* arbitrary match expression executed over all metadata of the IU.
*/
public class RequiredPropertiesMatch extends Requirement {
/**
* Argument $0 must evaluate to a String Argument $2 must evaluate to an
* expression compatible with the match operator "~="
*/
private static final IExpression PROPERTIES_MATCH = ExpressionUtil
.parse(String.format("%s.exists(cap | cap.%s == $0 && cap.%s ~= $1)", //$NON-NLS-1$
MEMBER_PROVIDED_CAPABILITIES, MEMBER_NAMESPACE, MEMBER_PROPERTIES));
public RequiredPropertiesMatch(String namespace, IFilterExpression attrFilter,
IMatchExpression<IInstallableUnit> envFilter, int min, int max, boolean greedy, String description) {
super(createMatchExpressionFromFilter(namespace, attrFilter, description), envFilter, min, max, greedy,
description);
}
@Override
public String toString() {
StringBuilder result = new StringBuilder();
result.append(extractNamespace(getMatches()));
result.append("; "); //$NON-NLS-1$
result.append(extractPropertiesMatch(getMatches()));
return result.toString();
}
public static IMatchExpression<IInstallableUnit> createMatchExpressionFromFilter(String namespace,
IFilterExpression attrFilter, String description) {
Assert.isNotNull(namespace);
Assert.isNotNull(attrFilter,
"Filter is missing for required capability " + namespace + " in bundle " + description); //$NON-NLS-1$ //$NON-NLS-2$
IExpressionFactory factory = ExpressionUtil.getFactory();
return factory.matchExpression(PROPERTIES_MATCH, namespace, attrFilter);
}
public static String extractNamespace(IMatchExpression<IInstallableUnit> matchExpression) {
assertValid(matchExpression);
return (String) matchExpression.getParameters()[0];
}
public static IFilterExpression extractPropertiesMatch(IMatchExpression<IInstallableUnit> matchExpression) {
assertValid(matchExpression);
return (IFilterExpression) matchExpression.getParameters()[1];
}
public static boolean isPropertiesMatchRequirement(IMatchExpression<IInstallableUnit> matchExpression) {
return PROPERTIES_MATCH.equals(ExpressionUtil.getOperand(matchExpression));
}
private static void assertValid(IMatchExpression<IInstallableUnit> matchExpression) {
if (!isPropertiesMatchRequirement(matchExpression)) {
throw new IllegalArgumentException();
}
}
}