Coverage Report - com.allanbank.mongodb.builder.expression.Expressions
 
Classes in this File Line Coverage Branch Coverage Complexity
Expressions
97%
72/74
100%
6/6
1.062
 
 1  
 /*
 2  
  * #%L
 3  
  * Expressions.java - mongodb-async-driver - Allanbank Consulting, Inc.
 4  
  * %%
 5  
  * Copyright (C) 2011 - 2014 Allanbank Consulting, Inc.
 6  
  * %%
 7  
  * Licensed under the Apache License, Version 2.0 (the "License");
 8  
  * you may not use this file except in compliance with the License.
 9  
  * You may obtain a copy of the License at
 10  
  * 
 11  
  *      http://www.apache.org/licenses/LICENSE-2.0
 12  
  * 
 13  
  * Unless required by applicable law or agreed to in writing, software
 14  
  * distributed under the License is distributed on an "AS IS" BASIS,
 15  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 16  
  * See the License for the specific language governing permissions and
 17  
  * limitations under the License.
 18  
  * #L%
 19  
  */
 20  
 
 21  
 package com.allanbank.mongodb.builder.expression;
 22  
 
 23  
 import static com.allanbank.mongodb.bson.builder.BuilderFactory.d;
 24  
 
 25  
 import java.util.Arrays;
 26  
 import java.util.Date;
 27  
 import java.util.List;
 28  
 import java.util.regex.Pattern;
 29  
 
 30  
 import com.allanbank.mongodb.bson.DocumentAssignable;
 31  
 import com.allanbank.mongodb.bson.Element;
 32  
 import com.allanbank.mongodb.bson.builder.BuilderFactory;
 33  
 import com.allanbank.mongodb.bson.element.BooleanElement;
 34  
 import com.allanbank.mongodb.bson.element.DocumentElement;
 35  
 import com.allanbank.mongodb.bson.element.DoubleElement;
 36  
 import com.allanbank.mongodb.bson.element.IntegerElement;
 37  
 import com.allanbank.mongodb.bson.element.LongElement;
 38  
 import com.allanbank.mongodb.bson.element.MongoTimestampElement;
 39  
 import com.allanbank.mongodb.bson.element.NullElement;
 40  
 import com.allanbank.mongodb.bson.element.ObjectId;
 41  
 import com.allanbank.mongodb.bson.element.ObjectIdElement;
 42  
 import com.allanbank.mongodb.bson.element.RegularExpressionElement;
 43  
 import com.allanbank.mongodb.bson.element.StringElement;
 44  
 import com.allanbank.mongodb.bson.element.TimestampElement;
 45  
 
 46  
 /**
 47  
  * Expressions provides a collection of static helper method for constructing
 48  
  * complex expression.
 49  
  * 
 50  
  * @api.yes This class is part of the driver's API. Public and protected members
 51  
  *          will be deprecated for at least 1 non-bugfix release (version
 52  
  *          numbers are <major>.<minor>.<bugfix>) before being
 53  
  *          removed or modified.
 54  
  * @copyright 2012-2013, Allanbank Consulting, Inc., All Rights Reserved
 55  
  */
 56  
 public final class Expressions {
 57  
 
 58  
     /** The {@value} operator token */
 59  
     public static final String ADD = "$add";
 60  
 
 61  
     /** The {@value} operator token */
 62  
     public static final String ALL_ELEMENTS_TRUE = "$allElementsTrue";
 63  
 
 64  
     /** The {@value} operator token */
 65  
     public static final String AND = "$and";
 66  
 
 67  
     /** The {@value} operator token */
 68  
     public static final String ANY_ELEMENT_TRUE = "$anyElementTrue";
 69  
 
 70  
     /** The {@value} operator token */
 71  
     public static final String COMPARE = "$cmp";
 72  
 
 73  
     /** The {@value} operator token */
 74  
     public static final String CONCATENATE = "$concat";
 75  
 
 76  
     /** The {@value} operator token */
 77  
     public static final String CONDITION = "$cond";
 78  
 
 79  
     /** The {@value} operator token */
 80  
     public static final String DAY_OF_MONTH = "$dayOfMonth";
 81  
 
 82  
     /** The {@value} operator token */
 83  
     public static final String DAY_OF_WEEK = "$dayOfWeek";
 84  
 
 85  
     /** The {@value} operator token */
 86  
     public static final String DAY_OF_YEAR = "$dayOfYear";
 87  
 
 88  
     /** The {@value} operator token */
 89  
     public static final String DIVIDE = "$divide";
 90  
 
 91  
     /** The {@value} operator token */
 92  
     public static final String EQUAL = "$eq";
 93  
 
 94  
     /** The {@value} operator token */
 95  
     public static final String GREATER_THAN = "$gt";
 96  
 
 97  
     /** The {@value} operator token */
 98  
     public static final String GREATER_THAN_OR_EQUAL = "$gte";
 99  
 
 100  
     /** The {@value} operator token */
 101  
     public static final String HOUR = "$hour";
 102  
 
 103  
     /** The {@value} operator token */
 104  
     public static final String IF_NULL = "$ifNull";
 105  
 
 106  
     /** The {@value} operator token */
 107  
     public static final String LESS_THAN = "$lt";
 108  
 
 109  
     /** The {@value} operator token */
 110  
     public static final String LESS_THAN_OR_EQUAL = "$lte";
 111  
 
 112  
     /** The {@value} operator token */
 113  
     public static final String LITERAL = "$literal";
 114  
 
 115  
     /** The {@value} operator token */
 116  
     public static final String MILLISECOND = "$millisecond";
 117  
 
 118  
     /** The {@value} operator token */
 119  
     public static final String MINUTE = "$minute";
 120  
 
 121  
     /** The {@value} operator token */
 122  
     public static final String MODULO = "$mod";
 123  
 
 124  
     /** The {@value} operator token */
 125  
     public static final String MONTH = "$month";
 126  
 
 127  
     /** The {@value} operator token */
 128  
     public static final String MULTIPLY = "$multiply";
 129  
 
 130  
     /** The {@value} operator token */
 131  
     public static final String NOT = "$not";
 132  
 
 133  
     /** The {@value} operator token */
 134  
     public static final String NOT_EQUAL = "$ne";
 135  
 
 136  
     /** The {@value} operator token */
 137  
     public static final String OR = "$or";
 138  
 
 139  
     /** The {@value} operator token */
 140  
     public static final String SECOND = "$second";
 141  
 
 142  
     /** The {@value} operator token */
 143  
     public static final String SET_DIFFERENCE = "$setDifference";
 144  
 
 145  
     /** The {@value} operator token */
 146  
     public static final String SET_EQUALS = "$setEquals";
 147  
 
 148  
     /** The {@value} operator token */
 149  
     public static final String SET_INTERSECTION = "$setIntersection";
 150  
 
 151  
     /** The {@value} operator token */
 152  
     public static final String SET_IS_SUBSET = "$setIsSubset";
 153  
 
 154  
     /** The {@value} operator token */
 155  
     public static final String SET_UNION = "$setUnion";
 156  
 
 157  
     /** The {@value} operator token */
 158  
     public static final String SIZE = "$size";
 159  
 
 160  
     /** The {@value} operator token */
 161  
     public static final String STRING_CASE_INSENSITIVE_COMPARE = "$strcasecmp";
 162  
 
 163  
     /** The {@value} operator token */
 164  
     public static final String SUB_STRING = "$substr";
 165  
 
 166  
     /** The {@value} operator token */
 167  
     public static final String SUBTRACT = "$subtract";
 168  
 
 169  
     /** The {@value} operator token */
 170  
     public static final String TO_LOWER = "$toLower";
 171  
 
 172  
     /** The {@value} operator token */
 173  
     public static final String TO_UPPER = "$toUpper";
 174  
 
 175  
     /** The {@value} operator token */
 176  
     public static final String WEEK = "$week";
 177  
 
 178  
     /** The {@value} operator token */
 179  
     public static final String YEAR = "$year";
 180  
 
 181  
     /**
 182  
      * Returns an {@link NaryExpression} {@value #ADD} expression.
 183  
      * 
 184  
      * @param expressions
 185  
      *            The sub-expressions.
 186  
      * @return The {@link NaryExpression} {@value #ADD} expression.
 187  
      */
 188  
     public static NaryExpression add(final Expression... expressions) {
 189  3
         return new NaryExpression(ADD, expressions);
 190  
     }
 191  
 
 192  
     /**
 193  
      * Returns a {@link UnaryExpression} {@value #ALL_ELEMENTS_TRUE} expression.
 194  
      * 
 195  
      * @param expression
 196  
      *            The expression that will be evaluated to create the set to
 197  
      *            inspect for a true element.
 198  
      * @return The {@link UnaryExpression} {@value #ALL_ELEMENTS_TRUE}
 199  
      *         expression.
 200  
      */
 201  
     public static UnaryExpression allElementsTrue(final Expression expression) {
 202  1
         return new UnaryExpression(ALL_ELEMENTS_TRUE, expression);
 203  
     }
 204  
 
 205  
     /**
 206  
      * Returns an {@link NaryExpression} {@value #AND} expression.
 207  
      * 
 208  
      * @param expressions
 209  
      *            The sub-expressions.
 210  
      * @return The {@link NaryExpression} {@value #AND} expression.
 211  
      */
 212  
     public static NaryExpression and(final Expression... expressions) {
 213  1
         return new NaryExpression(AND, expressions);
 214  
     }
 215  
 
 216  
     /**
 217  
      * Returns a {@link UnaryExpression} {@value #ANY_ELEMENT_TRUE} expression.
 218  
      * 
 219  
      * @param expression
 220  
      *            The expression that will be evaluated to create the set to
 221  
      *            inspect for a true element.
 222  
      * @return The {@link UnaryExpression} {@value #ANY_ELEMENT_TRUE}
 223  
      *         expression.
 224  
      */
 225  
     public static UnaryExpression anyElementTrue(final Expression expression) {
 226  1
         return new UnaryExpression(ANY_ELEMENT_TRUE, expression);
 227  
     }
 228  
 
 229  
     /**
 230  
      * Returns a {@link NaryExpression} {@value #COMPARE} expression.
 231  
      * 
 232  
      * @param lhs
 233  
      *            The left hand side of the operation.
 234  
      * @param rhs
 235  
      *            The left hand side of the operation.
 236  
      * @return The {@link NaryExpression} {@value #COMPARE} expression.
 237  
      */
 238  
     public static NaryExpression cmp(final Expression lhs, final Expression rhs) {
 239  1
         return new NaryExpression(COMPARE, lhs, rhs);
 240  
     }
 241  
 
 242  
     /**
 243  
      * Returns a {@link NaryExpression} {@value #CONCATENATE} expression.
 244  
      * 
 245  
      * @param expression
 246  
      *            The string expressions for the operator.
 247  
      * @return The {@link NaryExpression} {@value #CONCATENATE} expression.
 248  
      * 
 249  
      * @since MongoDB 2.4
 250  
      */
 251  
     public static NaryExpression concatenate(final Expression... expression) {
 252  1
         return new NaryExpression(CONCATENATE, expression);
 253  
     }
 254  
 
 255  
     /**
 256  
      * Returns a {@link NaryExpression} {@value #CONDITION} expression.
 257  
      * 
 258  
      * @param test
 259  
      *            The conditions test.
 260  
      * @param trueResult
 261  
      *            The result if the test is true.
 262  
      * @param falseResult
 263  
      *            The result if the test is false.
 264  
      * @return The {@link NaryExpression} {@value #CONDITION} expression.
 265  
      */
 266  
     public static NaryExpression cond(final Expression test,
 267  
             final Expression trueResult, final Expression falseResult) {
 268  1
         return new NaryExpression(CONDITION, test, trueResult, falseResult);
 269  
     }
 270  
 
 271  
     /**
 272  
      * Returns a {@link Constant} expression with the provided <tt>value</tt>.
 273  
      * 
 274  
      * @param value
 275  
      *            The constants value.
 276  
      * @return The {@link Constant} expression.
 277  
      */
 278  
     public static Constant constant(final boolean value) {
 279  11
         return new Constant(new BooleanElement("", value));
 280  
     }
 281  
 
 282  
     /**
 283  
      * Returns a {@link Constant} expression with the provided <tt>value</tt>.
 284  
      * 
 285  
      * @param value
 286  
      *            The constants value.
 287  
      * @return The {@link Constant} expression.
 288  
      */
 289  
     public static Constant constant(final Date value) {
 290  1
         return constantTimestamp(value.getTime());
 291  
     }
 292  
 
 293  
     /**
 294  
      * Returns a {@link Constant} expression with the provided <tt>value</tt>.
 295  
      * 
 296  
      * @param value
 297  
      *            The constants value.
 298  
      * @return The {@link Constant} expression.
 299  
      */
 300  
     public static Constant constant(final double value) {
 301  1
         return new Constant(new DoubleElement("", value));
 302  
     }
 303  
 
 304  
     /**
 305  
      * Returns a {@link Constant} expression wrapping the provided
 306  
      * <tt>element</tt>. This method is intended mainly for wrapping arrays
 307  
      * using the {@link BuilderFactory#a} method.<blockquote>
 308  
      * 
 309  
      * <pre>
 310  
      * <code>
 311  
      * import static {@link BuilderFactory#a com.allanbank.mongodb.bson.builder.BuilderFactory.a}
 312  
      * import static {@link Expressions#constant com.allanbank.mongodb.builder.expression.Expressions.constant}
 313  
      * 
 314  
      * constant( a( "This", "is", "an", "array" ) );
 315  
      * </code>
 316  
      * </pre>
 317  
      * 
 318  
      * </blockquote>
 319  
      * 
 320  
      * @param element
 321  
      *            The element value.
 322  
      * @return The {@link Constant} expression.
 323  
      */
 324  
     public static Expression constant(final Element element) {
 325  3
         return new Constant(element);
 326  
     }
 327  
 
 328  
     /**
 329  
      * Returns a {@link Constant} expression with the provided <tt>value</tt>.
 330  
      * 
 331  
      * @param value
 332  
      *            The constants value.
 333  
      * @return The {@link Constant} expression.
 334  
      */
 335  
     public static Constant constant(final int value) {
 336  22
         return new Constant(new IntegerElement("", value));
 337  
     }
 338  
 
 339  
     /**
 340  
      * Returns a {@link Constant} expression with the provided <tt>value</tt>.
 341  
      * 
 342  
      * @param value
 343  
      *            The constants value.
 344  
      * @return The {@link Constant} expression.
 345  
      */
 346  
     public static Constant constant(final long value) {
 347  1
         return new Constant(new LongElement("", value));
 348  
     }
 349  
 
 350  
     /**
 351  
      * Returns a {@link Constant} expression with the provided <tt>value</tt>.
 352  
      * 
 353  
      * @param value
 354  
      *            The constants value.
 355  
      * @return The {@link Constant} expression.
 356  
      */
 357  
     public static Constant constant(final ObjectId value) {
 358  1
         return new Constant(new ObjectIdElement("", value));
 359  
     }
 360  
 
 361  
     /**
 362  
      * Returns a {@link Constant} expression with the provided <tt>value</tt>.
 363  
      * 
 364  
      * @param value
 365  
      *            The constants value.
 366  
      * @return The {@link Constant} expression.
 367  
      */
 368  
     public static Constant constant(final Pattern value) {
 369  1
         return new Constant(new RegularExpressionElement("", value));
 370  
     }
 371  
 
 372  
     /**
 373  
      * Returns a {@link Constant} expression with the provided <tt>value</tt>.
 374  
      * 
 375  
      * @param value
 376  
      *            The constants value.
 377  
      * @return The {@link Constant} expression.
 378  
      */
 379  
     public static Constant constant(final String value) {
 380  4
         return new Constant(new StringElement("", value));
 381  
     }
 382  
 
 383  
     /**
 384  
      * Returns a {@link Constant} expression with the provided <tt>value</tt>.
 385  
      * 
 386  
      * @param value
 387  
      *            The constants value.
 388  
      * @return The {@link Constant} expression.
 389  
      */
 390  
     public static Constant constantMongoTimestamp(final long value) {
 391  1
         return new Constant(new MongoTimestampElement("", value));
 392  
     }
 393  
 
 394  
     /**
 395  
      * Returns a {@link Constant} expression with the provided <tt>value</tt>.
 396  
      * 
 397  
      * @param value
 398  
      *            The constants value.
 399  
      * @return The {@link Constant} expression.
 400  
      */
 401  
     public static Constant constantTimestamp(final long value) {
 402  2
         return new Constant(new TimestampElement("", value));
 403  
     }
 404  
 
 405  
     /**
 406  
      * Returns a {@link UnaryExpression} {@value #DAY_OF_MONTH} expression.
 407  
      * 
 408  
      * @param expression
 409  
      *            The date for the operator.
 410  
      * @return The {@link UnaryExpression} {@value #DAY_OF_MONTH} expression.
 411  
      */
 412  
     public static UnaryExpression dayOfMonth(final Expression expression) {
 413  1
         return new UnaryExpression(DAY_OF_MONTH, expression);
 414  
     }
 415  
 
 416  
     /**
 417  
      * Returns a {@link UnaryExpression} {@value #DAY_OF_WEEK} expression.
 418  
      * 
 419  
      * @param expression
 420  
      *            The date for the operator.
 421  
      * @return The {@link UnaryExpression} {@value #DAY_OF_WEEK} expression.
 422  
      */
 423  
     public static UnaryExpression dayOfWeek(final Expression expression) {
 424  1
         return new UnaryExpression(DAY_OF_WEEK, expression);
 425  
     }
 426  
 
 427  
     /**
 428  
      * Returns a {@link UnaryExpression} {@value #DAY_OF_YEAR} expression.
 429  
      * 
 430  
      * @param expression
 431  
      *            The date for the operator.
 432  
      * @return The {@link UnaryExpression} {@value #DAY_OF_YEAR} expression.
 433  
      */
 434  
     public static UnaryExpression dayOfYear(final Expression expression) {
 435  1
         return new UnaryExpression(DAY_OF_YEAR, expression);
 436  
     }
 437  
 
 438  
     /**
 439  
      * Returns a {@link NaryExpression} {@value #DIVIDE} expression.
 440  
      * 
 441  
      * @param numerator
 442  
      *            The numerator of the division.
 443  
      * @param denominator
 444  
      *            The denominator of the division.
 445  
      * @return The {@link NaryExpression} {@value #DIVIDE} expression.
 446  
      */
 447  
     public static NaryExpression divide(final Expression numerator,
 448  
             final Expression denominator) {
 449  2
         return new NaryExpression(DIVIDE, numerator, denominator);
 450  
     }
 451  
 
 452  
     /**
 453  
      * Returns a {@link NaryExpression} {@value #EQUAL} expression.
 454  
      * 
 455  
      * @param lhs
 456  
      *            The left hand side of the equals.
 457  
      * @param rhs
 458  
      *            The right hand side of the equals.
 459  
      * @return The {@link NaryExpression} {@value #EQUAL} expression.
 460  
      */
 461  
     public static NaryExpression eq(final Expression lhs, final Expression rhs) {
 462  1
         return new NaryExpression(EQUAL, lhs, rhs);
 463  
     }
 464  
 
 465  
     /**
 466  
      * Returns a {@link Constant} expression with the provided
 467  
      * <tt>fieldName</tt>.
 468  
      * <p>
 469  
      * Prepends a {@code $} to the field name if not already present.
 470  
      * </p>
 471  
      * <blockquote>
 472  
      * 
 473  
      * <pre>
 474  
      * <code>
 475  
      * Constant field = Expressions.field("field");
 476  
      * 
 477  
      * // Produces output: 
 478  
      * //      $field
 479  
      * System.out.println(field);
 480  
      * </code>
 481  
      * </pre>
 482  
      * 
 483  
      * </blockquote>
 484  
      * 
 485  
      * @param fieldName
 486  
      *            The name of the field.
 487  
      * @return The {@link Constant} expression.
 488  
      */
 489  
     public static Constant field(final String fieldName) {
 490  14
         if (fieldName.startsWith("$")) {
 491  1
             return new Constant(new StringElement("", fieldName));
 492  
         }
 493  13
         return new Constant(new StringElement("", "$" + fieldName));
 494  
     }
 495  
 
 496  
     /**
 497  
      * Returns a {@link NaryExpression} {@value #GREATER_THAN} expression.
 498  
      * 
 499  
      * @param lhs
 500  
      *            The left hand side of the comparison.
 501  
      * @param rhs
 502  
      *            The right hand side of the comparison.
 503  
      * @return The {@link NaryExpression} {@value #GREATER_THAN} expression.
 504  
      */
 505  
     public static NaryExpression gt(final Expression lhs, final Expression rhs) {
 506  1
         return new NaryExpression(GREATER_THAN, lhs, rhs);
 507  
     }
 508  
 
 509  
     /**
 510  
      * Returns a {@link NaryExpression} {@value #GREATER_THAN_OR_EQUAL}
 511  
      * expression.
 512  
      * 
 513  
      * @param lhs
 514  
      *            The left hand side of the comparison.
 515  
      * @param rhs
 516  
      *            The right hand side of the comparison.
 517  
      * @return The {@link NaryExpression} {@value #GREATER_THAN_OR_EQUAL}
 518  
      *         expression.
 519  
      */
 520  
     public static NaryExpression gte(final Expression lhs, final Expression rhs) {
 521  1
         return new NaryExpression(GREATER_THAN_OR_EQUAL, lhs, rhs);
 522  
     }
 523  
 
 524  
     /**
 525  
      * Returns a {@link UnaryExpression} {@value #HOUR} expression.
 526  
      * 
 527  
      * @param expression
 528  
      *            The date for the operator.
 529  
      * @return The {@link UnaryExpression} {@value #HOUR} expression.
 530  
      */
 531  
     public static UnaryExpression hour(final Expression expression) {
 532  1
         return new UnaryExpression(HOUR, expression);
 533  
     }
 534  
 
 535  
     /**
 536  
      * Returns a {@link NaryExpression} {@value #IF_NULL} expression.
 537  
      * 
 538  
      * @param first
 539  
      *            The first expression.
 540  
      * @param second
 541  
      *            The second expression.
 542  
      * @return The {@link NaryExpression} {@value #IF_NULL} expression.
 543  
      */
 544  
     public static NaryExpression ifNull(final Expression first,
 545  
             final Expression second) {
 546  3
         return new NaryExpression(IF_NULL, first, second);
 547  
     }
 548  
 
 549  
     /**
 550  
      * Creates a {@code $let} expression with the provided variables and
 551  
      * {@code in} expression.
 552  
      * <p>
 553  
      * Here is the <a href=
 554  
      * "http://docs.mongodb.org/master/reference/operator/aggregation/let/">
 555  
      * <code>let</code> expression's documentation</a> aggregation pipe line
 556  
      * using this helper class. <blockquote>
 557  
      * 
 558  
      * <pre>
 559  
      * <code>
 560  
      * import static com.allanbank.mongodb.builder.AggregationProjectFields.include;
 561  
      * import static {@link Expressions#add com.allanbank.mongodb.builder.expression.Expressions.add};
 562  
      * import static {@link Expressions#cond com.allanbank.mongodb.builder.expression.Expressions.cond};
 563  
      * import static {@link Expressions#constant com.allanbank.mongodb.builder.expression.Expressions.constant};
 564  
      * import static {@link Expressions#field com.allanbank.mongodb.builder.expression.Expressions.field};
 565  
      * import static {@link Expressions#let com.allanbank.mongodb.builder.expression.Expressions.let};
 566  
      * import static {@link Expressions#multiply com.allanbank.mongodb.builder.expression.Expressions.multiply};
 567  
      * import static {@link Expressions#set com.allanbank.mongodb.builder.expression.Expressions.set};
 568  
      * import static {@link Expressions#var com.allanbank.mongodb.builder.expression.Expressions.var};
 569  
      * 
 570  
      * Aggregate.Builder aggregate = Aggregate.builder();
 571  
      * 
 572  
      * //   $project: {
 573  
      * //      finalTotal: {
 574  
      * //         $let: {
 575  
      * //            vars: {
 576  
      * //               total: { $add: [ '$price', '$tax' ] },
 577  
      * //               discounted: { $cond: { if: '$applyDiscount', then: 0.9, else: 1 } }
 578  
      * //            },
 579  
      * //            in: { $multiply: [ "$$total", "$$discounted" ] }
 580  
      * //         }
 581  
      * //      }
 582  
      * //   }
 583  
      * final Aggregate.Builder aggregation = Aggregate.builder();
 584  
      * aggregation.project(
 585  
      *         include(),
 586  
      *         set("finalTotal",
 587  
      *                 let(
 588  
      *                    multiply(var("total"), var("discounted"))
 589  
      *                    set("total", add(field("price"), field("tax"))),
 590  
      *                    set("discounted",
 591  
      *                         cond(field("applyDiscount"), constant(0.9),
 592  
      *                                 constant(1))))));
 593  
      * 
 594  
      * // Aggregation Pipeline : '$pipeline' : [
 595  
      * //   {
 596  
      * //     '$project' : {
 597  
      * //       finalTotal : {
 598  
      * //         '$let' : {
 599  
      * //           vars : {
 600  
      * //             total : {
 601  
      * //               '$add' : [
 602  
      * //                 '$price', 
 603  
      * //                 '$tax'
 604  
      * //               ]
 605  
      * //             },
 606  
      * //             discounted : {
 607  
      * //               '$cond' : [
 608  
      * //                 '$applyDiscount', 
 609  
      * //                 0.9, 
 610  
      * //                 1
 611  
      * //               ]
 612  
      * //             }
 613  
      * //           },
 614  
      * //           in : {
 615  
      * //             '$multiply' : [
 616  
      * //               '$$total', 
 617  
      * //               '$$discounted'
 618  
      * //             ]
 619  
      * //           }
 620  
      * //         }
 621  
      * //       }
 622  
      * //     }
 623  
      * //   }
 624  
      * // ]
 625  
      * System.out.println("Aggregation Pipeline : " + aggregation);
 626  
      * </code>
 627  
      * </pre>
 628  
      * 
 629  
      * </blockquote>
 630  
      * 
 631  
      * @param inExpression
 632  
      *            The expression to be evaluated with the variables within the
 633  
      *            {@code $let} expression.
 634  
      * @param variables
 635  
      *            The variables for the {@code $let} expression.
 636  
      * @return The Element to set the value to the document.
 637  
      */
 638  
     public static UnaryExpression let(final Expression inExpression,
 639  
             final Element... variables) {
 640  1
         return let(Arrays.asList(variables), inExpression);
 641  
     }
 642  
 
 643  
     /**
 644  
      * Creates a {@code $let} expression with the provided variables and
 645  
      * {@code in} expression.
 646  
      * <p>
 647  
      * Here is the <a href=
 648  
      * "http://docs.mongodb.org/master/reference/operator/aggregation/let/">
 649  
      * <code>let</code> expression's documentation</a> aggregation pipe line
 650  
      * using this helper class. <blockquote>
 651  
      * 
 652  
      * <pre>
 653  
      * <code>
 654  
      * import static com.allanbank.mongodb.builder.AggregationProjectFields.include;
 655  
      * import static {@link Expressions#add com.allanbank.mongodb.builder.expression.Expressions.add};
 656  
      * import static {@link Expressions#cond com.allanbank.mongodb.builder.expression.Expressions.cond};
 657  
      * import static {@link Expressions#constant com.allanbank.mongodb.builder.expression.Expressions.constant};
 658  
      * import static {@link Expressions#field com.allanbank.mongodb.builder.expression.Expressions.field};
 659  
      * import static {@link Expressions#let com.allanbank.mongodb.builder.expression.Expressions.let};
 660  
      * import static {@link Expressions#multiply com.allanbank.mongodb.builder.expression.Expressions.multiply};
 661  
      * import static {@link Expressions#set com.allanbank.mongodb.builder.expression.Expressions.set};
 662  
      * import static {@link Expressions#var com.allanbank.mongodb.builder.expression.Expressions.var};
 663  
      * 
 664  
      * Aggregate.Builder aggregate = Aggregate.builder();
 665  
      * 
 666  
      * //   $project: {
 667  
      * //      finalTotal: {
 668  
      * //         $let: {
 669  
      * //            vars: {
 670  
      * //               total: { $add: [ '$price', '$tax' ] },
 671  
      * //               discounted: { $cond: { if: '$applyDiscount', then: 0.9, else: 1 } }
 672  
      * //            },
 673  
      * //            in: { $multiply: [ "$$total", "$$discounted" ] }
 674  
      * //         }
 675  
      * //      }
 676  
      * //   }
 677  
      * final Aggregate.Builder aggregation = Aggregate.builder();
 678  
      * aggregation.project(
 679  
      *         include(),
 680  
      *         set("finalTotal",
 681  
      *                 let(
 682  
      *                    Arrays.asList(
 683  
      *                       set("total", add(field("price"), field("tax"))),
 684  
      *                       set("discounted",
 685  
      *                          cond(field("applyDiscount"), constant(0.9),
 686  
      *                                 constant(1))))
 687  
      *                    multiply(var("total"), var("discounted")))));
 688  
      * 
 689  
      * // Aggregation Pipeline : '$pipeline' : [
 690  
      * //   {
 691  
      * //     '$project' : {
 692  
      * //       finalTotal : {
 693  
      * //         '$let' : {
 694  
      * //           vars : {
 695  
      * //             total : {
 696  
      * //               '$add' : [
 697  
      * //                 '$price', 
 698  
      * //                 '$tax'
 699  
      * //               ]
 700  
      * //             },
 701  
      * //             discounted : {
 702  
      * //               '$cond' : [
 703  
      * //                 '$applyDiscount', 
 704  
      * //                 0.9, 
 705  
      * //                 1
 706  
      * //               ]
 707  
      * //             }
 708  
      * //           },
 709  
      * //           in : {
 710  
      * //             '$multiply' : [
 711  
      * //               '$$total', 
 712  
      * //               '$$discounted'
 713  
      * //             ]
 714  
      * //           }
 715  
      * //         }
 716  
      * //       }
 717  
      * //     }
 718  
      * //   }
 719  
      * // ]
 720  
      * System.out.println("Aggregation Pipeline : " + aggregation);
 721  
      * </code>
 722  
      * </pre>
 723  
      * 
 724  
      * </blockquote>
 725  
      * 
 726  
      * @param variables
 727  
      *            The variables for the {@code $let} expression.
 728  
      * @param inExpression
 729  
      *            The expression to be evaluated with the variables within the
 730  
      *            {@code $let} expression.
 731  
      * @return The Element to set the value to the document.
 732  
      */
 733  
     public static UnaryExpression let(final List<Element> variables,
 734  
             final Expression inExpression) {
 735  5
         final DocumentAssignable letDocument = d(new DocumentElement("vars",
 736  
                 variables), inExpression.toElement("in"));
 737  
 
 738  5
         return new UnaryExpression("$let", new Constant(new DocumentElement(
 739  
                 "$let", letDocument.asDocument())));
 740  
     }
 741  
 
 742  
     /**
 743  
      * Starts the creation of a {@code $let} expression. The returned
 744  
      * {@link LetBuilder} can be used to add additional variables before setting
 745  
      * the {@link LetBuilder#in final expression} to evaluate.
 746  
      * <p>
 747  
      * Here is the <a href=
 748  
      * "http://docs.mongodb.org/master/reference/operator/aggregation/let/">
 749  
      * <code>let</code> expression's documentation</a> aggregation pipe line
 750  
      * using this helper class. <blockquote>
 751  
      * 
 752  
      * <pre>
 753  
      * <code>
 754  
      * import static com.allanbank.mongodb.builder.AggregationProjectFields.include;
 755  
      * import static {@link Expressions#add com.allanbank.mongodb.builder.expression.Expressions.add};
 756  
      * import static {@link Expressions#cond com.allanbank.mongodb.builder.expression.Expressions.cond};
 757  
      * import static {@link Expressions#constant com.allanbank.mongodb.builder.expression.Expressions.constant};
 758  
      * import static {@link Expressions#field com.allanbank.mongodb.builder.expression.Expressions.field};
 759  
      * import static {@link Expressions#let com.allanbank.mongodb.builder.expression.Expressions.let};
 760  
      * import static {@link Expressions#multiply com.allanbank.mongodb.builder.expression.Expressions.multiply};
 761  
      * import static {@link Expressions#set com.allanbank.mongodb.builder.expression.Expressions.set};
 762  
      * import static {@link Expressions#var com.allanbank.mongodb.builder.expression.Expressions.var};
 763  
      * 
 764  
      * Aggregate.Builder aggregate = Aggregate.builder();
 765  
      * 
 766  
      * //   $project: {
 767  
      * //      finalTotal: {
 768  
      * //         $let: {
 769  
      * //            vars: {
 770  
      * //               total: { $add: [ '$price', '$tax' ] },
 771  
      * //               discounted: { $cond: { if: '$applyDiscount', then: 0.9, else: 1 } }
 772  
      * //            },
 773  
      * //            in: { $multiply: [ "$$total", "$$discounted" ] }
 774  
      * //         }
 775  
      * //      }
 776  
      * //   }
 777  
      * final Aggregate.Builder aggregation = Aggregate.builder();
 778  
      * aggregation.project(
 779  
      *         include(),
 780  
      *         set("finalTotal",
 781  
      *                         let("total", add(field("price"), field("tax")))
 782  
      *                            .let("discounted", cond(field("applyDiscount"), 
 783  
      *                                                    constant(0.9),
 784  
      *                                                    constant(1)))
 785  
      *                            .in(multiply(var("total"), var("discounted")))));
 786  
      * 
 787  
      * // Aggregation Pipeline : '$pipeline' : [
 788  
      * //   {
 789  
      * //     '$project' : {
 790  
      * //       finalTotal : {
 791  
      * //         '$let' : {
 792  
      * //           vars : {
 793  
      * //             total : {
 794  
      * //               '$add' : [
 795  
      * //                 '$price', 
 796  
      * //                 '$tax'
 797  
      * //               ]
 798  
      * //             },
 799  
      * //             discounted : {
 800  
      * //               '$cond' : [
 801  
      * //                 '$applyDiscount', 
 802  
      * //                 0.9, 
 803  
      * //                 1
 804  
      * //               ]
 805  
      * //             }
 806  
      * //           },
 807  
      * //           in : {
 808  
      * //             '$multiply' : [
 809  
      * //               '$$total', 
 810  
      * //               '$$discounted'
 811  
      * //             ]
 812  
      * //           }
 813  
      * //         }
 814  
      * //       }
 815  
      * //     }
 816  
      * //   }
 817  
      * // ]
 818  
      * System.out.println("Aggregation Pipeline : " + aggregation);
 819  
      * </code>
 820  
      * </pre>
 821  
      * 
 822  
      * </blockquote>
 823  
      * 
 824  
      * @param name
 825  
      *            The name of the first field to set.
 826  
      * @param document
 827  
      *            The document to set the first field value to.
 828  
      * @return The Element to set the value to the document.
 829  
      */
 830  
     public static LetBuilder let(final String name,
 831  
             final DocumentAssignable document) {
 832  1
         return new LetBuilder(new DocumentElement(name, document.asDocument()));
 833  
     }
 834  
 
 835  
     /**
 836  
      * Starts the creation of a {@code $let} expression. The returned
 837  
      * {@link LetBuilder} can be used to add additional variables before setting
 838  
      * the {@link LetBuilder#in final expression} to evaluate.
 839  
      * <p>
 840  
      * Here is the <a href=
 841  
      * "http://docs.mongodb.org/master/reference/operator/aggregation/let/">
 842  
      * <code>let</code> expression's documentation</a> aggregation pipe line
 843  
      * using this helper class. <blockquote>
 844  
      * 
 845  
      * <pre>
 846  
      * <code>
 847  
      * import static com.allanbank.mongodb.builder.AggregationProjectFields.include;
 848  
      * import static {@link Expressions#add com.allanbank.mongodb.builder.expression.Expressions.add};
 849  
      * import static {@link Expressions#cond com.allanbank.mongodb.builder.expression.Expressions.cond};
 850  
      * import static {@link Expressions#constant com.allanbank.mongodb.builder.expression.Expressions.constant};
 851  
      * import static {@link Expressions#field com.allanbank.mongodb.builder.expression.Expressions.field};
 852  
      * import static {@link Expressions#let com.allanbank.mongodb.builder.expression.Expressions.let};
 853  
      * import static {@link Expressions#multiply com.allanbank.mongodb.builder.expression.Expressions.multiply};
 854  
      * import static {@link Expressions#set com.allanbank.mongodb.builder.expression.Expressions.set};
 855  
      * import static {@link Expressions#var com.allanbank.mongodb.builder.expression.Expressions.var};
 856  
      * 
 857  
      * Aggregate.Builder aggregate = Aggregate.builder();
 858  
      * 
 859  
      * //   $project: {
 860  
      * //      finalTotal: {
 861  
      * //         $let: {
 862  
      * //            vars: {
 863  
      * //               total: { $add: [ '$price', '$tax' ] },
 864  
      * //               discounted: { $cond: { if: '$applyDiscount', then: 0.9, else: 1 } }
 865  
      * //            },
 866  
      * //            in: { $multiply: [ "$$total", "$$discounted" ] }
 867  
      * //         }
 868  
      * //      }
 869  
      * //   }
 870  
      * final Aggregate.Builder aggregation = Aggregate.builder();
 871  
      * aggregation.project(
 872  
      *         include(),
 873  
      *         set("finalTotal",
 874  
      *                         let("total", add(field("price"), field("tax")))
 875  
      *                            .let("discounted", cond(field("applyDiscount"), 
 876  
      *                                                    constant(0.9),
 877  
      *                                                    constant(1)))
 878  
      *                            .in(multiply(var("total"), var("discounted")))));
 879  
      * 
 880  
      * // Aggregation Pipeline : '$pipeline' : [
 881  
      * //   {
 882  
      * //     '$project' : {
 883  
      * //       finalTotal : {
 884  
      * //         '$let' : {
 885  
      * //           vars : {
 886  
      * //             total : {
 887  
      * //               '$add' : [
 888  
      * //                 '$price', 
 889  
      * //                 '$tax'
 890  
      * //               ]
 891  
      * //             },
 892  
      * //             discounted : {
 893  
      * //               '$cond' : [
 894  
      * //                 '$applyDiscount', 
 895  
      * //                 0.9, 
 896  
      * //                 1
 897  
      * //               ]
 898  
      * //             }
 899  
      * //           },
 900  
      * //           in : {
 901  
      * //             '$multiply' : [
 902  
      * //               '$$total', 
 903  
      * //               '$$discounted'
 904  
      * //             ]
 905  
      * //           }
 906  
      * //         }
 907  
      * //       }
 908  
      * //     }
 909  
      * //   }
 910  
      * // ]
 911  
      * System.out.println("Aggregation Pipeline : " + aggregation);
 912  
      * </code>
 913  
      * </pre>
 914  
      * 
 915  
      * </blockquote>
 916  
      * 
 917  
      * @param name
 918  
      *            The name of the field to set.
 919  
      * @param expression
 920  
      *            The expression to compute the value for the first field.
 921  
      * @return The Element to set the value to the expression.
 922  
      */
 923  
     public static LetBuilder let(final String name, final Expression expression) {
 924  2
         return new LetBuilder(expression.toElement(name));
 925  
     }
 926  
 
 927  
     /**
 928  
      * Returns a {@link Constant} expression wrapping the <tt>value</tt> in a
 929  
      * {@value #LITERAL} sub-document.
 930  
      * 
 931  
      * @param value
 932  
      *            The constants value.
 933  
      * @return The {@link Constant} expression.
 934  
      */
 935  
     public static Constant literal(final String value) {
 936  1
         return new Constant(new DocumentElement("", new StringElement(
 937  
                 "$literal", value)));
 938  
     }
 939  
 
 940  
     /**
 941  
      * Returns a {@link NaryExpression} {@value #LESS_THAN} expression.
 942  
      * 
 943  
      * @param lhs
 944  
      *            The left hand side of the comparison.
 945  
      * @param rhs
 946  
      *            The right hand side of the comparison.
 947  
      * @return The {@link NaryExpression} {@value #LESS_THAN} expression.
 948  
      */
 949  
     public static NaryExpression lt(final Expression lhs, final Expression rhs) {
 950  1
         return new NaryExpression(LESS_THAN, lhs, rhs);
 951  
     }
 952  
 
 953  
     /**
 954  
      * Returns a {@link NaryExpression} {@value #LESS_THAN_OR_EQUAL} expression.
 955  
      * 
 956  
      * @param lhs
 957  
      *            The left hand side of the comparison.
 958  
      * @param rhs
 959  
      *            The right hand side of the comparison.
 960  
      * @return The {@link NaryExpression} {@value #LESS_THAN} expression.
 961  
      */
 962  
     public static NaryExpression lte(final Expression lhs, final Expression rhs) {
 963  1
         return new NaryExpression(LESS_THAN_OR_EQUAL, lhs, rhs);
 964  
     }
 965  
 
 966  
     /**
 967  
      * Returns a {@link UnaryExpression} expression for the {@code $map}
 968  
      * operation.
 969  
      * <p>
 970  
      * Prepends a {@code $} to the {@code inputField} name if not already
 971  
      * present.
 972  
      * </p>
 973  
      * <p>
 974  
      * Here is the <a href=
 975  
      * "http://docs.mongodb.org/master/reference/operator/aggregation/map/">
 976  
      * <code>map</code> expression's documentation</a> aggregation pipe line
 977  
      * using this helper class. <blockquote>
 978  
      * 
 979  
      * <pre>
 980  
      * <code>
 981  
      * import static com.allanbank.mongodb.builder.AggregationProjectFields.include;
 982  
      * import static {@link Expressions#map(String,String,Expression) com.allanbank.mongodb.builder.expression.Expressions.map};
 983  
      * import static {@link Expressions#set(String,Expression) com.allanbank.mongodb.builder.expression.Expressions.set};
 984  
      * import static {@link Expressions#add(Expression...) com.allanbank.mongodb.builder.expression.Expressions.add};
 985  
      * import static {@link Expressions#var(String) com.allanbank.mongodb.builder.expression.Expressions.var};
 986  
      * import static {@link Expressions#constant(int) com.allanbank.mongodb.builder.expression.Expressions.constant};
 987  
      * 
 988  
      * Aggregate.Builder aggregate = Aggregate.builder();
 989  
      * 
 990  
      * // { $project: { adjustments: { $map: { input: "$skews",
 991  
      * //                            as: "adj",
 992  
      * //                            in: { $add: [ "$$adj", 12 ] } } } } }
 993  
      * aggregate.project(
 994  
      *     include(),
 995  
      *     set( "adjustments", 
 996  
      *         map("skews").as("adj").in( add( var("adj"), constant(12) ) ) ) );
 997  
      * 
 998  
      * // Produces output: 
 999  
      * //    {
 1000  
      * //       '$project' : {
 1001  
      * //          adjustments : {
 1002  
      * //             '$map' {
 1003  
      * //                input : '$skews',
 1004  
      * //                as : 'adj',
 1005  
      * //                in : {
 1006  
      * //                   '$add' : [
 1007  
      * //                      '$$adj',
 1008  
      * //                      12
 1009  
      * //                   ]
 1010  
      * //                }
 1011  
      * //             }
 1012  
      * //          }
 1013  
      * //       }
 1014  
      * //    }
 1015  
      * System.out.println(aggregate);
 1016  
      * </code>
 1017  
      * </pre>
 1018  
      * 
 1019  
      * </blockquote>
 1020  
      * 
 1021  
      * @param inputField
 1022  
      *            The name of the {@code input} field. The map operation
 1023  
      *            expression.
 1024  
      * @return The first stage of the {@code $map} expression construction.
 1025  
      * 
 1026  
      * @see <a
 1027  
      *      href="http://docs.mongodb.org/master/reference/operator/aggregation/map/"><code>map</code>
 1028  
      *      expression documentation</a>
 1029  
      */
 1030  
     public static MapStage1 map(final String inputField) {
 1031  1
         return new MapStage1(inputField);
 1032  
     }
 1033  
 
 1034  
     /**
 1035  
      * Returns a {@link UnaryExpression} expression for the {@code $map}
 1036  
      * operation.
 1037  
      * <p>
 1038  
      * Prepends a {@code $} to the {@code inputField} name if not already
 1039  
      * present.
 1040  
      * </p>
 1041  
      * <p>
 1042  
      * Here is the <a href=
 1043  
      * "http://docs.mongodb.org/master/reference/operator/aggregation/map/">
 1044  
      * <code>map</code> expression's documentation</a> aggregation pipe line
 1045  
      * using this helper class. <blockquote>
 1046  
      * 
 1047  
      * <pre>
 1048  
      * <code>
 1049  
      * import static com.allanbank.mongodb.builder.AggregationProjectFields.include;
 1050  
      * import static {@link Expressions#map(String,String,Expression) com.allanbank.mongodb.builder.expression.Expressions.map};
 1051  
      * import static {@link Expressions#set(String,Expression) com.allanbank.mongodb.builder.expression.Expressions.set};
 1052  
      * import static {@link Expressions#add(Expression...) com.allanbank.mongodb.builder.expression.Expressions.add};
 1053  
      * import static {@link Expressions#var(String) com.allanbank.mongodb.builder.expression.Expressions.var};
 1054  
      * import static {@link Expressions#constant(int) com.allanbank.mongodb.builder.expression.Expressions.constant};
 1055  
      * 
 1056  
      * Aggregate.Builder aggregate = Aggregate.builder();
 1057  
      * 
 1058  
      * // { $project: { adjustments: { $map: { input: "$skews",
 1059  
      * //                            as: "adj",
 1060  
      * //                            in: { $add: [ "$$adj", 12 ] } } } } }
 1061  
      * aggregate.project(
 1062  
      *     include(),
 1063  
      *     set( "adjustments", 
 1064  
      *         map( "skews", "adj",
 1065  
      *            add( var("adj"), constant(12) ) ) ) );
 1066  
      * 
 1067  
      * // Produces output: 
 1068  
      * //    {
 1069  
      * //       '$project' : {
 1070  
      * //          adjustments : {
 1071  
      * //             '$map' {
 1072  
      * //                input : '$skews',
 1073  
      * //                as : 'adj',
 1074  
      * //                in : {
 1075  
      * //                   '$add' : [
 1076  
      * //                      '$$adj',
 1077  
      * //                      12
 1078  
      * //                   ]
 1079  
      * //                }
 1080  
      * //             }
 1081  
      * //          }
 1082  
      * //       }
 1083  
      * //    }
 1084  
      * System.out.println(aggregate);
 1085  
      * </code>
 1086  
      * </pre>
 1087  
      * 
 1088  
      * </blockquote>
 1089  
      * 
 1090  
      * @param inputField
 1091  
      *            The name of the {@code input} field.
 1092  
      * @param variableName
 1093  
      *            The name of the {@code as} variable.
 1094  
      * @param mapOperation
 1095  
      *            The map operation expression.
 1096  
      * @return The {@link UnaryExpression} expression.
 1097  
      * 
 1098  
      * @see <a
 1099  
      *      href="http://docs.mongodb.org/master/reference/operator/aggregation/map/"><code>map</code>
 1100  
      *      expression documentation</a>
 1101  
      */
 1102  
     public static UnaryExpression map(final String inputField,
 1103  
             final String variableName, final Expression mapOperation) {
 1104  
 
 1105  2
         final DocumentAssignable mapDocument = d(
 1106  
                 field(inputField).toElement("input"), constant(variableName)
 1107  
                         .toElement("as"), mapOperation.toElement("in"));
 1108  
 
 1109  2
         return new UnaryExpression("$map", new Constant(new DocumentElement(
 1110  
                 "$map", mapDocument.asDocument())));
 1111  
     }
 1112  
 
 1113  
     /**
 1114  
      * Returns a {@link UnaryExpression} {@value #MILLISECOND} expression.
 1115  
      * 
 1116  
      * @param expression
 1117  
      *            The date for the operator.
 1118  
      * @return The {@link UnaryExpression} {@value #MILLISECOND} expression.
 1119  
      */
 1120  
     public static UnaryExpression millisecond(final Expression expression) {
 1121  1
         return new UnaryExpression(MILLISECOND, expression);
 1122  
     }
 1123  
 
 1124  
     /**
 1125  
      * Returns a {@link UnaryExpression} {@value #MINUTE} expression.
 1126  
      * 
 1127  
      * @param expression
 1128  
      *            The date for the operator.
 1129  
      * @return The {@link UnaryExpression} {@value #MINUTE} expression.
 1130  
      */
 1131  
     public static UnaryExpression minute(final Expression expression) {
 1132  1
         return new UnaryExpression(MINUTE, expression);
 1133  
     }
 1134  
 
 1135  
     /**
 1136  
      * Returns a {@link NaryExpression} {@value #MODULO} expression.
 1137  
      * 
 1138  
      * @param numerator
 1139  
      *            The numerator of the modulo operation.
 1140  
      * @param denominator
 1141  
      *            The denominator of the modulo operation.
 1142  
      * @return The {@link NaryExpression} {@value #MODULO} expression.
 1143  
      */
 1144  
     public static NaryExpression mod(final Expression numerator,
 1145  
             final Expression denominator) {
 1146  2
         return new NaryExpression(MODULO, numerator, denominator);
 1147  
     }
 1148  
 
 1149  
     /**
 1150  
      * Returns a {@link UnaryExpression} {@value #MONTH} expression.
 1151  
      * 
 1152  
      * @param expression
 1153  
      *            The date for the operator.
 1154  
      * @return The {@link UnaryExpression} {@value #MONTH} expression.
 1155  
      */
 1156  
     public static UnaryExpression month(final Expression expression) {
 1157  1
         return new UnaryExpression(MONTH, expression);
 1158  
     }
 1159  
 
 1160  
     /**
 1161  
      * Returns a {@link NaryExpression} {@value #MULTIPLY} expression.
 1162  
      * 
 1163  
      * @param lhs
 1164  
      *            The left hand side of the operator.
 1165  
      * @param rhs
 1166  
      *            The right hand side of the operator.
 1167  
      * @return The {@link NaryExpression} {@value #MULTIPLY} expression.
 1168  
      */
 1169  
     public static NaryExpression multiply(final Expression lhs,
 1170  
             final Expression rhs) {
 1171  2
         return new NaryExpression(MULTIPLY, lhs, rhs);
 1172  
     }
 1173  
 
 1174  
     /**
 1175  
      * Returns a {@link NaryExpression} {@value #NOT_EQUAL} expression.
 1176  
      * 
 1177  
      * @param lhs
 1178  
      *            The left hand side of the comparison.
 1179  
      * @param rhs
 1180  
      *            The right hand side of the comparison.
 1181  
      * @return The {@link NaryExpression} {@value #NOT_EQUAL} expression.
 1182  
      */
 1183  
     public static NaryExpression ne(final Expression lhs, final Expression rhs) {
 1184  1
         return new NaryExpression(NOT_EQUAL, lhs, rhs);
 1185  
     }
 1186  
 
 1187  
     /**
 1188  
      * Returns a {@link UnaryExpression} {@value #NOT} expression.
 1189  
      * 
 1190  
      * @param expression
 1191  
      *            The sub expressions for the $not.
 1192  
      * @return The {@link UnaryExpression} {@value #NOT} expression.
 1193  
      */
 1194  
     public static UnaryExpression not(final Expression expression) {
 1195  1
         return new UnaryExpression(NOT, expression);
 1196  
     }
 1197  
 
 1198  
     /**
 1199  
      * Returns a <code>null</code> {@link Constant} expression.
 1200  
      * 
 1201  
      * @return The {@link Constant} expression.
 1202  
      */
 1203  
     public static Constant nullConstant() {
 1204  1
         return new Constant(new NullElement(""));
 1205  
     }
 1206  
 
 1207  
     /**
 1208  
      * Returns an {@link NaryExpression} {@value #OR} expression.
 1209  
      * 
 1210  
      * @param expressions
 1211  
      *            The sub-expressions.
 1212  
      * @return The {@link NaryExpression} {@value #OR} expression.
 1213  
      */
 1214  
     public static NaryExpression or(final Expression... expressions) {
 1215  1
         return new NaryExpression(OR, expressions);
 1216  
     }
 1217  
 
 1218  
     /**
 1219  
      * Returns a {@link UnaryExpression} {@value #SECOND} expression.
 1220  
      * 
 1221  
      * @param expression
 1222  
      *            The date for the operator.
 1223  
      * @return The {@link UnaryExpression} {@value #SECOND} expression.
 1224  
      */
 1225  
     public static UnaryExpression second(final Expression expression) {
 1226  2
         return new UnaryExpression(SECOND, expression);
 1227  
     }
 1228  
 
 1229  
     /**
 1230  
      * Returns an element to set the value to.
 1231  
      * 
 1232  
      * @param name
 1233  
      *            The name of the field to set.
 1234  
      * @param document
 1235  
      *            The document to set the document to.
 1236  
      * @return The Element to set the value to the document.
 1237  
      */
 1238  
     public static Element set(final String name,
 1239  
             final DocumentAssignable document) {
 1240  1
         return new DocumentElement(name, document.asDocument());
 1241  
     }
 1242  
 
 1243  
     /**
 1244  
      * Returns an element to set the value to.
 1245  
      * 
 1246  
      * @param name
 1247  
      *            The name of the field to set.
 1248  
      * @param expression
 1249  
      *            The expression to compute the value for the field.
 1250  
      * @return The Element to set the value to the expression.
 1251  
      */
 1252  
     public static Element set(final String name, final Expression expression) {
 1253  14
         return expression.toElement(name);
 1254  
     }
 1255  
 
 1256  
     /**
 1257  
      * Returns a {@link NaryExpression} {@value #SET_DIFFERENCE} expression.
 1258  
      * 
 1259  
      * @param lhs
 1260  
      *            The expression that will be evaluated to create the first set.
 1261  
      * @param rhs
 1262  
      *            The expression that will be evaluated to create the second
 1263  
      *            set.
 1264  
      * @return The {@link NaryExpression} {@value #SET_DIFFERENCE} expression.
 1265  
      */
 1266  
     public static NaryExpression setDifference(final Expression lhs,
 1267  
             final Expression rhs) {
 1268  1
         return new NaryExpression(SET_DIFFERENCE, lhs, rhs);
 1269  
     }
 1270  
 
 1271  
     /**
 1272  
      * Returns a {@link NaryExpression} {@value #SET_EQUALS} expression.
 1273  
      * 
 1274  
      * @param lhs
 1275  
      *            The expression that will be evaluated to create the first set.
 1276  
      * @param rhs
 1277  
      *            The expression that will be evaluated to create the second
 1278  
      *            set.
 1279  
      * @return The {@link NaryExpression} {@value #SET_EQUALS} expression.
 1280  
      */
 1281  
     public static NaryExpression setEquals(final Expression lhs,
 1282  
             final Expression rhs) {
 1283  1
         return new NaryExpression(SET_EQUALS, lhs, rhs);
 1284  
     }
 1285  
 
 1286  
     /**
 1287  
      * Returns a {@link NaryExpression} {@value #SET_INTERSECTION} expression.
 1288  
      * 
 1289  
      * @param lhs
 1290  
      *            The expression that will be evaluated to create the first set.
 1291  
      * @param rhs
 1292  
      *            The expression that will be evaluated to create the second
 1293  
      *            set.
 1294  
      * @return The {@link NaryExpression} {@value #SET_INTERSECTION} expression.
 1295  
      */
 1296  
     public static NaryExpression setIntersection(final Expression lhs,
 1297  
             final Expression rhs) {
 1298  1
         return new NaryExpression(SET_INTERSECTION, lhs, rhs);
 1299  
     }
 1300  
 
 1301  
     /**
 1302  
      * Returns a {@link NaryExpression} {@value #SET_IS_SUBSET} expression.
 1303  
      * 
 1304  
      * @param subSet
 1305  
      *            The expression that will be tested to see if it is a subset of
 1306  
      *            the {@code completeSet}.
 1307  
      * @param completeSet
 1308  
      *            The expression that will be evaluated to construct the
 1309  
      *            complete set of values.
 1310  
      * @return The {@link NaryExpression} {@value #SET_IS_SUBSET} expression.
 1311  
      */
 1312  
     public static NaryExpression setIsSubset(final Expression subSet,
 1313  
             final Expression completeSet) {
 1314  1
         return new NaryExpression(SET_IS_SUBSET, subSet, completeSet);
 1315  
     }
 1316  
 
 1317  
     /**
 1318  
      * Returns a {@link NaryExpression} {@value #SET_UNION} expression.
 1319  
      * 
 1320  
      * @param lhs
 1321  
      *            The expression that will be evaluated to create the first set.
 1322  
      * @param rhs
 1323  
      *            The expression that will be evaluated to create the second
 1324  
      *            set.
 1325  
      * @return The {@link NaryExpression} {@value #SET_UNION} expression.
 1326  
      */
 1327  
     public static NaryExpression setUnion(final Expression lhs,
 1328  
             final Expression rhs) {
 1329  1
         return new NaryExpression(SET_UNION, lhs, rhs);
 1330  
     }
 1331  
 
 1332  
     /**
 1333  
      * Returns a {@link UnaryExpression} {@value #SIZE} expression.
 1334  
      * 
 1335  
      * @param expression
 1336  
      *            The expression that will be evaluated to create the set to
 1337  
      *            inspect for a true element.
 1338  
      * @return The {@link UnaryExpression} {@value #SIZE} expression.
 1339  
      */
 1340  
     public static UnaryExpression size(final Expression expression) {
 1341  1
         return new UnaryExpression(SIZE, expression);
 1342  
     }
 1343  
 
 1344  
     /**
 1345  
      * Returns a {@link NaryExpression}
 1346  
      * {@value #STRING_CASE_INSENSITIVE_COMPARE} expression.
 1347  
      * 
 1348  
      * @param lhs
 1349  
      *            The left hand side of the comparison.
 1350  
      * @param rhs
 1351  
      *            The right hand side of the comparison.
 1352  
      * @return The {@link NaryExpression}
 1353  
      *         {@value #STRING_CASE_INSENSITIVE_COMPARE} expression.
 1354  
      */
 1355  
     public static NaryExpression strcasecmp(final Expression lhs,
 1356  
             final Expression rhs) {
 1357  1
         return new NaryExpression(STRING_CASE_INSENSITIVE_COMPARE, lhs, rhs);
 1358  
     }
 1359  
 
 1360  
     /**
 1361  
      * Returns a {@link NaryExpression} {@value #SUB_STRING} expression.
 1362  
      * 
 1363  
      * @param string
 1364  
      *            The string to pull a sub-string from.
 1365  
      * @param skip
 1366  
      *            The number of characters to skip in the string.
 1367  
      * @param length
 1368  
      *            The length of the string to extract.
 1369  
      * @return The {@link NaryExpression} {@value #SUB_STRING} expression.
 1370  
      */
 1371  
     public static NaryExpression substr(final Expression string,
 1372  
             final Expression skip, final Expression length) {
 1373  1
         return new NaryExpression(SUB_STRING, string, skip, length);
 1374  
     }
 1375  
 
 1376  
     /**
 1377  
      * Returns a {@link NaryExpression} {@value #SUBTRACT} expression.
 1378  
      * 
 1379  
      * @param lhs
 1380  
      *            The left hand side of the operator.
 1381  
      * @param rhs
 1382  
      *            The right hand side of the operator.
 1383  
      * @return The {@link NaryExpression} {@value #SUBTRACT} expression.
 1384  
      */
 1385  
     public static NaryExpression subtract(final Expression lhs,
 1386  
             final Expression rhs) {
 1387  2
         return new NaryExpression(SUBTRACT, lhs, rhs);
 1388  
     }
 1389  
 
 1390  
     /**
 1391  
      * Returns a {@link UnaryExpression} {@value #TO_LOWER} expression.
 1392  
      * 
 1393  
      * @param string
 1394  
      *            The string to modify.
 1395  
      * @return The {@link UnaryExpression} {@value #TO_LOWER} expression.
 1396  
      */
 1397  
     public static UnaryExpression toLower(final Expression string) {
 1398  1
         return new UnaryExpression(TO_LOWER, string);
 1399  
     }
 1400  
 
 1401  
     /**
 1402  
      * Returns a {@link UnaryExpression} {@value #TO_UPPER} expression.
 1403  
      * 
 1404  
      * @param string
 1405  
      *            The string to modify.
 1406  
      * @return The {@link UnaryExpression} {@value #TO_UPPER} expression.
 1407  
      */
 1408  
     public static UnaryExpression toUpper(final Expression string) {
 1409  1
         return new UnaryExpression(TO_UPPER, string);
 1410  
     }
 1411  
 
 1412  
     /**
 1413  
      * Returns a {@link Constant} expression with the provided
 1414  
      * <tt>variableName</tt>. See the {@link #let $let} and {@link #map $map}
 1415  
      * expressions for example usage.
 1416  
      * <p>
 1417  
      * Prepends a {@code $$} to the variable name if not already present.
 1418  
      * </p>
 1419  
      * <blockquote>
 1420  
      * 
 1421  
      * <pre>
 1422  
      * <code>
 1423  
      * Constant variable = Expressions.var("variable");
 1424  
      * 
 1425  
      * // Produces output: 
 1426  
      * //      $$variable
 1427  
      * System.out.println(variable);
 1428  
      * </code>
 1429  
      * </pre>
 1430  
      * 
 1431  
      * </blockquote>
 1432  
      * 
 1433  
      * @param variableName
 1434  
      *            The name of the field.
 1435  
      * @return The {@link Constant} expression.
 1436  
      */
 1437  
     public static Constant var(final String variableName) {
 1438  
 
 1439  
         Constant result;
 1440  3
         if (variableName.startsWith("$$")) {
 1441  1
             result = new Constant(new StringElement("", variableName));
 1442  
         }
 1443  2
         else if (variableName.startsWith("$")) {
 1444  1
             result = new Constant(new StringElement("", "$" + variableName));
 1445  
         }
 1446  
         else {
 1447  1
             result = new Constant(new StringElement("", "$$" + variableName));
 1448  
         }
 1449  3
         return result;
 1450  
     }
 1451  
 
 1452  
     /**
 1453  
      * Returns a {@link UnaryExpression} {@value #WEEK} expression.
 1454  
      * 
 1455  
      * @param expression
 1456  
      *            The date for the operator.
 1457  
      * @return The {@link UnaryExpression} {@value #WEEK} expression.
 1458  
      */
 1459  
     public static UnaryExpression week(final Expression expression) {
 1460  1
         return new UnaryExpression(WEEK, expression);
 1461  
     }
 1462  
 
 1463  
     /**
 1464  
      * Returns a {@link UnaryExpression} {@value #YEAR} expression.
 1465  
      * 
 1466  
      * @param expression
 1467  
      *            The date for the operator.
 1468  
      * @return The {@link UnaryExpression} {@value #YEAR} expression.
 1469  
      */
 1470  
     public static UnaryExpression year(final Expression expression) {
 1471  1
         return new UnaryExpression(YEAR, expression);
 1472  
     }
 1473  
 
 1474  
     /**
 1475  
      * Creates a new Expressions.
 1476  
      */
 1477  0
     private Expressions() {
 1478  0
     }
 1479  
 }