com.amazon.carbonado.filter
Class Filter<S extends Storable>

java.lang.Object
  extended by com.amazon.carbonado.filter.Filter<S>
All Implemented Interfaces:
Appender, Serializable
Direct Known Subclasses:
BinaryOpFilter, ClosedFilter, ExistsFilter, OpenFilter, PropertyFilter

public abstract class Filter<S extends Storable>
extends Object
implements Serializable, Appender

An immutable tree structure representing a query result filter. Filters can be created using a builder pattern, by expression parsing, or by a combination of techniques. Filter instances are canonical, which means that equivalent instances can be compared for equality using the '==' operator.

Any method that accepts a filter expression parses against the following syntax:

 Filter          = OrFilter
 OrFilter        = AndFilter { "|" AndFilter }
 AndFilter       = NotFilter { "&" NotFilter }
 NotFilter       = [ "!" ] EntityFilter
 EntityFilter    = PropertyFilter
                 = ChainedFilter
                 | "(" Filter ")"
 PropertyFilter  = ChainedProperty RelOp "?"
 RelOp           = "=" | "!=" | "<" | ">=" | ">" | "<="
 ChainedFilter   = ChainedProperty "(" [ Filter ] ")"
 ChainedProperty = Identifier
                 | InnerJoin "." ChainedProperty
                 | OuterJoin "." ChainedProperty
 InnerJoin       = Identifier
 OuterJoin       = "(" Identifier ")"
 

Author:
Brian S O'Neill
See Also:
Serialized Form

Nested Class Summary
 class Filter.NotJoined
          Result from calling notJoinedFrom(java.lang.String).
 
Method Summary
abstract
<R,P> R
accept(Visitor<S,R,P> visitor, P param)
          Accept the given visitor subclass to traverse the filter tree.
 Filter<S> and(Filter<S> filter)
          Returns a combined filter instance that accepts records which are only accepted by this filter and the one given.
 Filter<S> and(String expression)
          Returns a combined filter instance that accepts records which are only accepted by this filter and the one given.
 Filter<S> and(String propertyName, RelOp operator)
          Returns a combined filter instance that accepts records which are only accepted by this filter and the one given.
 Filter<S> and(String propertyName, RelOp operator, Object constantValue)
          Returns a combined filter instance that accepts records which are only accepted by this filter and the one given.
 Filter<S> andExists(String propertyName, Filter<?> subFilter)
          Returns a combined filter instance that accepts records which are only accepted by this filter and the "exists" test applied to a join.
 Filter<S> andNotExists(String propertyName, Filter<?> subFilter)
          Returns a combined filter instance that accepts records which are only accepted by this filter and the "not exists" test applied to a join.
 void appendTo(Appendable app)
          Appends the string value of this filter into the given Appendable.
abstract  void appendTo(Appendable app, FilterValues<S> values)
          Appends the string value of this filter into the given Appendable.
<T extends Storable>
Filter<T>
asJoinedFrom(ChainedProperty<T> joinProperty)
          Prepends a join property to all properties of this filter.
<T extends Storable>
Filter<T>
asJoinedFrom(Class<T> type, String joinProperty)
          Prepends a join property to all properties of this filter.
abstract
<T extends Storable>
Filter<T>
asJoinedFromAny(ChainedProperty<T> joinProperty)
          Allows join from any property type, including one-to-many joins.
abstract  Filter<S> bind()
          Walks through each property filter, assigning a bind ID to it.
 Filter<S> conjunctiveNormalForm()
          Returns an equivalent filter that is in conjunctive normal form.
 List<Filter<S>> conjunctiveNormalFormSplit()
          Splits the filter from its conjunctive normal form.
 Filter<S> disjunctiveNormalForm()
          Returns an equivalent filter that is in disjunctive normal form.
 List<Filter<S>> disjunctiveNormalFormSplit()
          Splits the filter from its disjunctive normal form.
