jdk/src/share/classes/javax/swing/RowFilter.java
author dmarkov
Wed, 16 Apr 2014 12:51:25 +0400
changeset 24184 4da2f6ec4dab
parent 23010 6dadb192ad81
child 25386 9ef80c24fd74
child 25568 b906a74c6882
permissions -rw-r--r--
8032874: ArrayIndexOutOfBoundsException in JTable while clearing data in JTable Reviewed-by: alexp, alexsch
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
23010
6dadb192ad81 8029235: Update copyright year to match last edit in jdk8 jdk repository for 2013
lana
parents: 21982
diff changeset
     2
 * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    23
 * questions.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
package javax.swing;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
import java.util.ArrayList;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
import java.math.BigDecimal;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
import java.math.BigInteger;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
import java.util.Date;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
import java.util.List;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
import java.util.regex.Matcher;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
import java.util.regex.Pattern;
21982
fd6e5fe509df 8029264: [doclint] more doclint and tidy cleanup
yan
parents: 20158
diff changeset
    34
import java.util.regex.PatternSyntaxException;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
 * <code>RowFilter</code> is used to filter out entries from the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
 * model so that they are not shown in the view.  For example, a
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
 * <code>RowFilter</code> associated with a <code>JTable</code> might
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
 * only allow rows that contain a column with a specific string. The
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
 * meaning of <em>entry</em> depends on the component type.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
 * For example, when a filter is
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
 * associated with a <code>JTable</code>, an entry corresponds to a
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
 * row; when associated with a <code>JTree</code>, an entry corresponds
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
 * to a node.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
 * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
 * Subclasses must override the <code>include</code> method to
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
 * indicate whether the entry should be shown in the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
 * view.  The <code>Entry</code> argument can be used to obtain the values in
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
 * each of the columns in that entry.  The following example shows an
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
 * <code>include</code> method that allows only entries containing one or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
 * more values starting with the string "a":
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
 * <pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
 * RowFilter&lt;Object,Object&gt; startsWithAFilter = new RowFilter&lt;Object,Object&gt;() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
 *   public boolean include(Entry&lt;? extends Object, ? extends Object&gt; entry) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
 *     for (int i = entry.getValueCount() - 1; i &gt;= 0; i--) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
 *       if (entry.getStringValue(i).startsWith("a")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
 *         // The value starts with "a", include it
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
 *         return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
 *       }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
 *     }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
 *     // None of the columns start with "a"; return false so that this
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
 *     // entry is not shown
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
 *     return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
 *   }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
 * };
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
 * </pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
 * <code>RowFilter</code> has two formal type parameters that allow
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
 * you to create a <code>RowFilter</code> for a specific model. For
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
 * example, the following assumes a specific model that is wrapping
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
 * objects of type <code>Person</code>.  Only <code>Person</code>s
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
 * with an age over 20 will be shown:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
 * <pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
 * RowFilter&lt;PersonModel,Integer&gt; ageFilter = new RowFilter&lt;PersonModel,Integer&gt;() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
 *   public boolean include(Entry&lt;? extends PersonModel, ? extends Integer&gt; entry) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
 *     PersonModel personModel = entry.getModel();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
 *     Person person = personModel.getPerson(entry.getIdentifier());
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
 *     if (person.getAge() &gt; 20) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
 *       // Returning true indicates this row should be shown.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
 *       return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
 *     }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
 *     // Age is &lt;= 20, don't show it.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
 *     return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
 *   }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
 * };
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
 * PersonModel model = createPersonModel();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
 * TableRowSorter&lt;PersonModel&gt; sorter = new TableRowSorter&lt;PersonModel&gt;(model);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
 * sorter.setRowFilter(ageFilter);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
 * </pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
 * @param <M> the type of the model; for example <code>PersonModel</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
 * @param <I> the type of the identifier; when using
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
 *            <code>TableRowSorter</code> this will be <code>Integer</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
 * @see javax.swing.table.TableRowSorter
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
 * @since 1.6
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
public abstract class RowFilter<M,I> {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
     * Enumeration of the possible comparison values supported by
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
     * some of the default <code>RowFilter</code>s.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
     * @see RowFilter
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
     * @since 1.6
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
    public enum ComparisonType {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
         * Indicates that entries with a value before the supplied
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
         * value should be included.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
        BEFORE,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
         * Indicates that entries with a value after the supplied
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
         * value should be included.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
        AFTER,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
         * Indicates that entries with a value equal to the supplied
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
         * value should be included.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
        EQUAL,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
         * Indicates that entries with a value not equal to the supplied
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
         * value should be included.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
        NOT_EQUAL
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
     * Throws an IllegalArgumentException if any of the values in
21982
fd6e5fe509df 8029264: [doclint] more doclint and tidy cleanup
yan
parents: 20158
diff changeset
   133
     * columns are {@literal <} 0.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
    private static void checkIndices(int[] columns) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
        for (int i = columns.length - 1; i >= 0; i--) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
            if (columns[i] < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
                throw new IllegalArgumentException("Index must be >= 0");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
     * Returns a <code>RowFilter</code> that uses a regular
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
     * expression to determine which entries to include.  Only entries
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
     * with at least one matching value are included.  For
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
     * example, the following creates a <code>RowFilter</code> that
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
     * includes entries with at least one value starting with
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
     * "a":
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
     * <pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
     *   RowFilter.regexFilter("^a");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
     * </pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
     * The returned filter uses {@link java.util.regex.Matcher#find}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
     * to test for inclusion.  To test for exact matches use the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
     * characters '^' and '$' to match the beginning and end of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
     * string respectively.  For example, "^foo$" includes only rows whose
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
     * string is exactly "foo" and not, for example, "food".  See
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
     * {@link java.util.regex.Pattern} for a complete description of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
     * the supported regular-expression constructs.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
     * @param regex the regular expression to filter on
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
     * @param indices the indices of the values to check.  If not supplied all
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
     *               values are evaluated
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
     * @return a <code>RowFilter</code> implementing the specified criteria
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
     * @throws NullPointerException if <code>regex</code> is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
     *         <code>null</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
     * @throws IllegalArgumentException if any of the <code>indices</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
     *         are &lt; 0
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
     * @throws PatternSyntaxException if <code>regex</code> is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
     *         not a valid regular expression.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
     * @see java.util.regex.Pattern
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
    public static <M,I> RowFilter<M,I> regexFilter(String regex,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
                                                       int... indices) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
        return (RowFilter<M,I>)new RegexFilter(Pattern.compile(regex),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
                                               indices);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
     * Returns a <code>RowFilter</code> that includes entries that
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
     * have at least one <code>Date</code> value meeting the specified
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
     * criteria.  For example, the following <code>RowFilter</code> includes
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
     * only entries with at least one date value after the current date:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
     * <pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
     *   RowFilter.dateFilter(ComparisonType.AFTER, new Date());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
     * </pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
     * @param type the type of comparison to perform
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
     * @param date the date to compare against
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
     * @param indices the indices of the values to check.  If not supplied all
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
     *               values are evaluated
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
     * @return a <code>RowFilter</code> implementing the specified criteria
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
     * @throws NullPointerException if <code>date</code> is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
     *          <code>null</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
     * @throws IllegalArgumentException if any of the <code>indices</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
     *         are &lt; 0 or <code>type</code> is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
     *         <code>null</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
     * @see java.util.Calendar
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
     * @see java.util.Date
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
    public static <M,I> RowFilter<M,I> dateFilter(ComparisonType type,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
                                            Date date, int... indices) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
        return (RowFilter<M,I>)new DateFilter(type, date.getTime(), indices);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
     * Returns a <code>RowFilter</code> that includes entries that
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
     * have at least one <code>Number</code> value meeting the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
     * specified criteria.  For example, the following
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
     * filter will only include entries with at
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
     * least one number value equal to 10:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
     * <pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
     *   RowFilter.numberFilter(ComparisonType.EQUAL, 10);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
     * </pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
     * @param type the type of comparison to perform
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
     * @param indices the indices of the values to check.  If not supplied all
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
     *               values are evaluated
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
     * @return a <code>RowFilter</code> implementing the specified criteria
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
     * @throws IllegalArgumentException if any of the <code>indices</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
     *         are &lt; 0, <code>type</code> is <code>null</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
     *         or <code>number</code> is <code>null</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
    public static <M,I> RowFilter<M,I> numberFilter(ComparisonType type,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
                                            Number number, int... indices) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
        return (RowFilter<M,I>)new NumberFilter(type, number, indices);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
     * Returns a <code>RowFilter</code> that includes entries if any
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
     * of the supplied filters includes the entry.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
     * The following example creates a <code>RowFilter</code> that will
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
     * include any entries containing the string "foo" or the string
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
     * "bar":
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
     * <pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
     *   List&lt;RowFilter&lt;Object,Object&gt;&gt; filters = new ArrayList&lt;RowFilter&lt;Object,Object&gt;&gt;(2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
     *   filters.add(RowFilter.regexFilter("foo"));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
     *   filters.add(RowFilter.regexFilter("bar"));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
     *   RowFilter&lt;Object,Object&gt; fooBarFilter = RowFilter.orFilter(filters);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
     * </pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
     * @param filters the <code>RowFilter</code>s to test
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
     * @throws IllegalArgumentException if any of the filters
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
     *         are <code>null</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
     * @throws NullPointerException if <code>filters</code> is null
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
     * @return a <code>RowFilter</code> implementing the specified criteria
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
     * @see java.util.Arrays#asList
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
    public static <M,I> RowFilter<M,I> orFilter(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
            Iterable<? extends RowFilter<? super M, ? super I>> filters) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
        return new OrFilter<M,I>(filters);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
     * Returns a <code>RowFilter</code> that includes entries if all
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
     * of the supplied filters include the entry.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
     * The following example creates a <code>RowFilter</code> that will
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
     * include any entries containing the string "foo" and the string
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
     * "bar":
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
     * <pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
     *   List&lt;RowFilter&lt;Object,Object&gt;&gt; filters = new ArrayList&lt;RowFilter&lt;Object,Object&gt;&gt;(2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
     *   filters.add(RowFilter.regexFilter("foo"));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
     *   filters.add(RowFilter.regexFilter("bar"));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
     *   RowFilter&lt;Object,Object&gt; fooBarFilter = RowFilter.andFilter(filters);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
     * </pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
     * @param filters the <code>RowFilter</code>s to test
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
     * @return a <code>RowFilter</code> implementing the specified criteria
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
     * @throws IllegalArgumentException if any of the filters
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
     *         are <code>null</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
     * @throws NullPointerException if <code>filters</code> is null
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
     * @see java.util.Arrays#asList
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
    public static <M,I> RowFilter<M,I> andFilter(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
            Iterable<? extends RowFilter<? super M, ? super I>> filters) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
        return new AndFilter<M,I>(filters);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
     * Returns a <code>RowFilter</code> that includes entries if the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
     * supplied filter does not include the entry.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
     * @param filter the <code>RowFilter</code> to negate
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
     * @return a <code>RowFilter</code> implementing the specified criteria
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
     * @throws IllegalArgumentException if <code>filter</code> is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
     *         <code>null</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
    public static <M,I> RowFilter<M,I> notFilter(RowFilter<M,I> filter) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
        return new NotFilter<M,I>(filter);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
     * Returns true if the specified entry should be shown;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
     * returns false if the entry should be hidden.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
     * The <code>entry</code> argument is valid only for the duration of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
     * the invocation.  Using <code>entry</code> after the call returns
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
     * results in undefined behavior.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
     * @param entry a non-<code>null</code> object that wraps the underlying
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
     *              object from the model
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
     * @return true if the entry should be shown
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
    public abstract boolean include(Entry<? extends M, ? extends I> entry);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
    //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
    // WARNING:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
    // Because of the method signature of dateFilter/numberFilter/regexFilter
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
    // we can NEVER add a method to RowFilter that returns M,I. If we were
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
    // to do so it would be possible to get a ClassCastException during normal
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
    // usage.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
    //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
     * An <code>Entry</code> object is passed to instances of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
     * <code>RowFilter</code>, allowing the filter to get the value of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
     * entry's data, and thus to determine whether the entry should be shown.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
     * An <code>Entry</code> object contains information about the model
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
     * as well as methods for getting the underlying values from the model.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
     * @param <M> the type of the model; for example <code>PersonModel</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
     * @param <I> the type of the identifier; when using
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
     *            <code>TableRowSorter</code> this will be <code>Integer</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
     * @see javax.swing.RowFilter
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
     * @see javax.swing.DefaultRowSorter#setRowFilter(javax.swing.RowFilter)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
     * @since 1.6
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
    public static abstract class Entry<M, I> {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
         * Creates an <code>Entry</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
        public Entry() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
         * Returns the underlying model.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
         * @return the model containing the data that this entry represents
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
        public abstract M getModel();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
         * Returns the number of values in the entry.  For
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
         * example, when used with a table this corresponds to the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
         * number of columns.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
         * @return number of values in the object being filtered
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
        public abstract int getValueCount();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
         * Returns the value at the specified index.  This may return
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
         * <code>null</code>.  When used with a table, index
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
         * corresponds to the column number in the model.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
         * @param index the index of the value to get
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
         * @return value at the specified index
20158
1c5d22e5b898 8025117: [cleanup] Eliminate doclint errors in javax/swing/text classes
yan
parents: 5506
diff changeset
   361
         * @throws IndexOutOfBoundsException if index &lt; 0 or
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
         *         &gt;= getValueCount
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
        public abstract Object getValue(int index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
         * Returns the string value at the specified index.  If
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
         * filtering is being done based on <code>String</code> values
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
         * this method is preferred to that of <code>getValue</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
         * as <code>getValue(index).toString()</code> may return a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
         * different result than <code>getStringValue(index)</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
         * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
         * This implementation calls <code>getValue(index).toString()</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
         * after checking for <code>null</code>.  Subclasses that provide
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
         * different string conversion should override this method if
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
         * necessary.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
         * @param index the index of the value to get
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
         * @return {@code non-null} string at the specified index
20158
1c5d22e5b898 8025117: [cleanup] Eliminate doclint errors in javax/swing/text classes
yan
parents: 5506
diff changeset
   380
         * @throws IndexOutOfBoundsException if index &lt; 0 ||
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
         *         &gt;= getValueCount
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
        public String getStringValue(int index) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
            Object value = getValue(index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
            return (value == null) ? "" : value.toString();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
         * Returns the identifer (in the model) of the entry.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
         * For a table this corresponds to the index of the row in the model,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
         * expressed as an <code>Integer</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
         * @return a model-based (not view-based) identifier for
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
         *         this entry
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
        public abstract I getIdentifier();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
    private static abstract class GeneralFilter extends RowFilter<Object,Object> {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
        private int[] columns;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
        GeneralFilter(int[] columns) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
            checkIndices(columns);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
            this.columns = columns;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
        public boolean include(Entry<? extends Object,? extends Object> value){
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
            int count = value.getValueCount();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
            if (columns.length > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
                for (int i = columns.length - 1; i >= 0; i--) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
                    int index = columns[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
                    if (index < count) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
                        if (include(value, index)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
                            return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
            else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
                while (--count >= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
                    if (include(value, count)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
                        return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
        protected abstract boolean include(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
              Entry<? extends Object,? extends Object> value, int index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
    private static class RegexFilter extends GeneralFilter {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
        private Matcher matcher;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
        RegexFilter(Pattern regex, int[] columns) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
            super(columns);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
            if (regex == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
                throw new IllegalArgumentException("Pattern must be non-null");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
            matcher = regex.matcher("");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
        protected boolean include(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
                Entry<? extends Object,? extends Object> value, int index) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
            matcher.reset(value.getStringValue(index));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
            return matcher.find();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
    private static class DateFilter extends GeneralFilter {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
        private long date;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
        private ComparisonType type;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
        DateFilter(ComparisonType type, long date, int[] columns) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
            super(columns);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
            if (type == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
                throw new IllegalArgumentException("type must be non-null");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
            this.type = type;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
            this.date = date;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
        protected boolean include(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
                Entry<? extends Object,? extends Object> value, int index) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
            Object v = value.getValue(index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
            if (v instanceof Date) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
                long vDate = ((Date)v).getTime();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
                switch(type) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
                case BEFORE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
                    return (vDate < date);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
                case AFTER:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
                    return (vDate > date);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
                case EQUAL:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
                    return (vDate == date);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
                case NOT_EQUAL:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
                    return (vDate != date);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
                default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
    private static class NumberFilter extends GeneralFilter {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
        private boolean isComparable;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
        private Number number;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
        private ComparisonType type;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
        NumberFilter(ComparisonType type, Number number, int[] columns) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
            super(columns);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
            if (type == null || number == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
                throw new IllegalArgumentException(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
                    "type and number must be non-null");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
            this.type = type;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
            this.number = number;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
            isComparable = (number instanceof Comparable);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
        @SuppressWarnings("unchecked")
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
        protected boolean include(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
                Entry<? extends Object,? extends Object> value, int index) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
            Object v = value.getValue(index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
            if (v instanceof Number) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
                boolean compared = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
                int compareResult;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
                Class vClass = v.getClass();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
                if (number.getClass() == vClass && isComparable) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
                    compareResult = ((Comparable)number).compareTo(v);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
                else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
                    compareResult = longCompare((Number)v);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
                switch(type) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
                case BEFORE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
                    return (compareResult > 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
                case AFTER:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
                    return (compareResult < 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
                case EQUAL:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
                    return (compareResult == 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
                case NOT_EQUAL:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
                    return (compareResult != 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
                default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
        private int longCompare(Number o) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
            long diff = number.longValue() - o.longValue();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
            if (diff < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
                return -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
            else if (diff > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
                return 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
            return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
    private static class OrFilter<M,I> extends RowFilter<M,I> {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
        List<RowFilter<? super M,? super I>> filters;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
        OrFilter(Iterable<? extends RowFilter<? super M, ? super I>> filters) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
            this.filters = new ArrayList<RowFilter<? super M,? super I>>();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
            for (RowFilter<? super M, ? super I> filter : filters) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
                if (filter == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
                    throw new IllegalArgumentException(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
                        "Filter must be non-null");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
                this.filters.add(filter);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
        public boolean include(Entry<? extends M, ? extends I> value) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
            for (RowFilter<? super M,? super I> filter : filters) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
                if (filter.include(value)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
                    return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   574
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
90ce3da70b43 Initial load
duke
parents:
diff changeset
   578
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
    private static class AndFilter<M,I> extends OrFilter<M,I> {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
        AndFilter(Iterable<? extends RowFilter<? super M,? super I>> filters) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   581
            super(filters);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
        public boolean include(Entry<? extends M, ? extends I> value) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
            for (RowFilter<? super M,? super I> filter : filters) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
                if (!filter.include(value)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
                    return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
            return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
    private static class NotFilter<M,I> extends RowFilter<M,I> {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
        private RowFilter<M,I> filter;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
        NotFilter(RowFilter<M,I> filter) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
            if (filter == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
                throw new IllegalArgumentException(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
                    "filter must be non-null");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
            this.filter = filter;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
        public boolean include(Entry<? extends M, ? extends I> value) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
            return !filter.include(value);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
}