# com.bea.content.expression
ExpressionHelper Class

public class ExpressionHelper
extends `Object`

Helper class to handle dealing with content Expressions.

For details on what content expressions should look like, see `parse()```.

Hierarchy
  `Object`
  `ExpressionHelper`

## Nested Class Summary

`public static class` | `ExpressionHelper.ParseException` Exception to report an error while parsing a query expression.

## Field Summary

`public static final `String`` | `AND` Syntax textual and logical operator.
`public static final `String`` | `CONTAINS` Syntax textual contains operator.
`public static final `String`` | `CONTAINS_ALL` Syntax textual contains all operator.
`public static final `String`` | `CONTAINS_ANY` Syntax textual contains any operator.
`public static final `DateFormat`` | `defDateFormat` The default date formatter.
`public static final `String`` | `defDateFormatStr` The default datetime format string in the content expression syntax ("MM/dd/yyyy HH:mm:ss z").
`public static final `String`` | `EQUALS` Syntax textual equals operator.
`public static final `String`` | `GREATER_THAN` Syntax textual greater than operator.
`public static final `String`` | `GREATER_THAN_EQUALS` Syntax textual greater than or equals operator.
`public static final `String`` | `IN` Syntax textual in operator.
`public static final `String`` | `LESS_THAN` Syntax textual less than operator.
`public static final `String`` | `LESS_THAN_EQUALS` Syntax textual less than or equals operator.
`public static final `String`` | `LIKE` Syntax textual like operator.
`public static final `String`` | `LIKE_IGNORE_CASE` Syntax textual like (case insensitive) operator.
`public static final `String`` | `NOT_EQUALS` Syntax textual not equals operator.
`public static final `String`` | `OR` Syntax textual or logical operator.

## Constructor Summary

ExpressionHelper()

## Method Summary

`public static `Expression`` | `convertContainsAnyOperators`(`Expression` expr) Convert an expression tree to not contain any 'containsany' comparison operators.
`public static `Expression`` | `convertInOperators`(`Expression` expr) Convert an expression tree to not contain any 'in' comparison operators.
`public static `String`` | `fromStringLiteral`(`String` in) Convert a String literal (which may contain quoted characters) into a corresponding String value.
`public static `String`` | `getComparator`(`Expression` expr) Get the syntax comparator textual operator for the given leaf node.
`public static `String`` | `getContentId`(`Expression` expr) Return the content id from the expression, if it's an expression for a single content object based upon identifier.
`public static `Search`` | `getContentIdSearch`(`String` contentId) Get a search object for a single content based upon the supplied id.
`public static `Search`` | `getContentPathSearch`(`String` contentPath) Get a search object for a single content based upon the supplied path.
`public static `PropertyRef`` | `getLeftHandSide`(`Expression` expr) Get the left-hand-side of a valid leaf node, which should be a PropertyRef.
`public static `String`` | `getLogicalComparator`(`Expression` expr) Get the syntax logical comparator textual operator for the given branch node.
`public static int` | `getOrdinalValue`(char ch) Get the ordinal (Unicode) value of a character.
`public static `Object`` | `getRightHandSide`(`Expression` expr) Get the right-hand-side of a valid leaf node.
`public static `Expression`` | `getSubExpression`(`Expression` expr, int count) Get a child expression of the specified expression at the count index.
`public static boolean` | `isHexString`(`String` str) Determine if a string contains only ASCII hexidecimal characters ([0-9a-fA-F]).
`public static `Expression`` | `isLogicalNot`(`Expression` expr) Tell if an expression is really a logical not and, if so, returns the contained expression.
`public static boolean` | `isValidBranchNode`(`Expression` expr) Tell if an expression is a valid content branch node type.
`public static boolean` | `isValidLeafNode`(`Expression` expr) Tell if an expression is a valid content leaf node type.
`public static `LogicalAnd`` | `join`(`Expression` expr1, `Expression` expr2) Join together two expression via an AND expression.
`public static `Expression`` | `normalize`(`Expression` expr) Normalize an Expression.
`public static `Expression`` | `parse`(`String` queryStr) Convert a query expression string into an Expression object.
`public static void` | `print`(`PrintWriter` out, `Expression` expr) Print a string representation of the given expression.
`public static void` | `printBranchNode`(`PrintWriter` out, `Expression` expr) Return a string representation of the given expression branch.
`public static void` | `printLeafNode`(`PrintWriter` out, `Expression` expr) Return a string representation of the given leaf expression node.
`public static `Expression`` | `realize`(`Expression` expr, `PropertyProvider` props) Realize an expression, which can contain property references, into an an expression which contains only literal values and can be sent to a `SearchOps```.
`public static `String`` | `toString`(`Expression` expr) Get a string representation of the given expression.
`public static `String`` | `toStringLiteral`(`String` in) Get an ASCII String literal from a Java string.

