001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.data.osm;
003
004import java.util.Collection;
005import java.util.Collections;
006
007import org.openstreetmap.josm.data.osm.FilterMatcher.FilterType;
008import org.openstreetmap.josm.tools.Utils;
009
010/**
011 * Class for applying {@link Filter}s to {@link OsmPrimitive}s.
012 *
013 * Provides a bridge between Filter GUI and the data.
014 *
015 * @author Petr_DlouhĂ˝
016 */
017public final class FilterWorker {
018
019    private FilterWorker() {
020        // Hide default constructor for utils classes
021    }
022
023    /**
024     * Apply the filters to the primitives of the data set.
025     *
026     * @param all the collection of primitives for that the filter state should
027     * be updated
028     * @param filterMatcher the FilterMatcher
029     * @return true, if the filter state (normal / disabled / hidden)
030     * of any primitive has changed in the process
031     */
032    public static boolean executeFilters(Collection<OsmPrimitive> all, FilterMatcher filterMatcher) {
033        boolean changed = false;
034        // first relations, then ways and nodes last; this is required to resolve dependencies
035        changed = doExecuteFilters(Utils.filter(all, OsmPrimitive.relationPredicate), filterMatcher);
036        changed |= doExecuteFilters(Utils.filter(all, OsmPrimitive.wayPredicate), filterMatcher);
037        changed |= doExecuteFilters(Utils.filter(all, OsmPrimitive.nodePredicate), filterMatcher);
038        return changed;
039    }
040
041    private static boolean doExecuteFilters(Collection<OsmPrimitive> all, FilterMatcher filterMatcher) {
042
043        boolean changed = false;
044
045        for (OsmPrimitive primitive: all) {
046            FilterType hiddenType = filterMatcher.isHidden(primitive);
047            if (hiddenType != FilterType.NOT_FILTERED) {
048                changed |= primitive.setDisabledState(true);
049                primitive.setHiddenType(hiddenType == FilterType.EXPLICIT);
050            } else {
051                FilterType disabledType = filterMatcher.isDisabled(primitive);
052                if (disabledType != FilterType.NOT_FILTERED) {
053                    changed |= primitive.setDisabledState(false);
054                    primitive.setDisabledType(disabledType == FilterType.EXPLICIT);
055                } else {
056                    changed |= primitive.unsetDisabledState();
057                }
058            }
059        }
060        return changed;
061    }
062
063    /**
064     * Apply the filters to a single primitive.
065     *
066     * @param primitive the primitive
067     * @param filterMatcher the FilterMatcher
068     * @return true, if the filter state (normal / disabled / hidden)
069     * of the primitive has changed in the process
070     */
071    public static boolean executeFilters(OsmPrimitive primitive, FilterMatcher filterMatcher) {
072        return doExecuteFilters(Collections.singleton(primitive), filterMatcher);
073    }
074
075    /**
076     * Clear all filter flags, i.e.&nbsp;turn off filters.
077     * @param prims the primitives
078     */
079    public static void clearFilterFlags(Collection<OsmPrimitive> prims) {
080        for (OsmPrimitive osm : prims) {
081            osm.unsetDisabledState();
082        }
083    }
084}