001/**
002 * Logback: the reliable, generic, fast and flexible logging framework.
003 * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
004 *
005 * This program and the accompanying materials are dual-licensed under
006 * either the terms of the Eclipse Public License v1.0 as published by
007 * the Eclipse Foundation
008 *
009 *   or (per the licensee's choosing)
010 *
011 * under the terms of the GNU Lesser General Public License version 2.1
012 * as published by the Free Software Foundation.
013 */
014package ch.qos.logback.core.util;
015
016import java.util.Arrays;
017import java.util.ArrayList;
018import java.util.Collection;
019import java.util.List;
020import java.util.regex.Pattern;
021
022/**
023 * Static utility methods for working with collections of strings.
024 *
025 * @author Carl Harris
026 */
027public class StringCollectionUtil {
028
029    /**
030     * Retains all values in the subject collection that are matched by at least one
031     * of a collection of regular expressions.
032     * <p>
033     * This method is a convenience overload for
034     * {@link #retainMatching(Collection, Collection)}.
035     * 
036     * @param values   subject value collection
037     * @param patterns patterns to match
038     */
039    public static void retainMatching(Collection<String> values, String... patterns) {
040        retainMatching(values, Arrays.asList(patterns));
041    }
042
043    /**
044     * Retains all values in the subject collection that are matched by at least one
045     * of a collection of regular expressions.
046     * <p>
047     * The semantics of this method are conceptually similar to
048     * {@link Collection#retainAll(Collection)}, but uses pattern matching instead
049     * of exact matching.
050     * 
051     * @param values   subject value collection
052     * @param patterns patterns to match
053     */
054    public static void retainMatching(Collection<String> values, Collection<String> patterns) {
055        if (patterns.isEmpty())
056            return;
057        List<String> matches = new ArrayList<String>(values.size());
058        for (String p : patterns) {
059            Pattern pattern = Pattern.compile(p);
060            for (String value : values) {
061                if (pattern.matcher(value).matches()) {
062                    matches.add(value);
063                }
064            }
065        }
066        values.retainAll(matches);
067    }
068
069    /**
070     * Removes all values in the subject collection that are matched by at least one
071     * of a collection of regular expressions.
072     * <p>
073     * This method is a convenience overload for
074     * {@link #removeMatching(Collection, Collection)}.
075     * 
076     * @param values   subject value collection
077     * @param patterns patterns to match
078     */
079    public static void removeMatching(Collection<String> values, String... patterns) {
080        removeMatching(values, Arrays.asList(patterns));
081    }
082
083    /**
084     * Removes all values in the subject collection that are matched by at least one
085     * of a collection of regular expressions.
086     * <p>
087     * The semantics of this method are conceptually similar to
088     * {@link Collection#removeAll(Collection)}, but uses pattern matching instead
089     * of exact matching.
090     * 
091     * @param values   subject value collection
092     * @param patterns patterns to match
093     */
094    public static void removeMatching(Collection<String> values, Collection<String> patterns) {
095        List<String> matches = new ArrayList<String>(values.size());
096        for (String p : patterns) {
097            Pattern pattern = Pattern.compile(p);
098            for (String value : values) {
099                if (pattern.matcher(value).matches()) {
100                    matches.add(value);
101                }
102            }
103        }
104        values.removeAll(matches);
105    }
106
107}