You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

RowFilter.java 5.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. /*
  2. Copyright (c) 2008 Health Market Science, Inc.
  3. This library is free software; you can redistribute it and/or
  4. modify it under the terms of the GNU Lesser General Public
  5. License as published by the Free Software Foundation; either
  6. version 2.1 of the License, or (at your option) any later version.
  7. This library is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  10. Lesser General Public License for more details.
  11. You should have received a copy of the GNU Lesser General Public
  12. License along with this library; if not, write to the Free Software
  13. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  14. USA
  15. You can contact Health Market Science at info@healthmarketscience.com
  16. or at the following address:
  17. Health Market Science
  18. 2700 Horizon Drive
  19. Suite 200
  20. King of Prussia, PA 19406
  21. */
  22. package com.healthmarketscience.jackcess;
  23. import java.util.Iterator;
  24. import java.util.Map;
  25. import org.apache.commons.lang.ObjectUtils;
  26. /**
  27. * The RowFilter class encapsulates a filter test for a table row. This can
  28. * be used by the {@link #apply(Iterable)} method to create an Iterable over a
  29. * table which returns only rows matching some criteria.
  30. *
  31. * @author Patricia Donaldson, Xerox Corporation
  32. */
  33. public abstract class RowFilter
  34. {
  35. /**
  36. * Returns {@code true} if the given table row matches the Filter criteria,
  37. * {@code false} otherwise.
  38. * @param row current row to test for inclusion in the filter
  39. */
  40. public abstract boolean matches(Map<String, Object> row);
  41. /**
  42. * Returns an iterable which filters the given iterable based on this
  43. * filter.
  44. *
  45. * @param iterable row iterable to filter
  46. *
  47. * @return a filtering iterable
  48. */
  49. public Iterable<Map<String, Object>> apply(
  50. Iterable<Map<String, Object>> iterable)
  51. {
  52. return new FilterIterable(iterable);
  53. }
  54. /**
  55. * Creates a filter based on a row pattern.
  56. *
  57. * @param rowPattern Map from column names to the values to be matched.
  58. * A table row will match the target if
  59. * {@code ObjectUtils.equals(rowPattern.get(s), row.get(s))}
  60. * for all column names in the pattern map.
  61. * @return a filter which matches table rows which match the values in the
  62. * row pattern
  63. */
  64. public static RowFilter matchPattern(final Map<String, Object> rowPattern)
  65. {
  66. return new RowFilter() {
  67. @Override
  68. public boolean matches(Map<String, Object> row)
  69. {
  70. for(Map.Entry<String,Object> e : rowPattern.entrySet()) {
  71. if(!ObjectUtils.equals(e.getValue(), row.get(e.getKey()))) {
  72. return false;
  73. }
  74. }
  75. return true;
  76. }
  77. };
  78. }
  79. /**
  80. * Creates a filter based on a single value row pattern.
  81. *
  82. * @param columnPattern column to be matched
  83. * @param valuePattern value to be matched.
  84. * A table row will match the target if
  85. * {@code ObjectUtils.equals(valuePattern, row.get(columnPattern.getName()))}.
  86. * @return a filter which matches table rows which match the value in the
  87. * row pattern
  88. */
  89. public static RowFilter matchPattern(final Column columnPattern, final Object valuePattern)
  90. {
  91. return new RowFilter() {
  92. @Override
  93. public boolean matches(Map<String, Object> row)
  94. {
  95. return ObjectUtils.equals(valuePattern, columnPattern.getRowValue(row));
  96. }
  97. };
  98. }
  99. /**
  100. * Creates a filter which inverts the sense of the given filter (rows which
  101. * are matched by the given filter will not be matched by the returned
  102. * filter, and vice versa).
  103. *
  104. * @param filter filter which to invert
  105. *
  106. * @return a RowFilter which matches rows not matched by the given filter
  107. */
  108. public static RowFilter invert(final RowFilter filter)
  109. {
  110. return new RowFilter() {
  111. @Override
  112. public boolean matches(Map<String, Object> row)
  113. {
  114. return !filter.matches(row);
  115. }
  116. };
  117. }
  118. /**
  119. * Returns an iterable which filters the given iterable based on the given
  120. * rowFilter.
  121. *
  122. * @param rowFilter the filter criteria, may be {@code null}
  123. * @param iterable row iterable to filter
  124. *
  125. * @return a filtering iterable (or the given iterable if a {@code null}
  126. * filter was given)
  127. */
  128. public static Iterable<Map<String, Object>> apply(
  129. RowFilter rowFilter,
  130. Iterable<Map<String, Object>> iterable)
  131. {
  132. return((rowFilter != null) ? rowFilter.apply(iterable) : iterable);
  133. }
  134. /**
  135. * Iterable which creates a filtered view of a another row iterable.
  136. */
  137. private class FilterIterable implements Iterable<Map<String, Object>>
  138. {
  139. private final Iterable<Map<String, Object>> _iterable;
  140. private FilterIterable(Iterable<Map<String, Object>> iterable)
  141. {
  142. _iterable = iterable;
  143. }
  144. /**
  145. * Returns an iterator which iterates through the rows of the underlying
  146. * iterable, returning only rows for which the {@link RowFilter#matches}
  147. * method returns {@code true}
  148. */
  149. public Iterator<Map<String, Object>> iterator()
  150. {
  151. return new Iterator<Map<String, Object>>() {
  152. private final Iterator<Map<String, Object>> _iter =
  153. _iterable.iterator();
  154. private Map<String, Object> _next;
  155. public boolean hasNext() {
  156. while(_iter.hasNext()) {
  157. _next = _iter.next();
  158. if(RowFilter.this.matches(_next)) {
  159. return true;
  160. }
  161. }
  162. _next = null;
  163. return false;
  164. }
  165. public Map<String, Object> next() {
  166. return _next;
  167. }
  168. public void remove() {
  169. throw new UnsupportedOperationException();
  170. }
  171. };
  172. }
  173. }
  174. }