blob: 4ec751c600418dd469c04302b2e8684cdd8a6249 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009, 2010 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.p2.metadata.expression;
import java.util.List;
import java.util.Map;
import org.eclipse.equinox.p2.metadata.IVersionedId;
import org.eclipse.equinox.p2.query.IQuery;
/**
* This interface provides all the factory methods needed to create the
* nodes of the expression tree.
* @since 2.0
* @noimplement This interface is not intended to be implemented directly by clients.
* @noextend This interface is not intended to be extended directly by clients.
*/
public interface IExpressionFactory {
String FUNC_BOOLEAN = "boolean"; //$NON-NLS-1$
String FUNC_VERSION = "version"; //$NON-NLS-1$
String FUNC_CLASS = "class"; //$NON-NLS-1$
String FUNC_RANGE = "range"; //$NON-NLS-1$
String FUNC_FILTER = "filter"; //$NON-NLS-1$
IExpression[] NO_ARGS = new IExpression[0];
/**
* Create a collection filter that yields true if the <code>lambda</code> yields true for
* all of the elements of the <code>collection</code>
* @param collection The collection providing the elements to test
* @param lambda The lambda that performs the test
* @return A boolean expression
*/
IExpression all(IExpression collection, IExpression lambda);
/**
* Create a logical <i>and</i> of its <code>operands</code>.
* @param operands The boolean operands
* @return A boolean expression
*/
IExpression and(IExpression... operands);
/**
* Creates an expression that represents a variable assignment
* @param variable The variable
* @param expression The expression that yields the value to assign to the variable
* @return An assignment expression
*/
IExpression assignment(IExpression variable, IExpression expression);
/**
* Create an expression that collects the result of evaluating each element in a new collection.
* @param collection The collection providing the elements to evaluate
* @param lambda The lambda that creates each new element
* @return A collection expression
*/
IExpression collect(IExpression collection, IExpression lambda);
/**
* Create an expression that first evaluates a <code>test</code> and then, depending on the outcome,
* evaluates either <code>ifTrue</code> or <code>ifFalse</code>. The expression yields the result
* of the <code>ifTrue</code> or <code>ifFalse</code> evaluation.
* @param test The test
* @param ifTrue The code to evaluate when the test evaluates to <code>true</code>
* @param ifFalse The code to evaluate when the test evaluates to <code>false</code>
* @return The conditional expression
*/
IExpression condition(IExpression test, IExpression ifTrue, IExpression ifFalse);
/**
* Create an expression that yields the first element of the
* <code>collection</code> for which the <code>lambda</code> yields <code>true</code>.
* @param collection The collection providing the elements to test
* @param lambda The lambda that performs the test
* @return An element expression
*/
IExpression first(IExpression collection, IExpression lambda);
/**
* Intended to be applied on collections of collections. Yields a single collection with
* all elements from the source collections, in the order they are evaluated.
* @param collection The collection providing the collections that provides all elements
* @return A collection expression
*/
IExpression flatten(IExpression collection);
/**
* Creates a lambda expression that takes more then one variable (currying). Suitable for use
* in most collection expressions.
* @param variable The element variable that the lambda uses
* @param body The body of the lambda
* @param initialAssignments Assignments to evaluate once before calling the body for each element.
* @return A lambda expression with currying
*/
IExpression lambda(IExpression variable, IExpression[] initialAssignments, IExpression body);
/**
* Creates a member call expression.
* @param target The target for the member call
* @param name The name of the member
* @param args The arguments to use for the call
* @return A member expression
*/
IExpression memberCall(IExpression target, String name, IExpression... args);
/**
* <p>Recursively traverse and collect elements based on a condition</p>
* <p>A common scenario in p2 is that you want to start with a set of roots and then find
* all items that fulfill the root requirements. Those items in turn introduce new
* requirements so you want to find them too. The process continues until no more
* requirements can be satisfied. This type of query can be performed using the traverse
* function.</p>
* <p>The function will evaluate an expression, once for each element, collect
* elements for which the evaluation returned true, then then re-evaluate using the
* collected result as source of elements. No element is evaluated twice. This continues
* until no more elements are found.</p>
* @param collection The collection providing the elements to test
* @param lambda The lambda that collects the children for the next iteration
* @return A collection expression
*/
IExpression traverse(IExpression collection, IExpression lambda);
/**
* Create an expression that yields a new collection where each element is unique. An
* optional <code>cache</code> can be provided if the uniqueness should span a larger
* scope then just the source collection.
* @param collection The source collection
* @param cache Optional cache to use when uniqueness should span over several invocations
* @return A collection expression
*/
IExpression unique(IExpression collection, IExpression cache);
/**
* Create an array of elements.
* @param elements The elements of the array
* @return An array expression
*/
IExpression array(IExpression... elements);
/**
* Create an lookup of <code>key</code> in the <code>target</code>.
* The key expression should evaluate to a string or an integer.
* @param target The target for the lookup
* @param key The key to use for the lookup
* @return A lookup expression
*/
IExpression at(IExpression target, IExpression key);
/**
* Create an evaluation context with one single variable
* @param params Indexed parameters to use in the expression
* @return the context
*/
IEvaluationContext createContext(Object... params);
/**
* Create an evaluation context with one single variable
* @param params Indexed parameters to use in the expression
* @param variables The variables that will be maintained by the context
* @return the context
*/
IEvaluationContext createContext(IExpression[] variables, Object... params);
/**
* Creates an expression that evaluates to the constant <code>value</code>.
* @param value The constant
* @return A constant expression
*/
IExpression constant(Object value);
/**
* Creates a top level expression that represents a full query.
* @param expr The query
* @param parameters The parameters of the query
* @return A top level query expression
*/
<T> IContextExpression<T> contextExpression(IExpression expr, Object... parameters);
/**
* Create an expression that tests if <code>lhs</code> is equal to <code>rhs</code>.
* @param lhs The left hand side value.
* @param rhs The right hand side value.
* @return A boolean expression
*/
IExpression equals(IExpression lhs, IExpression rhs);
/**
* Create a collection filter that yields true if the <code>lambda</code> yields true for
* at least one of the elements of the <code>collection</code>
* @param collection The collection providing the elements to test
* @param lambda The lambda that performs the test
* @return A boolean expression
*/
IExpression exists(IExpression collection, IExpression lambda);
/**
* Creates a top level expression suitable for predicate matching
* @param expression The boolean expression
* @return A top level predicate expression
*/
IFilterExpression filterExpression(IExpression expression);
/**
* Given one of the values in the map returned by {@link #getFunctionMap()}, this method
* returns a function expression.
* @param function The value obtained from the map.
* @param args The arguments to evaluate and pass when evaluating the function.
* @return A function expression
*/
IExpression function(Object function, IExpression... args);
/**
* Returns a map of functions supported by this factory. The map is keyed by
* function names and the value is an object suitable to pass to the {@link #function(Object, IExpression[])}
* method.
* @return A key/function map.
*/
Map<String, ? extends Object> getFunctionMap();
/**
* Create an expression that tests if <code>lhs</code> is greater than <code>rhs</code>.
* @param lhs The left hand side value.
* @param rhs The right hand side value.
* @return A boolean expression
*/
IExpression greater(IExpression lhs, IExpression rhs);
/**
* Create an expression that tests if <code>lhs</code> is greater than or equal to <code>rhs</code>.
* @param lhs The left hand side value.
* @param rhs The right hand side value.
* @return A boolean expression
*/
IExpression greaterEqual(IExpression lhs, IExpression rhs);
/**
* Creates an indexed parameter expression
* @param index The index to use
* @return a parameter expression
*/
IExpression indexedParameter(int index);
/**
* Create an <i>intersection</i> of <code>c1</code> and <code>c2</code>
* @param c1 first collection
* @param c2 second collection
* @return An intersect expression
*/
IExpression intersect(IExpression c1, IExpression c2);
/**
* Creates a lambda expression that takes exactly one variable. Suitable for use
* in most collection expressions.
* @param variable The element variable that the lambda uses
* @param body The body of the lambda
* @return A lambda expression
*/
IExpression lambda(IExpression variable, IExpression body);
/**
* Create an expression that yields a new collection consisting of the latest version of
* the elements of the <code>collection</code>. Each element in <code>collection</code>
* must implement the {@link IVersionedId} interface.
* @param collection The collection providing the versioned elements
* @return A collection expression
*/
IExpression latest(IExpression collection);
/**
* Create an expression that tests if <code>lhs</code> is less than <code>rhs</code>.
* @param lhs The left hand side value.
* @param rhs The right hand side value.
* @return A boolean expression
*/
IExpression less(IExpression lhs, IExpression rhs);
/**
* Create an expression that tests if <code>lhs</code> is less than or equal to <code>rhs</code>.
* @param lhs The left hand side value.
* @param rhs The right hand side value.
* @return A boolean expression
*/
IExpression lessEqual(IExpression lhs, IExpression rhs);
/**
* Create an expression that yields a new collection consisting of the <i>count</i>
* first elements of the source collection.
* @param collection The source collection
* @param count The element count limit
* @return A collection expression
*/
IExpression limit(IExpression collection, int count);
/**
* Create an expression that yields a new collection consisting of the <i>n</i> first
* elements of the source collection where <i>n</i> is determined by <code>limit</code>.
* @param collection The source collection
* @param limit The expression that evaluates to the element count limit
* @return A collection expression
*/
IExpression limit(IExpression collection, IExpression limit);
/**
* Performs boolean normalization on the expression to create a canonical form.
* @param operands The operands to normalize
* @param expressionType The type (must be either {@link IExpression#TYPE_AND}
* or {@link IExpression#TYPE_OR}.
* @return The normalized expression
*/
IExpression normalize(List<? extends IExpression> operands, int expressionType);
/**
* Create an expression that tests if <code>lhs</code> matches <code>rhs</code>.
* @param lhs The left hand side value.
* @param rhs The right hand side value.
* @return A boolean expression
*/
IExpression matches(IExpression lhs, IExpression rhs);
/**
* Creates a parameterized top level expression suitable for predicate matching
* @param expression The boolean expression
* @param parameters The parameters to use in the call
* @return A top level predicate expression
*/
<T> IMatchExpression<T> matchExpression(IExpression expression, Object... parameters);
/**
* Creates a member accessor expression.
* @param target The target for the member access
* @param name The name of the member
* @return A member expression
*/
IExpression member(IExpression target, String name);
/**
* Creates an expression that negates the result of evaluating its <code>operand</code>.
* @param operand The boolean expression to negate
* @return A boolean expression
*/
IExpression not(IExpression operand);
/**
* Create a logical <i>or</i> of its <code>operands</code>.
* @param operands The boolean operands
* @return A boolean expression
*/
IExpression or(IExpression... operands);
/**
* Create a pipe of expressions.
* @param expressions The expressions that make out the pipe
* @return A pipe expression
*/
IExpression pipe(IExpression... expressions);
/**
* Create an expression that yields a new collection consisting of all elements of the
* <code>collection</code> for which the <code>lambda</code> yields <code>true</code>.
* @param collection The collection providing the elements to test
* @param lambda The lambda that performs the test
* @return A collection expression
*/
IExpression select(IExpression collection, IExpression lambda);
/**
* Returns the variable that represents <code>this</code> in an expression
* @return The <code>this</code> variable.
*/
IExpression thisVariable();
/**
* Wrap an {@link IQuery} as an expression.
* @param query The query to wrap.
* @return An expression that wraps the query
*/
IExpression toExpression(IQuery<?> query);
/**
* Create a <i>union</i> of <code>c1</code> and <code>c2</code>
* @param c1 first collection
* @param c2 second collection
* @return A union expression
*/
IExpression union(IExpression c1, IExpression c2);
/**
* Creates an expression that represents a variable
* @param name The name of the variable
* @return A variable expression
*/
IExpression variable(String name);
}