abstract  boolean equals(Object obj)
           
static
<S extends Storable>
Filter<S>
filterFor(Class<S> type, String expression)
          Returns a cached filter instance that operates on the given type and filter expression.
static
<S extends Storable>
ClosedFilter<S>
getClosedFilter(Class<S> type)
          Returns a cached filter instance that operates on the given type, which prevents any results from passing through.
static
<S extends Storable>
OpenFilter<S>
getOpenFilter(Class<S> type)
          Returns a cached filter instance that operates on the given type, which allows all results to pass through.
 Class<S> getStorableType()
          Returns the storable type that this filter operates on.
 int hashCode()
           
 FilterValues<S> initialFilterValues()
          Returns a FilterValues instance for assigning values to a Filter.
abstract  boolean isBound()
          Returns true if all property filters are known to be properly bound.
 boolean isClosed()
          Returns true if filter prevents any results from passing through.
 boolean isOpen()
          Returns true if filter allows all results to pass through.
abstract  Filter<S> not()
          Returns the logical negation of this filter.
 Filter.NotJoined notJoinedFrom(ChainedProperty<S> joinProperty)
          Removes a join property prefix from all applicable properties of this filter.
 Filter.NotJoined notJoinedFrom(String joinProperty)
          Removes a join property prefix from all applicable properties of this filter.
 Filter<S> or(Filter<S> filter)
          Returns a combined filter instance that accepts records which are accepted either by this filter or the one given.
 Filter<S> or(String expression)
          Returns a combined filter instance that accepts records which are accepted either by this filter or the one given.
 Filter<S> or(String propertyName, RelOp operator)
          Returns a combined filter instance that accepts records which are accepted either by this filter or the one given.
 Filter<S> or(String propertyName, RelOp operator, Object constantValue)
          Returns a combined filter instance that accepts records which are accepted either by this filter or the one given.
 Filter<S> orExists(String propertyName, Filter<?> subFilter)
          Returns a combined filter instance that accepts records which are accepted either by this filter or the "exists" test applied to a join.
 Filter<S> orNotExists(String propertyName, Filter<?> subFilter)
          Returns a combined filter instance that accepts records which are accepted either by this filter or the "not exists" test applied to a join.
 Filter<S> reduce()
          Returns an equivalent filter with redundant terms eliminated.
 String toString()
          Returns the string value of this filter, which is also parsable.
abstract  Filter<S> unbind()
          Undoes the effect of a bind operation.
 
Methods inherited from class java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait
 

Method Detail

filterFor

public static <S extends Storable> Filter<S> filterFor(Class<S> type,
                                                       String expression)
Returns a cached filter instance that operates on the given type and filter expression.

Parameters:
type - type of Storable that query is made against
expression - query filter expression to parse
Returns:
canonical Filter instance
Throws:
IllegalArgumentException - if type or filter expression is null
MalformedFilterException - if filter expression is malformed

getOpenFilter

public static <S extends Storable> OpenFilter<S> getOpenFilter(Class<S> type)
Returns a cached filter instance that operates on the given type, which allows all results to pass through.

Parameters:
type - type of Storable that query is made against
Returns:
canonical Filter instance
See Also:
OpenFilter

getClosedFilter

public static <S extends Storable> ClosedFilter<S> getClosedFilter(Class<S> type)
Returns a cached filter instance that operates on the given type, which prevents any results from passing through.

Parameters:
type - type of Storable that query is made against
Returns:
canonical Filter instance
See Also:
ClosedFilter

getStorableType

public Class<S> getStorableType()
Returns the storable type that this filter operates on.


initialFilterValues

public FilterValues<S> initialFilterValues()
Returns a FilterValues instance for assigning values to a Filter. Returns null if Filter has no parameters.

Note: The returned FilterValues instance may reference a different filter instance than this one. Call getFilter to retrieve it. The difference is caused by the filter property values being bound.


and

