ca.odell.glazedlists.matchers.Matchers Maven / Gradle / Ivy
Show all versions of glazedlists_java15 Show documentation
/* Glazed Lists (c) 2003-2006 */
/* http://publicobject.com/glazedlists/ publicobject.com,*/
/* O'Dell Engineering Ltd.*/
package ca.odell.glazedlists.matchers;
import ca.odell.glazedlists.Filterator;
import ca.odell.glazedlists.GlazedLists;
import ca.odell.glazedlists.impl.matchers.*;
import java.beans.PropertyChangeEvent;
import java.lang.reflect.Array;
import java.util.*;
/**
* A factory for creating Matchers.
*
* @author Jesse Wilson
*/
public final class Matchers {
/**
* A dummy constructor to prevent instantiation of this class
*/
private Matchers() {
throw new UnsupportedOperationException();
}
// Matcher Editors // // // // // // // // // // // // // // // // // // //
/**
* Provides a proxy to another MatcherEditor that may go out of scope
* without explicitly removing itself from the source MatcherEditor's set
* of listeners.
*
* This exists to solve a garbage collection problem. Suppose I have a
* {@link MatcherEditor} M which is long lived and many
* {@link MatcherEditor.Listener}s, t which must listen to M
* while they exist. Instead of adding each of the t directly as
* listeners of M, add a proxy instead. The proxy will retain a
* WeakReference
to the t, and will remove itself from
* the list of listeners for M.
*
* The {@link MatcherEditor} returned by this method makes implementing the
* above scheme trivial. It does two things for you automatically:
*
*
* - It wraps each {@link MatcherEditor.Listener} passed to
* {@link MatcherEditor#addMatcherEditorListener} in a
* {@link java.lang.ref.WeakReference} so that the listeners are
* garbage collected when they become unreachable.
*
*
- It registers itself as a weak listener of the
* given
matcherEditor
so the MatcherEditor returned by
* this method will be garbage collected when it becomes unreachable.
*
*
* @see java.lang.ref.WeakReference
*/
public static MatcherEditor weakReferenceProxy(MatcherEditor matcherEditor) {
return new WeakReferenceMatcherEditor(matcherEditor);
}
// Matchers // // // // // // // // // // // // // // // // // // // // //
/**
* Get a {@link Matcher} that always returns true, therefore matching everything.
*/
public static Matcher trueMatcher() {
return TrueMatcher.getInstance();
}
/**
* Get a {@link Matcher} that always returns false, therefore matching nothing..
*/
public static Matcher falseMatcher() {
return FalseMatcher.getInstance();
}
/**
* Get a {@link Matcher} that returns the opposite of the specified {@link Matcher}.
*/
public static Matcher invert(Matcher original) {
return new NotMatcher(original);
}
/**
* Get a {@link Matcher} that returns returns true iff it is
* given a non-null
object.
*/
public static Matcher isNull() {
return NullMatcher.getInstance();
}
/**
* Get a {@link Matcher} that returns returns true iff it is
* given a null
object.
*/
public static Matcher isNotNull() {
return NotNullMatcher.getInstance();
}
/**
* Get a {@link Matcher} that returns true iff it is given a
* non-null
and non-empty
String.
*/
public static Matcher nonNullAndNonEmptyString() {
return NonNullAndNonEmptyStringMatcher.getInstance();
}
/**
* Creates a {@link Matcher} that uses Reflection to compare the expectedValue
* of the specified property of an object to the expectedValue
.
*/
public static Matcher beanPropertyMatcher(Class beanClass, String propertyName, Object expectedValue) {
return new BeanPropertyMatcher(beanClass, propertyName, expectedValue);
}
/**
* Creates a {@link Matcher} that matches {@link Comparable} objects for
* containment within the range between the given start
* and end
.
*/
public static Matcher rangeMatcher(D start, D end) {
return new RangeMatcher(start, end);
}
/**
* Creates a {@link Matcher} that uses the given filterator
* to extract {@link Comparable} objects from filtered objects and compares
* those Comparables against the range between the given start
* and end
. If at least one Comparable returned by the
* filterator
is within the range, the object is considered
* a match.
*
* null
start
or end
values are
* allowed and are interpreted as "no start"
or
* "no end"
to the range respectively.
*
* @param start the {@link Comparable} which starts the range
* @param end the {@link Comparable} which ends the range
* @param filterator the logic for extracting filter {@link Comparable}s
* from filtered objects
*/
public static Matcher rangeMatcher(D start, D end, Filterator filterator) {
return new RangeMatcher(start, end, filterator);
}
/**
* Create a {@link Matcher} that uses the given propertyNames
to match
* {@link PropertyChangeEvent}s by their property name. The concrete behaviour depends on the
* matchPropertyNames
parameter. If you want to match property change events
* against a known set of property names, use a value of true
. Alternatively,
* when you specify false
, the specified property names will serve as an exclude
* list, e.g. if an event matches a specified property name, it will be filtered out.
*
* These matchers are especially useful as an event matcher in a bean connector.
*
* @param matchPropertyNames if true
, match property change events against the
* specified property names, if false
filter them
* @param propertyNames the property names to consider
* @see GlazedLists#beanConnector(Class, Matcher)
*/
public static Matcher propertyEventNameMatcher(boolean matchPropertyNames, String... propertyNames) {
return new PropertyEventNameMatcher(matchPropertyNames, propertyNames);
}
/**
* Iterate through the specified collection and count all elements
* that match the specified matcher.
*
* @return the number of elements in the collection that are matched
*/
public static int count(Collection collection, Matcher super E> matcher) {
int count = 0;
for (Iterator i = collection.iterator(); i.hasNext();)
if (matcher.matches(i.next()))
count++;
return count;
}
/**
* Iterate through the specified collection and remove all elements
* that don't match the specified matcher.
*
* @return true
if any elements were removed from the specified
* {@link Collection}
*/
public static boolean filter(Collection collection, Matcher super E> matcher) {
boolean changed = false;
for (Iterator i = collection.iterator(); i.hasNext();) {
if (!matcher.matches(i.next())) {
i.remove();
changed = true;
}
}
return changed;
}
/**
* Return a new array containing only the items
that satisfy
* the matcher
.
*
* @param items the array of Objects to search
* @param matcher the criteria for considering an element a match
* @return a new array containing only the items
that satisfy
* the matcher
*/
public static E[] select(E[] items, Matcher super E> matcher) {
final Collection super E> selections = select(Arrays.asList(items), matcher);
return selections.toArray((E[]) Array.newInstance(items.getClass().getComponentType(), selections.size()));
}
/**
* Add all elements from the given collection
that satisfy the
* matcher
to a new ArrayList
.
*
* @param collection the Collection to search
* @param matcher the criteria for considering an element a match
* @return a new {@link ArrayList} containing the elements which satisfy
* the matcher
*/
public static Collection super E> select(Collection collection, Matcher super E> matcher) {
return select(collection, matcher, new ArrayList());
}
/**
* Add all elements from the given collection
that satisfy the
* matcher
to the given results
Collection.
* results
can be any Collection that supports the
* {@link Collection#add} operation.
*
* @param collection the Collection to search
* @param matcher the criteria for considering an element a match
* @param results the Collection into which matching elements are added
* @return the results
{@link Collection} containing the
* elements which satisfy the matcher
*/
public static Collection super E> select(Collection collection, Matcher super E> matcher, Collection super E> results) {
for (Iterator i = collection.iterator(); i.hasNext();) {
E element = i.next();
if (matcher.matches(element))
results.add(element);
}
return results;
}
/**
* Returns true if the given collection
contains an
* element that satisfies the given matcher
; false
* otherise.
*
* @param collection the Collection to search
* @param matcher the criteria for considering an element a match
* @return true if the given collection
contains an
* element that satisfies the given matcher
;
* false otherise
*/
public static boolean contains(Collection collection, Matcher super E> matcher) {
for (Iterator i = collection.iterator(); i.hasNext();)
if (matcher.matches(i.next()))
return true;
return false;
}
/**
* Returns the index of the first element from the given list
* that satisfies the matcher
or -1 if no such
* element exists.
*
* @param list the List to search
* @param matcher the criteria for considering an element a match
* @return the index of the first element from the given list
* that satisfies the matcher
or -1 if no such
* element exists
*/
public static int indexOf(List list, Matcher super E> matcher) {
for (int i = 0, n = list.size(); i < n; i++) {
if (matcher.matches(list.get(i)))
return i;
}
return -1;
}
/**
* Returns a Matcher which returns a match when any of the
* given matchers
reports a match.
*
* @param matchers the Collection of Matchers to combine with an "or" operator
* @return a Matcher that combines the matchers
via an "or" operator
*/
public static Matcher or(Matcher super E>... matchers) {
return new OrMatcher(matchers);
}
/**
* Returns a Matcher which returns a match when all of the
* given matchers
report a match.
*
* @param matchers the Collection of Matchers to combine with an "and" operator
* @return a Matcher that combines the matchers
via an "and" operator
*/
public static Matcher and(Matcher super E>... matchers) {
return new AndMatcher(matchers);
}
/**
* Returns a Matcher which reports a match when the given object to match
* is not null and reports on of the given classes
as its type.
*
* @param classes the object types that are matched
* @return a Matcher which reports a match when the given object to match
* is not null and reports on of the given classes
as its
* type
*/
public static Matcher types(Class... classes) {
return new TypeMatcher(classes);
}
}