1 /******************************************************************************* 2 * Copyright (c) 2009, 2010 Cloudsmith Inc. and others. 3 * 4 * This program and the accompanying materials 5 * are made available under the terms of the Eclipse Public License 2.0 6 * which accompanies this distribution, and is available at 7 * https://www.eclipse.org/legal/epl-2.0/ 8 * 9 * SPDX-License-Identifier: EPL-2.0 10 * 11 * Contributors: 12 * Cloudsmith Inc. - initial API and implementation 13 *******************************************************************************/ 14 package org.eclipse.equinox.p2.metadata.expression; 15 16 import java.util.List; 17 import java.util.Map; 18 import org.eclipse.equinox.p2.metadata.IVersionedId; 19 import org.eclipse.equinox.p2.query.IQuery; 20 21 /** 22 * This interface provides all the factory methods needed to create the 23 * nodes of the expression tree. 24 * @since 2.0 25 * @noimplement This interface is not intended to be implemented directly by clients. 26 * @noextend This interface is not intended to be extended directly by clients. 27 */ 28 public interface IExpressionFactory { 29 String FUNC_BOOLEAN = "boolean"; //$NON-NLS-1$ 30 String FUNC_VERSION = "version"; //$NON-NLS-1$ 31 String FUNC_CLASS = "class"; //$NON-NLS-1$ 32 String FUNC_RANGE = "range"; //$NON-NLS-1$ 33 String FUNC_FILTER = "filter"; //$NON-NLS-1$ 34 35 IExpression[] NO_ARGS = new IExpression[0]; 36 37 /** 38 * Create a collection filter that yields true if the <code>lambda</code> yields true for 39 * all of the elements of the <code>collection</code> 40 * @param collection The collection providing the elements to test 41 * @param lambda The lambda that performs the test 42 * @return A boolean expression 43 */ all(IExpression collection, IExpression lambda)44 IExpression all(IExpression collection, IExpression lambda); 45 46 /** 47 * Create a logical <i>and</i> of its <code>operands</code>. 48 * @param operands The boolean operands 49 * @return A boolean expression 50 */ and(IExpression... operands)51 IExpression and(IExpression... operands); 52 53 /** 54 * Creates an expression that represents a variable assignment 55 * @param variable The variable 56 * @param expression The expression that yields the value to assign to the variable 57 * @return An assignment expression 58 */ assignment(IExpression variable, IExpression expression)59 IExpression assignment(IExpression variable, IExpression expression); 60 61 /** 62 * Create an expression that collects the result of evaluating each element in a new collection. 63 * @param collection The collection providing the elements to evaluate 64 * @param lambda The lambda that creates each new element 65 * @return A collection expression 66 */ collect(IExpression collection, IExpression lambda)67 IExpression collect(IExpression collection, IExpression lambda); 68 69 /** 70 * Create an expression that first evaluates a <code>test</code> and then, depending on the outcome, 71 * evaluates either <code>ifTrue</code> or <code>ifFalse</code>. The expression yields the result 72 * of the <code>ifTrue</code> or <code>ifFalse</code> evaluation. 73 * @param test The test 74 * @param ifTrue The code to evaluate when the test evaluates to <code>true</code> 75 * @param ifFalse The code to evaluate when the test evaluates to <code>false</code> 76 * @return The conditional expression 77 */ condition(IExpression test, IExpression ifTrue, IExpression ifFalse)78 IExpression condition(IExpression test, IExpression ifTrue, IExpression ifFalse); 79 80 /** 81 * Create an expression that yields the first element of the 82 * <code>collection</code> for which the <code>lambda</code> yields <code>true</code>. 83 * @param collection The collection providing the elements to test 84 * @param lambda The lambda that performs the test 85 * @return An element expression 86 */ first(IExpression collection, IExpression lambda)87 IExpression first(IExpression collection, IExpression lambda); 88 89 /** 90 * Intended to be applied on collections of collections. Yields a single collection with 91 * all elements from the source collections, in the order they are evaluated. 92 * @param collection The collection providing the collections that provides all elements 93 * @return A collection expression 94 */ flatten(IExpression collection)95 IExpression flatten(IExpression collection); 96 97 /** 98 * Creates a lambda expression that takes more then one variable (currying). Suitable for use 99 * in most collection expressions. 100 * @param variable The element variable that the lambda uses 101 * @param body The body of the lambda 102 * @param initialAssignments Assignments to evaluate once before calling the body for each element. 103 * @return A lambda expression with currying 104 */ lambda(IExpression variable, IExpression[] initialAssignments, IExpression body)105 IExpression lambda(IExpression variable, IExpression[] initialAssignments, IExpression body); 106 107 /** 108 * Creates a member call expression. 109 * @param target The target for the member call 110 * @param name The name of the member 111 * @param args The arguments to use for the call 112 * @return A member expression 113 */ memberCall(IExpression target, String name, IExpression... args)114 IExpression memberCall(IExpression target, String name, IExpression... args); 115 116 /** 117 * <p>Recursively traverse and collect elements based on a condition</p> 118 * <p>A common scenario in p2 is that you want to start with a set of roots and then find 119 * all items that fulfill the root requirements. Those items in turn introduce new 120 * requirements so you want to find them too. The process continues until no more 121 * requirements can be satisfied. This type of query can be performed using the traverse 122 * function.</p> 123 * <p>The function will evaluate an expression, once for each element, collect 124 * elements for which the evaluation returned true, then then re-evaluate using the 125 * collected result as source of elements. No element is evaluated twice. This continues 126 * until no more elements are found.</p> 127 * @param collection The collection providing the elements to test 128 * @param lambda The lambda that collects the children for the next iteration 129 * @return A collection expression 130 */ traverse(IExpression collection, IExpression lambda)131 IExpression traverse(IExpression collection, IExpression lambda); 132 133 /** 134 * Create an expression that yields a new collection where each element is unique. An 135 * optional <code>cache</code> can be provided if the uniqueness should span a larger 136 * scope then just the source collection. 137 * @param collection The source collection 138 * @param cache Optional cache to use when uniqueness should span over several invocations 139 * @return A collection expression 140 */ unique(IExpression collection, IExpression cache)141 IExpression unique(IExpression collection, IExpression cache); 142 143 /** 144 * Create an array of elements. 145 * @param elements The elements of the array 146 * @return An array expression 147 */ array(IExpression... elements)148 IExpression array(IExpression... elements); 149 150 /** 151 * Create an lookup of <code>key</code> in the <code>target</code>. 152 * The key expression should evaluate to a string or an integer. 153 * @param target The target for the lookup 154 * @param key The key to use for the lookup 155 * @return A lookup expression 156 */ at(IExpression target, IExpression key)157 IExpression at(IExpression target, IExpression key); 158 159 /** 160 * Create an evaluation context with one single variable 161 * @param params Indexed parameters to use in the expression 162 * @return the context 163 */ createContext(Object... params)164 IEvaluationContext createContext(Object... params); 165 166 /** 167 * Create an evaluation context with one single variable 168 * @param params Indexed parameters to use in the expression 169 * @param variables The variables that will be maintained by the context 170 * @return the context 171 */ createContext(IExpression[] variables, Object... params)172 IEvaluationContext createContext(IExpression[] variables, Object... params); 173 174 /** 175 * Creates an expression that evaluates to the constant <code>value</code>. 176 * @param value The constant 177 * @return A constant expression 178 */ constant(Object value)179 IExpression constant(Object value); 180 181 /** 182 * Creates a top level expression that represents a full query. 183 * @param expr The query 184 * @param parameters The parameters of the query 185 * @return A top level query expression 186 */ contextExpression(IExpression expr, Object... parameters)187 <T> IContextExpression<T> contextExpression(IExpression expr, Object... parameters); 188 189 /** 190 * Create an expression that tests if <code>lhs</code> is equal to <code>rhs</code>. 191 * @param lhs The left hand side value. 192 * @param rhs The right hand side value. 193 * @return A boolean expression 194 */ equals(IExpression lhs, IExpression rhs)195 IExpression equals(IExpression lhs, IExpression rhs); 196 197 /** 198 * Create a collection filter that yields true if the <code>lambda</code> yields true for 199 * at least one of the elements of the <code>collection</code> 200 * @param collection The collection providing the elements to test 201 * @param lambda The lambda that performs the test 202 * @return A boolean expression 203 */ exists(IExpression collection, IExpression lambda)204 IExpression exists(IExpression collection, IExpression lambda); 205 206 /** 207 * Creates a top level expression suitable for predicate matching 208 * @param expression The boolean expression 209 * @return A top level predicate expression 210 */ filterExpression(IExpression expression)211 IFilterExpression filterExpression(IExpression expression); 212 213 /** 214 * Given one of the values in the map returned by {@link #getFunctionMap()}, this method 215 * returns a function expression. 216 * @param function The value obtained from the map. 217 * @param args The arguments to evaluate and pass when evaluating the function. 218 * @return A function expression 219 */ function(Object function, IExpression... args)220 IExpression function(Object function, IExpression... args); 221 222 /** 223 * Returns a map of functions supported by this factory. The map is keyed by 224 * function names and the value is an object suitable to pass to the {@link #function(Object, IExpression[])} 225 * method. 226 * @return A key/function map. 227 */ getFunctionMap()228 Map<String, ? extends Object> getFunctionMap(); 229 230 /** 231 * Create an expression that tests if <code>lhs</code> is greater than <code>rhs</code>. 232 * @param lhs The left hand side value. 233 * @param rhs The right hand side value. 234 * @return A boolean expression 235 */ greater(IExpression lhs, IExpression rhs)236 IExpression greater(IExpression lhs, IExpression rhs); 237 238 /** 239 * Create an expression that tests if <code>lhs</code> is greater than or equal to <code>rhs</code>. 240 * @param lhs The left hand side value. 241 * @param rhs The right hand side value. 242 * @return A boolean expression 243 */ greaterEqual(IExpression lhs, IExpression rhs)244 IExpression greaterEqual(IExpression lhs, IExpression rhs); 245 246 /** 247 * Creates an indexed parameter expression 248 * @param index The index to use 249 * @return a parameter expression 250 */ indexedParameter(int index)251 IExpression indexedParameter(int index); 252 253 /** 254 * Create an <i>intersection</i> of <code>c1</code> and <code>c2</code> 255 * @param c1 first collection 256 * @param c2 second collection 257 * @return An intersect expression 258 */ intersect(IExpression c1, IExpression c2)259 IExpression intersect(IExpression c1, IExpression c2); 260 261 /** 262 * Creates a lambda expression that takes exactly one variable. Suitable for use 263 * in most collection expressions. 264 * @param variable The element variable that the lambda uses 265 * @param body The body of the lambda 266 * @return A lambda expression 267 */ lambda(IExpression variable, IExpression body)268 IExpression lambda(IExpression variable, IExpression body); 269 270 /** 271 * Create an expression that yields a new collection consisting of the latest version of 272 * the elements of the <code>collection</code>. Each element in <code>collection</code> 273 * must implement the {@link IVersionedId} interface. 274 * @param collection The collection providing the versioned elements 275 * @return A collection expression 276 */ latest(IExpression collection)277 IExpression latest(IExpression collection); 278 279 /** 280 * Create an expression that tests if <code>lhs</code> is less than <code>rhs</code>. 281 * @param lhs The left hand side value. 282 * @param rhs The right hand side value. 283 * @return A boolean expression 284 */ less(IExpression lhs, IExpression rhs)285 IExpression less(IExpression lhs, IExpression rhs); 286 287 /** 288 * Create an expression that tests if <code>lhs</code> is less than or equal to <code>rhs</code>. 289 * @param lhs The left hand side value. 290 * @param rhs The right hand side value. 291 * @return A boolean expression 292 */ lessEqual(IExpression lhs, IExpression rhs)293 IExpression lessEqual(IExpression lhs, IExpression rhs); 294 295 /** 296 * Create an expression that yields a new collection consisting of the <i>count</i> 297 * first elements of the source collection. 298 * @param collection The source collection 299 * @param count The element count limit 300 * @return A collection expression 301 */ limit(IExpression collection, int count)302 IExpression limit(IExpression collection, int count); 303 304 /** 305 * Create an expression that yields a new collection consisting of the <i>n</i> first 306 * elements of the source collection where <i>n</i> is determined by <code>limit</code>. 307 * @param collection The source collection 308 * @param limit The expression that evaluates to the element count limit 309 * @return A collection expression 310 */ limit(IExpression collection, IExpression limit)311 IExpression limit(IExpression collection, IExpression limit); 312 313 /** 314 * Performs boolean normalization on the expression to create a canonical form. 315 * @param operands The operands to normalize 316 * @param expressionType The type (must be either {@link IExpression#TYPE_AND} 317 * or {@link IExpression#TYPE_OR}. 318 * @return The normalized expression 319 */ normalize(List<? extends IExpression> operands, int expressionType)320 IExpression normalize(List<? extends IExpression> operands, int expressionType); 321 322 /** 323 * Create an expression that tests if <code>lhs</code> matches <code>rhs</code>. 324 * @param lhs The left hand side value. 325 * @param rhs The right hand side value. 326 * @return A boolean expression 327 */ matches(IExpression lhs, IExpression rhs)328 IExpression matches(IExpression lhs, IExpression rhs); 329 330 /** 331 * Creates a parameterized top level expression suitable for predicate matching 332 * @param expression The boolean expression 333 * @param parameters The parameters to use in the call 334 * @return A top level predicate expression 335 */ matchExpression(IExpression expression, Object... parameters)336 <T> IMatchExpression<T> matchExpression(IExpression expression, Object... parameters); 337 338 /** 339 * Creates a member accessor expression. 340 * @param target The target for the member access 341 * @param name The name of the member 342 * @return A member expression 343 */ member(IExpression target, String name)344 IExpression member(IExpression target, String name); 345 346 /** 347 * Creates an expression that negates the result of evaluating its <code>operand</code>. 348 * @param operand The boolean expression to negate 349 * @return A boolean expression 350 */ not(IExpression operand)351 IExpression not(IExpression operand); 352 353 /** 354 * Create a logical <i>or</i> of its <code>operands</code>. 355 * @param operands The boolean operands 356 * @return A boolean expression 357 */ or(IExpression... operands)358 IExpression or(IExpression... operands); 359 360 /** 361 * Create a pipe of expressions. 362 * @param expressions The expressions that make out the pipe 363 * @return A pipe expression 364 */ pipe(IExpression... expressions)365 IExpression pipe(IExpression... expressions); 366 367 /** 368 * Create an expression that yields a new collection consisting of all elements of the 369 * <code>collection</code> for which the <code>lambda</code> yields <code>true</code>. 370 * @param collection The collection providing the elements to test 371 * @param lambda The lambda that performs the test 372 * @return A collection expression 373 */ select(IExpression collection, IExpression lambda)374 IExpression select(IExpression collection, IExpression lambda); 375 376 /** 377 * Returns the variable that represents <code>this</code> in an expression 378 * @return The <code>this</code> variable. 379 */ thisVariable()380 IExpression thisVariable(); 381 382 /** 383 * Wrap an {@link IQuery} as an expression. 384 * @param query The query to wrap. 385 * @return An expression that wraps the query 386 */ toExpression(IQuery<?> query)387 IExpression toExpression(IQuery<?> query); 388 389 /** 390 * Create a <i>union</i> of <code>c1</code> and <code>c2</code> 391 * @param c1 first collection 392 * @param c2 second collection 393 * @return A union expression 394 */ union(IExpression c1, IExpression c2)395 IExpression union(IExpression c1, IExpression c2); 396 397 /** 398 * Creates an expression that represents a variable 399 * @param name The name of the variable 400 * @return A variable expression 401 */ variable(String name)402 IExpression variable(String name); 403 } 404