public final Filter<S> and(String expression)
Returns a combined filter instance that accepts records which are only accepted by this filter and the one given.

Parameters:
expression - query filter expression to parse
Returns:
canonical Filter instance
Throws:
IllegalArgumentException - if filter is null

and

public Filter<S> and(Filter<S> filter)
Returns a combined filter instance that accepts records which are only accepted by this filter and the one given.

Returns:
canonical Filter instance
Throws:
IllegalArgumentException - if filter is null

and

public final Filter<S> and(String propertyName,
                           RelOp operator)
Returns a combined filter instance that accepts records which are only accepted by this filter and the one given.

Parameters:
propertyName - property name to match on, which may be a chained property
operator - relational operator
Returns:
canonical Filter instance
Throws:
IllegalArgumentException - if property is not found

and

public final Filter<S> and(String propertyName,
                           RelOp operator,
                           Object constantValue)
Returns a combined filter instance that accepts records which are only accepted by this filter and the one given.

Parameters:
propertyName - property name to match on, which may be a chained property
operator - relational operator
constantValue - constant value to match
Returns:
canonical Filter instance
Throws:
IllegalArgumentException - if property is not found

andExists

public final Filter<S> andExists(String propertyName,
                                 Filter<?> subFilter)
Returns a combined filter instance that accepts records which are only accepted by this filter and the "exists" test applied to a join.

Parameters:
propertyName - join property name, which may be a chained property
subFilter - sub-filter to apply to join, which may be null to test for any existing
Returns:
canonical Filter instance
Throws:
IllegalArgumentException - if property is not found
Since:
1.2

andNotExists

public final Filter<S> andNotExists(String propertyName,
                                    Filter<?> subFilter)
Returns a combined filter instance that accepts records which are only accepted by this filter and the "not exists" test applied to a join.

Parameters:
propertyName - join property name, which may be a chained property
subFilter - sub-filter to apply to join, which may be null to test for any not existing
Returns:
canonical Filter instance
Throws:
IllegalArgumentException - if property is not found
Since:
1.2

or

public final Filter<S> or(String expression)
Returns a combined filter instance that accepts records which are accepted either by this filter or the one given.

Parameters:
expression - query filter expression to parse
Returns:
canonical Filter instance
Throws:
IllegalArgumentException - if filter is null

or

public Filter<S> or(Filter<S> filter)
Returns a combined filter instance that accepts records which are accepted either by this filter or the one given.

Returns:
canonical Filter instance
Throws:
IllegalArgumentException - if filter is null

or

public final Filter<S> or(String propertyName,
                          RelOp operator)
Returns a combined filter instance that accepts records which are accepted either by this filter or the one given.

Parameters:
propertyName - property name to match on, which may be a chained property
operator - relational operator
Returns:
canonical Filter instance
Throws:
IllegalArgumentException - if property is not found

or

public final Filter<S> or(String propertyName,
                          RelOp operator,
                          Object constantValue)
Returns a combined filter instance that accepts records which are accepted either by this filter or the one given.

Parameters:
propertyName - property name to match on, which may be a chained property
operator - relational operator
constantValue - constant value to match
Returns:
canonical Filter instance
Throws:
IllegalArgumentException - if property is not found

orExists

public final Filter<S> orExists(String propertyName,
                                Filter<?> subFilter)
Returns a combined filter instance that accepts records which are accepted either by this filter or the "exists" test applied to a join.

Parameters:
propertyName - one-to-many join property name, which may be a chained property
subFilter - sub-filter to apply to join, which may be null to test for any existing
Returns:
canonical Filter instance
Throws:
IllegalArgumentException - if property is not found
Since:
1.2

orNotExists

public final Filter<S> orNotExists(String propertyName,
                                   Filter<?> subFilter)
Returns a combined filter instance that accepts records which are accepted either by this filter or the "not exists" test applied to a join.

