Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDirk Fauth2023-01-16 13:24:08 +0000
committerDirk Fauth2023-01-16 13:24:08 +0000
commit1695769432518c10d4e0991d43c0e06e334d7d71 (patch)
tree76a34b45bd2972a24214dae2d80ae16cdd6946ac
parent381fb194f968e5de1b0886f432c6a95dc4960bfd (diff)
downloadorg.eclipse.nebula.widgets.nattable-1695769432518c10d4e0991d43c0e06e334d7d71.tar.gz
org.eclipse.nebula.widgets.nattable-1695769432518c10d4e0991d43c0e06e334d7d71.tar.xz
org.eclipse.nebula.widgets.nattable-1695769432518c10d4e0991d43c0e06e334d7d71.zip
Bug 581362 - Create a filter strategy with excludes
Signed-off-by: Dirk Fauth <dirk.fauth@googlemail.com> Change-Id: I8b0500661b352475c99fbf8da6d0fe696c0a37c7
-rw-r--r--org.eclipse.nebula.widgets.nattable.examples/src/org/eclipse/nebula/widgets/nattable/examples/_600_GlazedLists/_603_Filter/_6037_MixedFilterRowExample.java140
-rw-r--r--org.eclipse.nebula.widgets.nattable.extension.glazedlists.test/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/filterrow/ComboBoxGlazedListsWithExcludeFilterStrategyTest.java156
-rw-r--r--org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/filterrow/ComboBoxGlazedListsWithExcludeFilterStrategy.java161
3 files changed, 336 insertions, 121 deletions
diff --git a/org.eclipse.nebula.widgets.nattable.examples/src/org/eclipse/nebula/widgets/nattable/examples/_600_GlazedLists/_603_Filter/_6037_MixedFilterRowExample.java b/org.eclipse.nebula.widgets.nattable.examples/src/org/eclipse/nebula/widgets/nattable/examples/_600_GlazedLists/_603_Filter/_6037_MixedFilterRowExample.java
index 05069903..9ae837ca 100644
--- a/org.eclipse.nebula.widgets.nattable.examples/src/org/eclipse/nebula/widgets/nattable/examples/_600_GlazedLists/_603_Filter/_6037_MixedFilterRowExample.java
+++ b/org.eclipse.nebula.widgets.nattable.examples/src/org/eclipse/nebula/widgets/nattable/examples/_600_GlazedLists/_603_Filter/_6037_MixedFilterRowExample.java
@@ -15,7 +15,6 @@ package org.eclipse.nebula.widgets.nattable.examples._600_GlazedLists._603_Filte
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
@@ -35,7 +34,6 @@ import org.eclipse.nebula.widgets.nattable.config.DefaultNatTableStyleConfigurat
import org.eclipse.nebula.widgets.nattable.config.IConfigRegistry;
import org.eclipse.nebula.widgets.nattable.config.IEditableRule;
import org.eclipse.nebula.widgets.nattable.data.ExtendedReflectiveColumnPropertyAccessor;
-import org.eclipse.nebula.widgets.nattable.data.IColumnAccessor;
import org.eclipse.nebula.widgets.nattable.data.IColumnPropertyAccessor;
import org.eclipse.nebula.widgets.nattable.data.IDataProvider;
import org.eclipse.nebula.widgets.nattable.data.IRowIdAccessor;
@@ -60,7 +58,7 @@ import org.eclipse.nebula.widgets.nattable.examples.AbstractNatExample;
import org.eclipse.nebula.widgets.nattable.examples.runner.StandaloneNatExampleRunner;
import org.eclipse.nebula.widgets.nattable.extension.glazedlists.GlazedListsEventLayer;
import org.eclipse.nebula.widgets.nattable.extension.glazedlists.filterrow.ComboBoxFilterRowHeaderComposite;
-import org.eclipse.nebula.widgets.nattable.extension.glazedlists.filterrow.ComboBoxGlazedListsFilterStrategy;
+import org.eclipse.nebula.widgets.nattable.extension.glazedlists.filterrow.ComboBoxGlazedListsWithExcludeFilterStrategy;
import org.eclipse.nebula.widgets.nattable.extension.glazedlists.filterrow.FilterRowUtils;
import org.eclipse.nebula.widgets.nattable.extension.glazedlists.filterrow.GlazedListsFilterRowComboBoxDataProvider;
import org.eclipse.nebula.widgets.nattable.filterrow.FilterRowDataLayer;
@@ -140,9 +138,7 @@ import ca.odell.glazedlists.FilterList;
import ca.odell.glazedlists.GlazedLists;
import ca.odell.glazedlists.SortedList;
import ca.odell.glazedlists.TransformedList;
-import ca.odell.glazedlists.matchers.CompositeMatcherEditor;
import ca.odell.glazedlists.matchers.Matcher;
-import ca.odell.glazedlists.matchers.MatcherEditor;
/**
* Example showing how to add the filter row to the layer composition of a grid
@@ -614,119 +610,6 @@ public class _6037_MixedFilterRowExample extends AbstractNatExample {
}
}
- // TODO 2.1 move this class to the GlazedLists extension
- /**
- * Specialized {@link ComboBoxGlazedListsFilterStrategy} that can be used to
- * exclude items from filtering. This means you can register a
- * {@link Matcher} that avoids that matching items get filtered by the
- * filterrow.
- *
- * @param <T>
- */
- class ComboBoxGlazedListsWithExcludeFilterStrategy<T> extends ComboBoxGlazedListsFilterStrategy<T> {
-
- private final CompositeMatcherEditor<T> compositeMatcherEditor;
-
- protected Map<Matcher<T>, MatcherEditor<T>> excludeMatcherEditor = new HashMap<>();
-
- public ComboBoxGlazedListsWithExcludeFilterStrategy(
- FilterRowComboBoxDataProvider<T> comboBoxDataProvider,
- FilterList<T> filterList,
- IColumnAccessor<T> columnAccessor,
- IConfigRegistry configRegistry) {
- super(comboBoxDataProvider, filterList, columnAccessor, configRegistry);
-
- // The default MatcherEditor is created and stored as member in the
- // DefaultGlazedListsFilterStrategy. That MatcherEditor is used for
- // the default filter operations. To exclude entries from filtering,
- // we create another CompositeMatcherEditor with an OR mode and set
- // that one on the FilterList.
- this.compositeMatcherEditor = new CompositeMatcherEditor<>();
- this.compositeMatcherEditor.setMode(CompositeMatcherEditor.OR);
-
- this.compositeMatcherEditor.getMatcherEditors().add(getMatcherEditor());
-
- this.filterList.setMatcherEditor(this.compositeMatcherEditor);
- }
-
- /**
- * Add a exclude filter to this filter strategy which will always be
- * applied additionally to any other filter to exclude from filtering.
- *
- * @param matcher
- * the exclude filter to add
- */
- public void addExcludeFilter(final Matcher<T> matcher) {
- // create a new MatcherEditor
- MatcherEditor<T> matcherEditor = GlazedLists.fixedMatcherEditor(matcher);
- addExcludeFilter(matcherEditor);
- }
-
- /**
- * Add a exclude filter to this filter strategy which will always be
- * applied additionally to any other filter to exclude items from
- * filtering.
- *
- * @param matcherEditor
- * the exclude filter to add
- */
- public void addExcludeFilter(final MatcherEditor<T> matcherEditor) {
- // add the new MatcherEditor to the CompositeMatcherEditor
- this.filterLock.writeLock().lock();
- try {
- this.compositeMatcherEditor.getMatcherEditors().add(matcherEditor);
- } finally {
- this.filterLock.writeLock().unlock();
- }
-
- this.excludeMatcherEditor.put(matcherEditor.getMatcher(), matcherEditor);
- }
-
- /**
- * Remove the exclude filter from this filter strategy.
- *
- * @param matcher
- * the filter to remove
- */
- public void removeExcludeFilter(final Matcher<T> matcher) {
- MatcherEditor<T> removed = this.excludeMatcherEditor.remove(matcher);
- if (removed != null) {
- this.filterLock.writeLock().lock();
- try {
- this.compositeMatcherEditor.getMatcherEditors().remove(removed);
- } finally {
- this.filterLock.writeLock().unlock();
- }
- }
- }
-
- /**
- * Remove the exclude filter from this filter strategy.
- *
- * @param matcherEditor
- * the filter to remove
- */
- public void removeExcludeFilter(final MatcherEditor<T> matcherEditor) {
- removeExcludeFilter(matcherEditor.getMatcher());
- }
-
- /**
- * Removes all applied exclude filters from this filter strategy.
- */
- public void clearExcludeFilter() {
- Collection<MatcherEditor<T>> excludeMatcher = this.excludeMatcherEditor.values();
- if (!excludeMatcher.isEmpty()) {
- this.filterLock.writeLock().lock();
- try {
- this.compositeMatcherEditor.getMatcherEditors().removeAll(excludeMatcher);
- } finally {
- this.filterLock.writeLock().unlock();
- }
- this.excludeMatcherEditor.clear();
- }
- }
- }
-
/**
* The configuration to enable editing of {@link PersonWithAddress} objects.
*/
@@ -849,9 +732,14 @@ public class _6037_MixedFilterRowExample extends AbstractNatExample {
FilterRowDataLayer.FILTER_ROW_COLUMN_LABEL_PREFIX
+ DataModelConstants.FIRSTNAME_COLUMN_POSITION);
- // register the FilterRowRegularExpressionConverter in the first
- // column that converts simple expressions like wildcards to valid
- // regular expressions
+ // register display converters for the first column to support an
+ // unidirectional conversion of user friendly strings to complex
+ // regular expressions.
+
+ // CellConfigAttributes.DISPLAY_CONVERTER is needed for editing.
+ // Using the DefaultDisplayConverter will simply take the entered
+ // value to the data model. That means, the filter row contains
+ // exactly the value that was entered by the user.
configRegistry.registerConfigAttribute(
CellConfigAttributes.DISPLAY_CONVERTER,
new DefaultDisplayConverter(),
@@ -859,6 +747,10 @@ public class _6037_MixedFilterRowExample extends AbstractNatExample {
FilterRowDataLayer.FILTER_ROW_COLUMN_LABEL_PREFIX
+ DataModelConstants.FIRSTNAME_COLUMN_POSITION);
+ // FilterRowConfigAttributes.FILTER_DISPLAY_CONVERTER is used to
+ // convert the value in the filter row to a filter string. It is
+ // used for the unidirectional conversion of the user value to a
+ // complex regular expression.
configRegistry.registerConfigAttribute(
FilterRowConfigAttributes.FILTER_DISPLAY_CONVERTER,
new CustomFilterRowRegularExpressionConverter(),
@@ -866,6 +758,12 @@ public class _6037_MixedFilterRowExample extends AbstractNatExample {
FilterRowDataLayer.FILTER_ROW_COLUMN_LABEL_PREFIX
+ DataModelConstants.FIRSTNAME_COLUMN_POSITION);
+ // FilterRowConfigAttributes.FILTER_CONTENT_DISPLAY_CONVERTER is
+ // needed to convert the body data. This is necessary as the filter
+ // row does not know about the display converter in the body. If it
+ // is not set it would use the FILTER_DISPLAY_CONVERTER, which would
+ // cause issues in the further processing for the regular expression
+ // conversion.
configRegistry.registerConfigAttribute(
FilterRowConfigAttributes.FILTER_CONTENT_DISPLAY_CONVERTER,
new DefaultDisplayConverter(),
diff --git a/org.eclipse.nebula.widgets.nattable.extension.glazedlists.test/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/filterrow/ComboBoxGlazedListsWithExcludeFilterStrategyTest.java b/org.eclipse.nebula.widgets.nattable.extension.glazedlists.test/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/filterrow/ComboBoxGlazedListsWithExcludeFilterStrategyTest.java
new file mode 100644
index 00000000..ab0572af
--- /dev/null
+++ b/org.eclipse.nebula.widgets.nattable.extension.glazedlists.test/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/filterrow/ComboBoxGlazedListsWithExcludeFilterStrategyTest.java
@@ -0,0 +1,156 @@
+/*******************************************************************************
+ * Copyright (c) 2023 Dirk Fauth.
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Dirk Fauth <dirk.fauth@googlemail.com> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.nebula.widgets.nattable.extension.glazedlists.filterrow;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.util.Arrays;
+
+import org.eclipse.nebula.widgets.nattable.config.ConfigRegistry;
+import org.eclipse.nebula.widgets.nattable.config.DefaultNatTableStyleConfiguration;
+import org.eclipse.nebula.widgets.nattable.data.IColumnAccessor;
+import org.eclipse.nebula.widgets.nattable.data.ListDataProvider;
+import org.eclipse.nebula.widgets.nattable.data.ReflectiveColumnPropertyAccessor;
+import org.eclipse.nebula.widgets.nattable.dataset.person.Person;
+import org.eclipse.nebula.widgets.nattable.dataset.person.PersonService;
+import org.eclipse.nebula.widgets.nattable.edit.EditConstants;
+import org.eclipse.nebula.widgets.nattable.extension.glazedlists.fixture.DataLayerFixture;
+import org.eclipse.nebula.widgets.nattable.filterrow.FilterRowDataProvider;
+import org.eclipse.nebula.widgets.nattable.filterrow.combobox.ComboBoxFilterRowConfiguration;
+import org.eclipse.nebula.widgets.nattable.filterrow.combobox.FilterRowComboBoxDataProvider;
+import org.eclipse.nebula.widgets.nattable.filterrow.config.DefaultFilterRowConfiguration;
+import org.eclipse.nebula.widgets.nattable.layer.DataLayer;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import ca.odell.glazedlists.EventList;
+import ca.odell.glazedlists.FilterList;
+import ca.odell.glazedlists.GlazedLists;
+import ca.odell.glazedlists.matchers.Matcher;
+
+public class ComboBoxGlazedListsWithExcludeFilterStrategyTest {
+
+ private FilterList<Person> filterList;
+
+ private ConfigRegistry configRegistry;
+ private DataLayerFixture columnHeaderLayer;
+ private FilterRowComboBoxDataProvider<Person> comboBoxDataProvider;
+ private ComboBoxGlazedListsWithExcludeFilterStrategy<Person> filterStrategy;
+ private FilterRowDataProvider<Person> dataProvider;
+
+ private static String[] personPropertyNames = {
+ "firstName",
+ "lastName",
+ "gender",
+ "married",
+ "birthday" };
+
+ // Homer should never be filtered
+ private static Matcher<Person> homerFilter = item -> "Homer".equals(item.getFirstName());
+
+ @BeforeEach
+ public void setup() {
+ // initialize the collection with a big amount of values
+ EventList<Person> baseCollection = GlazedLists.eventList(PersonService.getFixedPersons());
+ for (int i = 1; i < 1000; i++) {
+ baseCollection.addAll(PersonService.getFixedPersons());
+ }
+ this.filterList = new FilterList<>(GlazedLists.eventList(baseCollection));
+
+ this.configRegistry = new ConfigRegistry();
+
+ new DefaultNatTableStyleConfiguration().configureRegistry(this.configRegistry);
+ new DefaultFilterRowConfiguration().configureRegistry(this.configRegistry);
+ new ComboBoxFilterRowConfiguration().configureRegistry(this.configRegistry);
+
+ this.columnHeaderLayer = new DataLayerFixture(5, 2, 100, 50);
+
+ IColumnAccessor<Person> bodyDataColumnAccessor = new ReflectiveColumnPropertyAccessor<>(personPropertyNames);
+ this.comboBoxDataProvider = new GlazedListsFilterRowComboBoxDataProvider<>(
+ new DataLayer(new ListDataProvider<>(this.filterList, bodyDataColumnAccessor)),
+ baseCollection,
+ bodyDataColumnAccessor);
+
+ this.filterStrategy = new ComboBoxGlazedListsWithExcludeFilterStrategy<>(
+ this.comboBoxDataProvider,
+ this.filterList,
+ bodyDataColumnAccessor,
+ this.configRegistry);
+ this.dataProvider = new FilterRowDataProvider<>(
+ this.filterStrategy,
+ this.columnHeaderLayer,
+ this.columnHeaderLayer.getDataProvider(), this.configRegistry);
+ for (int i = 0; i < this.dataProvider.getColumnCount(); i++) {
+ this.dataProvider.getFilterIndexToObjectMap().put(i, EditConstants.SELECT_ALL_ITEMS_VALUE);
+ }
+ this.filterStrategy.applyFilter(this.dataProvider.getFilterIndexToObjectMap());
+ }
+
+ @Test
+ public void shouldFilterForFlanders() {
+ assertEquals(18000, this.filterList.size());
+
+ this.dataProvider.setDataValue(1, 1, Arrays.asList("Flanders"));
+
+ assertEquals(8000, this.filterList.size());
+ }
+
+ // with exclude filter
+
+ @Test
+ public void shouldFilterForFlandersWithHomerExcludeFilter() {
+ this.filterStrategy.addExcludeFilter(homerFilter);
+ assertEquals(18000, this.filterList.size());
+
+ this.dataProvider.setDataValue(1, 1, Arrays.asList("Flanders"));
+ // we now expect 8000 Flanders and the 3000 Homers that are excluded
+ // from filtering
+ assertEquals(11000, this.filterList.size());
+
+ this.filterStrategy.removeExcludeFilter(homerFilter);
+ // if Homer is not excluded anymore, only Flanders should be there
+ assertEquals(8000, this.filterList.size());
+ }
+
+ @Test
+ public void shouldFilterForFlandersWithHomerExcludeFilterAndClear() {
+ this.filterStrategy.addExcludeFilter(homerFilter);
+ assertEquals(18000, this.filterList.size());
+
+ this.dataProvider.setDataValue(1, 1, Arrays.asList("Flanders"));
+ // we now expect 8000 Flanders and the 3000 Homers that are excluded
+ // from filtering
+ assertEquals(11000, this.filterList.size());
+
+ this.filterStrategy.clearExcludeFilter();
+ // if Homer is not excluded anymore, only Flanders should be there
+ assertEquals(8000, this.filterList.size());
+ }
+
+ @Test
+ public void shouldFilterForNedFlandersWithHomerExcludeFilter() {
+ this.filterStrategy.addExcludeFilter(homerFilter);
+ assertEquals(18000, this.filterList.size());
+
+ this.dataProvider.setDataValue(0, 1, Arrays.asList("Ned"));
+ this.dataProvider.setDataValue(1, 1, Arrays.asList("Flanders"));
+ // we now expect 2000 Ned Flanders and the 3000 Homers that are excluded
+ // from filtering
+ assertEquals(5000, this.filterList.size());
+
+ this.filterStrategy.clearExcludeFilter();
+ // if Homer is not excluded anymore, only Ned Flanders should be there
+ assertEquals(2000, this.filterList.size());
+ }
+
+}
diff --git a/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/filterrow/ComboBoxGlazedListsWithExcludeFilterStrategy.java b/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/filterrow/ComboBoxGlazedListsWithExcludeFilterStrategy.java
new file mode 100644
index 00000000..fcd89433
--- /dev/null
+++ b/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/filterrow/ComboBoxGlazedListsWithExcludeFilterStrategy.java
@@ -0,0 +1,161 @@
+/*******************************************************************************
+ * Copyright (c) 2023 Dirk Fauth and others.
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Dirk Fauth <dirk.fauth@googlemail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.nebula.widgets.nattable.extension.glazedlists.filterrow;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.nebula.widgets.nattable.config.IConfigRegistry;
+import org.eclipse.nebula.widgets.nattable.data.IColumnAccessor;
+import org.eclipse.nebula.widgets.nattable.filterrow.combobox.FilterRowComboBoxDataProvider;
+
+import ca.odell.glazedlists.FilterList;
+import ca.odell.glazedlists.GlazedLists;
+import ca.odell.glazedlists.matchers.CompositeMatcherEditor;
+import ca.odell.glazedlists.matchers.Matcher;
+import ca.odell.glazedlists.matchers.MatcherEditor;
+
+/**
+ * Specialized {@link ComboBoxGlazedListsFilterStrategy} that can be used to
+ * exclude items from filtering. This means you can register a {@link Matcher}
+ * that avoids that matching items get filtered by the filter row.
+ *
+ * @param <T>
+ *
+ * @since 2.1
+ */
+public class ComboBoxGlazedListsWithExcludeFilterStrategy<T> extends ComboBoxGlazedListsFilterStrategy<T> {
+
+ private final CompositeMatcherEditor<T> compositeMatcherEditor;
+
+ protected Map<Matcher<T>, MatcherEditor<T>> excludeMatcherEditor = new HashMap<>();
+
+ /**
+ *
+ * @param comboBoxDataProvider
+ * The FilterRowComboBoxDataProvider needed to determine whether
+ * filters should applied or not. If there are no values
+ * specified for filtering of a column then everything should be
+ * filtered, if all possible values are given as filter then no
+ * filter needs to be applied.
+ * @param filterList
+ * The CompositeMatcherEditor that is used for GlazedLists
+ * filtering
+ * @param columnAccessor
+ * The IColumnAccessor needed to access the row data to perform
+ * filtering
+ * @param configRegistry
+ * The IConfigRegistry to retrieve several configurations from
+ */
+ public ComboBoxGlazedListsWithExcludeFilterStrategy(
+ FilterRowComboBoxDataProvider<T> comboBoxDataProvider,
+ FilterList<T> filterList,
+ IColumnAccessor<T> columnAccessor,
+ IConfigRegistry configRegistry) {
+ super(comboBoxDataProvider, filterList, columnAccessor, configRegistry);
+
+ // The default MatcherEditor is created and stored as member in the
+ // DefaultGlazedListsFilterStrategy. That MatcherEditor is used for
+ // the default filter operations. To exclude entries from filtering,
+ // we create another CompositeMatcherEditor with an OR mode and set
+ // that one on the FilterList.
+ // Note that we need both, the default MatcherEditor from the
+ // DefaultGlazedListsFilterStrategy for the user filters that are
+ // combined with AND mode, and the MatcherEditor with OR mode that
+ // combines the user filters with the exclude MatcherEditors registered
+ // via this strategy.
+ this.compositeMatcherEditor = new CompositeMatcherEditor<>();
+ this.compositeMatcherEditor.setMode(CompositeMatcherEditor.OR);
+
+ this.compositeMatcherEditor.getMatcherEditors().add(getMatcherEditor());
+
+ this.filterList.setMatcherEditor(this.compositeMatcherEditor);
+ }
+
+ /**
+ * Add a exclude filter to this filter strategy which will always be applied
+ * additionally to any other filter to exclude from filtering.
+ *
+ * @param matcher
+ * the exclude filter to add
+ */
+ public void addExcludeFilter(final Matcher<T> matcher) {
+ // create a new MatcherEditor
+ MatcherEditor<T> matcherEditor = GlazedLists.fixedMatcherEditor(matcher);
+ addExcludeFilter(matcherEditor);
+ }
+
+ /**
+ * Add a exclude filter to this filter strategy which will always be applied
+ * additionally to any other filter to exclude items from filtering.
+ *
+ * @param matcherEditor
+ * the exclude filter to add
+ */
+ public void addExcludeFilter(final MatcherEditor<T> matcherEditor) {
+ // add the new MatcherEditor to the CompositeMatcherEditor
+ this.filterLock.writeLock().lock();
+ try {
+ this.compositeMatcherEditor.getMatcherEditors().add(matcherEditor);
+ } finally {
+ this.filterLock.writeLock().unlock();
+ }
+
+ this.excludeMatcherEditor.put(matcherEditor.getMatcher(), matcherEditor);
+ }
+
+ /**
+ * Remove the exclude filter from this filter strategy.
+ *
+ * @param matcher
+ * the filter to remove
+ */
+ public void removeExcludeFilter(final Matcher<T> matcher) {
+ MatcherEditor<T> removed = this.excludeMatcherEditor.remove(matcher);
+ if (removed != null) {
+ this.filterLock.writeLock().lock();
+ try {
+ this.compositeMatcherEditor.getMatcherEditors().remove(removed);
+ } finally {
+ this.filterLock.writeLock().unlock();
+ }
+ }
+ }
+
+ /**
+ * Remove the exclude filter from this filter strategy.
+ *
+ * @param matcherEditor
+ * the filter to remove
+ */
+ public void removeExcludeFilter(final MatcherEditor<T> matcherEditor) {
+ removeExcludeFilter(matcherEditor.getMatcher());
+ }
+
+ /**
+ * Removes all applied exclude filters from this filter strategy.
+ */
+ public void clearExcludeFilter() {
+ Collection<MatcherEditor<T>> excludeMatcher = this.excludeMatcherEditor.values();
+ if (!excludeMatcher.isEmpty()) {
+ this.filterLock.writeLock().lock();
+ try {
+ this.compositeMatcherEditor.getMatcherEditors().removeAll(excludeMatcher);
+ } finally {
+ this.filterLock.writeLock().unlock();
+ }
+ this.excludeMatcherEditor.clear();
+ }
+ }
+} \ No newline at end of file

Back to the top