Methods from class `java.lang.`Object``
`clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

## Field Detail

### AND

    public static final String AND

  Syntax textual and logical operator.

### CONTAINS

    public static final String CONTAINS

  Syntax textual contains operator.

### CONTAINS_ALL

    public static final String CONTAINS_ALL

  Syntax textual contains all operator.

### CONTAINS_ANY

    public static final String CONTAINS_ANY

  Syntax textual contains any operator.

### defDateFormat

    public static final DateFormat defDateFormat

  The default date formatter.

### defDateFormatStr

    public static final String defDateFormatStr

  The default datetime format string in the content expression syntax ("MM/dd/yyyy HH:mm:ss z").

### EQUALS

    public static final String EQUALS

  Syntax textual equals operator.

### GREATER_THAN

    public static final String GREATER_THAN

  Syntax textual greater than operator.

### GREATER_THAN_EQUALS

    public static final String GREATER_THAN_EQUALS

  Syntax textual greater than or equals operator.

### IN

    public static final String IN

  Syntax textual in operator.

### LESS_THAN

    public static final String LESS_THAN

  Syntax textual less than operator.

### LESS_THAN_EQUALS

    public static final String LESS_THAN_EQUALS

  Syntax textual less than or equals operator.

### LIKE

    public static final String LIKE

  Syntax textual like operator.

### LIKE_IGNORE_CASE

    public static final String LIKE_IGNORE_CASE

  Syntax textual like (case insensitive) operator.

### NOT_EQUALS

    public static final String NOT_EQUALS

  Syntax textual not equals operator.

### OR

    public static final String OR

  Syntax textual or logical operator.

## Constructor Detail

### ExpressionHelper

    public ExpressionHelper()

## Method Detail

### convertContainsAnyOperators(Expression) Method

    public static Expression convertContainsAnyOperators(Expression expr)
         throws IllegalArgumentException

Convert an expression tree to not contain any 'containsany' comparison operators.

This will change all CollectionContainsAny leafs into a MultiOr branch of CollectionContains leafs for each element of the CollectionContainsAny right-hand-side list. Or, in syntax terms, "`prop containsany (1, 2, 3)`" will become "`(prop contains 1 || prop contains== 2 || prop contains 3)`".

#### Parameters

expr
  the incoming expression.

#### Returns

the updated expression, which might not be the same as what's passed in depending upon the structure (can be null if it normalizes down to "`prop containsany null`" or "`prop containsany ()`").

#### Exceptions

``IllegalArgumentException``
  if the expression structure isn't valid.

### convertInOperators(Expression) Method

    public static Expression convertInOperators(Expression expr)
         throws IllegalArgumentException

Convert an expression tree to not contain any 'in' comparison operators.

This will change all ContainedIn leafs into a MultiOr branch of Equals leafs for each element of the ContainedIn right-hand-side list. Or, in syntax terms, "`prop in (1, 2, 3)`" will become "`(prop == 1 || prop == 2 || prop == 3)`".

#### Parameters

expr
  the incoming expression.

#### Returns

the updated expression, which might not be the same as what's passed in depending upon the structure (can be null if it normalizes down to "`prop in null`" or "`prop in ()`").

#### Exceptions

``IllegalArgumentException``
  if the expression structure isn't valid.

### fromStringLiteral(String) Method

    public static String fromStringLiteral(String in)

Convert a String literal (which may contain quoted characters) into a corresponding String value.

This supports the standard Java Language Specification escape sequences.

#### Parameters

in
  the input string literal.

#### Returns

the string value.

### getComparator(Expression) Method

    public static String getComparator(Expression expr)
         throws IllegalArgumentException

Get the syntax comparator textual operator for the given leaf node.

#### Parameters

expr
  the leaf node expression.

#### Returns

the syntax operator constant, one of `ExpressionHelper.EQUALS```, `ExpressionHelper.NOT_EQUALS```, `ExpressionHelper.GREATER_THAN```, `ExpressionHelper.GREATER_THAN_EQUALS```, `ExpressionHelper.LESS_THAN```, `ExpressionHelper.LESS_THAN_EQUALS```, `ExpressionHelper.LIKE```, `ExpressionHelper.LIKE_IGNORE_CASE```, `ExpressionHelper.IN```, `ExpressionHelper.CONTAINS```, `ExpressionHelper.CONTAINS_ALL```, or `ExpressionHelper.CONTAINS_ANY``` or null if the expression is null.

#### Exceptions

``IllegalArgumentException``
  if the expression is not a valid leaf node.

### getContentId(Expression) Method

    public static String getContentId(Expression expr)

Return the content id from the expression, if it's an expression for a single content object based upon identifier.

#### Returns

the content id, or null if it's not a identifier equality expression.

### getContentIdSearch(String) Method

    public static Search getContentIdSearch(String contentId)

Get a search object for a single content based upon the supplied id.

### getContentPathSearch(String) Method

    public static Search getContentPathSearch(String contentPath)

Get a search object for a single content based upon the supplied path.

### getLeftHandSide(Expression) Method

    public static PropertyRef getLeftHandSide(Expression expr)
         throws IllegalArgumentException

Get the left-hand-side of a valid leaf node, which should be a PropertyRef.

#### Parameters

expr
  the leaf node expression.

#### Returns

the left-hand-side content property ref

#### Exceptions

``IllegalArgumentException``
  if the the left-hand-side is null or not a PropertyRef.

### getLogicalComparator(Expression) Method

    public static String getLogicalComparator(Expression expr)
         throws IllegalArgumentException

Get the syntax logical comparator textual operator for the given branch node.

#### Parameters

expr
  the expression.

#### Returns

the boolean logic syntax operator constant, either `ExpressionHelper.AND``` or `ExpressionHelper.OR```, or null if the expression is null.

#### Exceptions

``IllegalArgumentException``
  thrown if the given expression is not a valid branch node expression.

### getOrdinalValue(char) Method

    public static int getOrdinalValue(char ch)

Get the ordinal (Unicode) value of a character.

### getRightHandSide(Expression) Method

    public static Object getRightHandSide(Expression expr)
         throws IllegalArgumentException

Get the right-hand-side of a valid leaf node.

#### Parameters

expr
  the leaf node expression.

#### Returns

the right-hand-side value, which should be an Object value, null, a `RequestPropertyRef```, a `SessionPropertyRef```, or a `UserPropertyRef```.

#### Exceptions

``IllegalArgumentException``
  if the expression is not a valid leaf node.

### getSubExpression(Expression, int) Method

    public static Expression getSubExpression(Expression expr,
                                              int count)
         throws IllegalArgumentException

Get a child expression of the specified expression at the count index.

#### Parameters

expr
  the parent expression.

count
  the index.

#### Returns

the child expression or null if no such child.

#### Exceptions

``IllegalArgumentException``
  if the child is not an Expression.

### isHexString(String) Method

    public static boolean isHexString(String str)

Determine if a string contains only ASCII hexidecimal characters ([0-9a-fA-F]).

#### Parameters

str
  the input string.

#### Returns

true if the string contains only ASCII hex characters.

### isLogicalNot(Expression) Method

    public static Expression isLogicalNot(Expression expr)

Tell if an expression is really a logical not and, if so, returns the contained expression.

#### Parameters

expr
  the expression.

#### Returns

the contained expressions if expr is a logical not, null otherwise.

### isValidBranchNode(Expression) Method

    public static boolean isValidBranchNode(Expression expr)

Tell if an expression is a valid content branch node type.

### isValidLeafNode(Expression) Method

    public static boolean isValidLeafNode(Expression expr)

Tell if an expression is a valid content leaf node type.

### join(Expression, Expression) Method

    public static LogicalAnd join(Expression expr1,
                                  Expression expr2)

Join together two expression via an AND expression.

#### Parameters

expr1
  the first expression.

expr2
  the second expression.

#### Returns

a LogicalAnd of the two expressions.

### normalize(Expression) Method

    public static Expression normalize(Expression expr)
         throws IllegalArgumentException

Normalize an Expression.

This will recursively remove branches that contain only one Expression (which are boolean equivelant to the one child expression) or that contain no children (which are considered empty).

#### Parameters

expr
  the incoming expression.

#### Returns

the normalized expression, null if normalized to nothing.

#### Exceptions

``IllegalArgumentException``
  thrown if the expression is not a valid content expression.

### parse(String) Method

    public static Expression parse(String queryStr)
         throws ExpressionHelper.ParseException, IllegalArgumentException

Convert a query expression string into an Expression object.

The string should follow the query syntax specified in the Personalization Server documentation. The expression syntax is tree-based, with each leaf in the tree beinging of the form "property comparator value" (e.g. "`cm_BinarySize <= 1234`").

Property (LHS)

  This specifies the object property to match against. To specify a property name which contains non-identifier characters (e.g. whitespace, double quotes, dashes), you can use the "`toProperty('property name')`" form in the left-hand-side. To specify property set names as part of the property name, either use the "`properyset.name`" form or the "`toProperty('propertyset', 'property')`" form in the left-hand-side.

Comparators

  The valid comparision operators are `=` (or `==`), `!=`, `<`, `>`, `<=`, `>=`, "`like`", "`likeignorecase`", "`contains`", "`containsall`" "`containsany`", and "`in`".
  The "`like`" and "`likeignorecase`" operators expect the pattern (which is the value of the leaf) to use `*` (match all) and `?` (match any); "`like`" and "`likeignorecase`" also are only expected to work against String values, although they might work with other datatypes depending upon the search implementation. "`like`" does case sensitive matching; "`likeignorecase`" does case insensitive matching.
  The "`in`" operator expects the value to be a list. Otherwise, it's equivalent to `=`. The "`contains`" operator is only expected to work against multi-valued properties, although it might work with other datatypes depending upon the search implementation.
  The "`containsall`" and "`containsany`" operators are only expected to work against multi-valued properties, although they might work with other datatypes depending upon the search implementation. They expect the value to be a list. Otherwise, they're equivalent to "`contains`".

Value (RHS)
  - String literal values are enclosed in single quotes (back-slash is the quoting character, unicode characters not supported). Additionally, unicode (e.g. "`\u6565`"), octal (e.g. "`\7`", "`\65`", "`\377`"), and standard Java escape sequences (e.g. "`\n`", "`\r`", "`\b`") are allowed in the string literals.
  - Boolean literals are either the "`true`" or "`false`" keyword (without quotes).
  - Number literals are Java form (scientific notation is supported).
  - Time literals are presented in "`toDate(['formatStr'], 'dateStr')`" format. `formatStr` must be a valid `SimpleDateFormat``` format string; if omitted, '`MM/dd/yyyy HH:mm:ss z`' is used. Also, the "`now`" keyword specifies the time at which the expression was created.
  - Lists are a comma-separated list of the other value types inside parenthesis. Lists are 1-dimensional; they cannot contain other lists. Lists are only valid values with:
    - `=`, `!=`, "`containsany`" or "`containsall`" against multi-valued property
    - "`in`" against single-valued property
  - References to user, request, or session properties are represented as such:

         <type>Property(<propertyset>, <propertyname>)

         where <type> is one of 'user', 'request',
         or 'session', <propertyset> is the property set name
         and follows the rules for string literals.
         <propertyname> is the property name and follows the
         rules for string literals.

         References to properties should not be passed into the
         SearchOps class. Expression which
         contain references to properties should be realized into a
         searchable expression via the realize() method.

Each branch in the tree is comprised of 1 or more leafs or branches separated by either "`&&`" (boolean AND) or "`||`" (boolean OR). They can be enclosed in parenthesis for clearity and ordering (AND has precendance over OR). Additionally, "`!`" marks a branch as using negative logic (boolean NOT). The "`!`" operator can only be used preceding an open parenthesis.

Examples of valid expression strings: ``

- identifier == '00099abv48932ds'
- keys == ('00099abv48932ds', -1, 2.0, true, now, null)
- language == userProperty('MyProperties', 'userPreferredLang')
- ((UserAge <= 35 && colors contains 'red') || (UserAge > 35 && !(colors contains 'black')) && mimeType == 'text/html'
- toProperty('MyApp', 'Launch Date') < now && !(MyApp.expireDate > toDate('HH:mm:ss MM-dd-yyyy', '12:12:12 12/12/2002'))

In the resulting expression tree, the following caveats apply for it to be valid for the `SearchOps```:

- Each branch node can only be a LogicalAnd, LogicalOr, LogicalMulitAnd, or LogicalMultiOr. Any other branch node type is invalid.
- Each leaf node can only be an Equals, GreaterOrEquals, GreaterThan, LessOrEquals, LessThan, NotEquals, StringLike, ContainedIn, CollectionContains, CollectionContainsAll, or CollectionContainsAny. Any other branch node type is invalid.
- Any valid branch or leaf node may be contained in a LogicalNot node.
- In each leaf node, the left-hand-side will always be a PropertyRef node, which must contain Strings for getPropertySet() and getPropertyName(). In non-realized expression, a leaf node can be a UserPropertyRef, RequestPropertyRef, or SessionPropertyRef to represent a reference to an external property. Repositories should not receive non-realized expression, and, therefore, should not handle these objects; they are free to raise an exception if one is found.
- The right-hand-side of Equals, NotEquals, GreaterOrEquals, GreaterThan, LessOrEquals, LessThan, or CollectionContains leaf nodes can be a Collection, Long, Double, String, or Timestamp.
- The right-hand-side of StringLike leaf nodes can be a String. Anything else is invalid (i.e. should not match). The isCaseInsensitiveMatch() flag of the StringLike will be set depending upon whether it should do case sensitive (false, i.e. like) or case insensitive (true, i.e. likeignorecase) matching.
- The right-hand-side of CollectionContainsAll, CollectionContainsAny, or ContainedIn leaf nodes can be a Collection. Anything else is invalid (i.e. should not match).

#### Parameters

queryStr
  the query expression string

#### Returns

an Expression object representing (null if queryStr is a null expression).

#### Exceptions

``ExpressionHelper.ParseException``
``IllegalArgumentException``
  thrown on a general error.

Related Topics

``ExpressionHelper.normalize(Expression)``

### print(PrintWriter, Expression) Method

    public static void print(PrintWriter out,
                             Expression expr)
         throws IllegalArgumentException

Print a string representation of the given expression.

Pretty much, a string generated from this method can be parse()'ed into the semantically equivalent (not neccessarily identical) expression tree.

#### Parameters

out
  the output writer.

expr
  the expression.

#### Exceptions

``IllegalArgumentException``
  thrown if the given expression is not a valid content expression.

### printBranchNode(PrintWriter, Expression) Method

    public static void printBranchNode(PrintWriter out,
                                       Expression expr)

Return a string representation of the given expression branch.

#### Parameters

out
  the output writer.

expr
  the expression.

### printLeafNode(PrintWriter, Expression) Method

    public static void printLeafNode(PrintWriter out,
                                     Expression expr)
         throws IllegalArgumentException

Return a string representation of the given leaf expression node.

#### Parameters

out
  the output writer.

expr
  the expression.

#### Exceptions

``IllegalArgumentException``
  thrown if the given expression is not a valid leaf expression.

### realize(Expression, PropertyProvider) Method

    public static Expression realize(Expression expr,
                                     PropertyProvider props)
         throws IllegalArgumentException

Realize an expression, which can contain property references, into an an expression which contains only literal values and can be sent to a `SearchOps```. Or, in syntax terms, if the user's "prop" property in the 'propset' Property Set is 'red', "`prop == userProperty('propset', 'prop')`" will become "`prop == 'red'`".

This will modify the passed in expression.

#### Parameters

expr
  the expression to realize.

props
  the object which provides values for property references.

#### Returns

the modified expression

#### Exceptions

``IllegalArgumentException``
  thrown if the expr is not a valid content expression or contain a reference to an unknown property type.

### toString(Expression) Method

    public static String toString(Expression expr)
         throws IllegalArgumentException

Get a string representation of the given expression.

Pretty much, a string generated from this method can be parse()'ed into the semantically equivalent (not neccessarily identical) expression tree.

#### Parameters

expr
  the expression.

#### Returns

the query syntax representation of the expression.

#### Exceptions

``IllegalArgumentException``
  thrown if the given expression is not a valid content expression.

### toStringLiteral(String) Method

    public static String toStringLiteral(String in)

Get an ASCII String literal from a Java string.

This will quote some special characters with back-slashes.

The output of this can be sent through `ExpressionHelper.fromStringLiteral(String)``` to result in the original String.