Parameters:
propertyName - one-to-many join property name, which may be a chained property
subFilter - sub-filter to apply to join, which may be null to test for any not existing
Returns:
canonical Filter instance
Throws:
IllegalArgumentException - if property is not found
Since:
1.2

not

public abstract Filter<S> not()
Returns the logical negation of this filter.

Returns:
canonical Filter instance

disjunctiveNormalForm

public final Filter<S> disjunctiveNormalForm()
Returns an equivalent filter that is in disjunctive normal form. In this form, all logical 'and' operations are performed before all logical 'or' operations. This method often returns a filter with more terms than before.

The tree is also normalized such that all terms in a common logical operation are ordered left to right. For example, expressions of the form "(a = ? & b = ?) & (c = ? & d = ?)" are converted to "(((a = ?) & (b = ?)) & c = ?) & d = ?".

Although the disjunctive normal filter may have more terms, it can be used to extract values from a FilterValues instance created from this filter. This works because the disjunctive normal filter is composed of the same set of PropertyFilter instances.

Returns:
canonical Filter instance

disjunctiveNormalFormSplit

public List<Filter<S>> disjunctiveNormalFormSplit()
Splits the filter from its disjunctive normal form. Or'ng the filters together produces the full disjunctive normal form.

Returns:
unmodifiable list of sub filters which don't perform any 'or' operations
Since:
1.1.1

conjunctiveNormalForm

public final Filter<S> conjunctiveNormalForm()
Returns an equivalent filter that is in conjunctive normal form. In this form, all logical 'or' operations are performed before all logical 'and' operations. This method often returns a filter with more terms than before.

The tree is also normalized such that all terms in a common logical operation are ordered left to right. For example, expressions of the form "(a = ? | b = ?) | (c = ? | d = ?)" are converted to "(((a = ?) | (b = ?)) | c = ?) | d = ?".

Although the conjunctive normal filter may have more terms, it can be used to extract values from a FilterValues instance created from this filter. This works because the conjunctive normal filter is composed of the same set of PropertyFilter instances.

Returns:
canonical Filter instance

conjunctiveNormalFormSplit

public List<Filter<S>> conjunctiveNormalFormSplit()
Splits the filter from its conjunctive normal form. And'ng the filters together produces the full conjunctive normal form.

Returns:
unmodifiable list of sub filters which don't perform any 'and' operations
Since:
1.1.1

accept

public abstract <R,P> R accept(Visitor<S,R,P> visitor,
                               P param)
Accept the given visitor subclass to traverse the filter tree.

Parameters:
visitor - visitor to traverse through the tree
param - generic input parameter passed to visit methods
Returns:
generic return value passed from visit methods

bind

public abstract Filter<S> bind()
Walks through each property filter, assigning a bind ID to it. This step is automatically performed for proper dnf/cnf conversion, and for building FilterValues.

Returns:
canonical Filter instance with bound property filters

unbind

public abstract Filter<S> unbind()
Undoes the effect of a bind operation. The returned filter might still report itself as bound if it doesn't make a distinction between these states.

Returns:
canonical Filter instance with unbound property filters

isBound

public abstract boolean isBound()
Returns true if all property filters are known to be properly bound. This is a side effect of calling bind(), initialFilterValues(), disjunctiveNormalForm() or conjunctiveNormalForm().


reduce

public final Filter<S> reduce()
Returns an equivalent filter with redundant terms eliminated. The tree is also normalized such that all terms in a common logical operation are ordered left to right. For example, expressions of the form "(a = ? & b = ?) & (c = ? & d = ?)" are converted to "(((a = ?) & (b = ?)) & c = ?) & d = ?".

Returns:
canonical Filter instance

asJoinedFrom

public final <T extends Storable> Filter<T> asJoinedFrom(Class<T> type,
                                                         String joinProperty)
