blob: 47a318c5b2451224f7947e719aab37586622dbca [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009, 2017 Cloudsmith Inc. 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:
* Cloudsmith Inc. - initial API and implementation
*******************************************************************************/
package org.eclipse.equinox.internal.p2.metadata.expression;
import org.eclipse.equinox.p2.metadata.expression.IEvaluationContext;
import org.eclipse.equinox.p2.metadata.expression.IExpression;
import org.eclipse.equinox.p2.metadata.index.IIndexProvider;
/**
* Highly specialized evaluation contexts optimized for misc purposes
*/
public class EvaluationContext implements IEvaluationContext {
public static class SingleVariableContext extends EvaluationContext {
private Object value;
private final IExpression variable;
public SingleVariableContext(EvaluationContext parentContext, IExpression variable, Object[] parameters) {
super(parentContext, parameters);
this.variable = variable;
}
@Override
public Object getValue(IExpression var) {
return variable == var ? value : parentContext.getValue(var);
}
@Override
public void setValue(IExpression var, Object val) {
if (variable == var)
value = val;
else
parentContext.setValue(var, val);
}
}
public static class MultiVariableContext extends EvaluationContext {
private final Object[] values;
public MultiVariableContext(EvaluationContext parentContext, IExpression[] variables, Object[] parameters) {
super(parentContext, parameters);
values = new Object[variables.length * 2];
for (int idx = 0, ndx = 0; ndx < variables.length; ++ndx, idx += 2)
values[idx] = variables[ndx];
}
@Override
public Object getValue(IExpression variable) {
for (int idx = 0; idx < values.length; ++idx)
if (values[idx++] == variable)
return values[idx];
return parentContext.getValue(variable);
}
@Override
public void setValue(IExpression variable, Object value) {
for (int idx = 0; idx < values.length; ++idx)
if (values[idx++] == variable) {
values[idx] = value;
return;
}
parentContext.setValue(variable, value);
}
}
private static final Object[] noParameters = new Object[0];
private static final EvaluationContext INSTANCE = new EvaluationContext(null, noParameters);
public static IEvaluationContext create() {
return INSTANCE;
}
public static IEvaluationContext create(IEvaluationContext parent, IExpression variable) {
return new SingleVariableContext((EvaluationContext) parent, variable, ((EvaluationContext) parent).parameters);
}
public static IEvaluationContext create(IEvaluationContext parent, IExpression[] variables) {
return create(parent, ((EvaluationContext) parent).parameters, variables);
}
public static IEvaluationContext create(IEvaluationContext parent, Object[] parameters, IExpression[] variables) {
if (variables == null || variables.length == 0)
return create(parent, parameters);
if (parameters == null)
parameters = noParameters;
return variables.length == 1 ? new SingleVariableContext((EvaluationContext) parent, variables[0], parameters) : new MultiVariableContext((EvaluationContext) parent, variables, parameters);
}
public static IEvaluationContext create(IEvaluationContext parent, Object[] parameters) {
if (parameters == null)
parameters = noParameters;
return new EvaluationContext((EvaluationContext) parent, parameters);
}
public static IEvaluationContext create(IExpression variable) {
return new SingleVariableContext(INSTANCE, variable, noParameters);
}
public static IEvaluationContext create(IExpression[] variables) {
return create(INSTANCE, noParameters, variables);
}
public static IEvaluationContext create(Object[] parameters, IExpression variable) {
if (parameters == null)
parameters = noParameters;
return new SingleVariableContext(INSTANCE, variable, parameters);
}
public static IEvaluationContext create(Object[] parameters, IExpression[] variables) {
return create(INSTANCE, parameters, variables);
}
final EvaluationContext parentContext;
private final Object[] parameters;
private IIndexProvider<?> indexProvider;
EvaluationContext(EvaluationContext parentContext, Object[] parameters) {
this.parentContext = parentContext;
this.parameters = parameters;
}
@Override
public final Object getParameter(int position) {
return parameters[position];
}
@Override
public Object getValue(IExpression variable) {
if (parentContext == null)
throw new IllegalArgumentException("No such variable: " + variable); //$NON-NLS-1$
return parentContext.getValue(variable);
}
@Override
public void setValue(IExpression variable, Object value) {
if (parentContext == null)
throw new IllegalArgumentException("No such variable: " + variable); //$NON-NLS-1$
parentContext.setValue(variable, value);
}
@Override
public IIndexProvider<?> getIndexProvider() {
if (indexProvider == null) {
if (parentContext == null)
return null;
return parentContext.getIndexProvider();
}
return indexProvider;
}
@Override
public void setIndexProvider(IIndexProvider<?> indexProvider) {
this.indexProvider = indexProvider;
}
}