All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ca.odell.glazedlists.matchers.Matchers Maven / Gradle / Ivy

The newest version!
/* 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: *

*

    *
  1. 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. *

    *

  2. 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 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 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 matcher) { final Collection 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 select(Collection collection, Matcher 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 select(Collection collection, Matcher matcher, Collection 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 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 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... 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... 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); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy