| /******************************************************************************* |
| * 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; |
| } |
| } |