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 be updated
027     * @param filterMatcher the FilterMatcher
028     * @return true, if the filter state (normal / disabled / hidden)
029     * of any primitive has changed in the process
030     */
031    public static boolean executeFilters(Collection<OsmPrimitive> all, FilterMatcher filterMatcher) {
032        boolean changed;
033        // first relations, then ways and nodes last; this is required to resolve dependencies
034        changed = doExecuteFilters(Utils.filter(all, OsmPrimitive.relationPredicate), filterMatcher);
035        changed |= doExecuteFilters(Utils.filter(all, OsmPrimitive.wayPredicate), filterMatcher);
036        changed |= doExecuteFilters(Utils.filter(all, OsmPrimitive.nodePredicate), filterMatcher);
037        return changed;
038    }
039
040    private static boolean doExecuteFilters(Collection<OsmPrimitive> all, FilterMatcher filterMatcher) {
041
042        boolean changed = false;
043
044        for (OsmPrimitive primitive: all) {
045            FilterType hiddenType = filterMatcher.isHidden(primitive);
046            if (hiddenType != FilterType.NOT_FILTERED) {
047                changed |= primitive.setDisabledState(true);
048                primitive.setHiddenType(hiddenType == FilterType.EXPLICIT);
049            } else {
050                FilterType disabledType = filterMatcher.isDisabled(primitive);
051                if (disabledType != FilterType.NOT_FILTERED) {
052                    changed |= primitive.setDisabledState(false);
053                    primitive.setDisabledType(disabledType == FilterType.EXPLICIT);
054                } else {
055                    changed |= primitive.unsetDisabledState();
056                }
057            }
058        }
059        return changed;
060    }
061
062    /**
063     * Apply the filters to a single primitive.
064     *
065     * @param primitive the primitive
066     * @param filterMatcher the FilterMatcher
067     * @return true, if the filter state (normal / disabled / hidden)
068     * of the primitive has changed in the process
069     */
070    public static boolean executeFilters(OsmPrimitive primitive, FilterMatcher filterMatcher) {
071        return doExecuteFilters(Collections.singleton(primitive), filterMatcher);
072    }
073
074    /**
075     * Clear all filter flags, i.e.&nbsp;turn off filters.
076     * @param prims the primitives
077     */
078    public static void clearFilterFlags(Collection<OsmPrimitive> prims) {
079        for (OsmPrimitive osm : prims) {
080            osm.unsetDisabledState();
081        }
082    }
083}