Prepends a join property to all properties of this filter. For example, consider two Storable types, Person and Address. Person has a property "homeAddress" which joins to Address. An Address filter, "city = ?", as joined from Person's "homeAddress", becomes "homeAddress.city = ?".
 Filter<Address> addressFilter = Filter.filterFor(Address.class, "city = ?");
 Filter<Person> personFilter = addressFilter.asJoinedFrom(Person.class, "homeAddress");

 // Equivalent filter:
 Filter<Person> personFilter2 = Filter.filterFor(Person.class, "homeAddress.city = ?");
 

Parameters:
type - type of T which contains join property
joinProperty - property of T which joins to this Filter's Storable type
Returns:
filter for type T
Throws:
IllegalArgumentException - if property does not exist or is not a join to type S

asJoinedFrom

public final <T extends Storable> Filter<T> asJoinedFrom(ChainedProperty<T> joinProperty)
Prepends a join property to all properties of this filter. For example, consider two Storable types, Person and Address. Person has a property "homeAddress" which joins to Address. An Address filter, "city = ?", as joined from Person's "homeAddress", becomes "homeAddress.city = ?".

Parameters:
joinProperty - property of T which joins to this Filter's Storable type
Returns:
filter for type T
Throws:
IllegalArgumentException - if property is not a join to type S

asJoinedFromAny

public abstract <T extends Storable> Filter<T> asJoinedFromAny(ChainedProperty<T> joinProperty)
Allows join from any property type, including one-to-many joins.


notJoinedFrom

public final Filter.NotJoined notJoinedFrom(String joinProperty)
Removes a join property prefix from all applicable properties of this filter. For example, consider two Storable types, Person and Address. Person has a property "homeAddress" which joins to Address. A Person filter might be "homeAddress.city = ? & lastName = ?". When not joined from "homeAddress", it becomes "city = ?" on Address with a remainder of "lastName = ?" on Person.

The resulting remainder filter (if any) is always logically and'd to the not joined filter. In order to achieve this, the original filter is first converted to conjunctive normal form. And as a side affect, both the remainder and not joined filters are bound.

Parameters:
joinProperty - property to not join from
Returns:
not join result
Throws:
IllegalArgumentException - if property does not exist or if property does not refer to a Storable

notJoinedFrom

public final Filter.NotJoined notJoinedFrom(ChainedProperty<S> joinProperty)
Removes a join property prefix from all applicable properties of this filter. For example, consider two Storable types, Person and Address. Person has a property "homeAddress" which joins to Address. A Person filter might be "homeAddress.city = ? & lastName = ?". When not joined from "homeAddress", it becomes "city = ?" on Address with a remainder of "lastName = ?" on Person.

The resulting remainder filter (if any) is always logically and'd to the not joined filter. In order to achieve this, the original filter is first converted to conjunctive normal form. And as a side affect, both the remainder and not joined filters are bound.

Parameters:
joinProperty - property to not join from
Returns:
not join result
Throws:
IllegalArgumentException - if property does not refer to a Storable

isOpen

public boolean isOpen()
Returns true if filter allows all results to pass through.

Since:
1.2

isClosed

public boolean isClosed()
Returns true if filter prevents any results from passing through.

Since:
1.2

hashCode

public final int hashCode()
Overrides:
hashCode in class Object

equals

public abstract boolean equals(Object obj)
Overrides:
equals in class Object

toString

public String toString()
Returns the string value of this filter, which is also parsable.

Overrides:
toString in class Object

appendTo

public void appendTo(Appendable app)
              throws IOException
Appends the string value of this filter into the given Appendable.

Specified by:
appendTo in interface Appender
Parameters:
app - Appendable object to receive string representation
Throws:
IOException - if thrown from given Appendable

appendTo

public abstract void appendTo(Appendable app,
                              FilterValues<S> values)
                       throws IOException
Appends the string value of this filter into the given Appendable.

Parameters:
values - optionally supply filter values
Throws:
IOException


Copyright © 2006-2009 Amazon Technologies, Inc.. All Rights Reserved.