    001    /*
    002     * Licensed to the Apache Software Foundation (ASF) under one or more
    003     * contributor license agreements. See the NOTICE file distributed with
    004     * this work for additional information regarding copyright ownership.
    005     * The ASF licenses this file to You under the Apache license, Version 2.0
    006     * (the "License"); you may not use this file except in compliance with
    007     * the License. You may obtain a copy of the License at
    008     *
    009     *      http://www.apache.org/licenses/LICENSE-2.0
    010     *
    011     * Unless required by applicable law or agreed to in writing, software
    012     * distributed under the License is distributed on an "AS IS" BASIS,
    013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    014     * See the license for the specific language governing permissions and
    015     * limitations under the license.
    016     */
    017    package org.apache.logging.log4j.core.filter;
    018
    019    import java.util.ArrayList;
    020    import java.util.Arrays;
    021    import java.util.Collections;
    022    import java.util.Iterator;
    023    import java.util.List;
    024
    025    import org.apache.logging.log4j.Level;
    026    import org.apache.logging.log4j.Marker;
    027    import org.apache.logging.log4j.core.AbstractLifeCycle;
    028    import org.apache.logging.log4j.core.Filter;
    029    import org.apache.logging.log4j.core.LogEvent;
    030    import org.apache.logging.log4j.core.Logger;
    031    import org.apache.logging.log4j.core.config.Node;
    032    import org.apache.logging.log4j.core.config.plugins.Plugin;
    033    import org.apache.logging.log4j.core.config.plugins.PluginElement;
    034    import org.apache.logging.log4j.core.config.plugins.PluginFactory;
    035    import org.apache.logging.log4j.message.Message;
    036
    037    /**
    038     * Composes and invokes one or more filters.
    039     */
    040    @Plugin(name = "filters", category = Node.CATEGORY, printObject = true)
    041    public final class CompositeFilter extends AbstractLifeCycle implements Iterable<Filter>, Filter {
    042
    043        private static final long serialVersionUID = 1L;
    044
    045        private final List<Filter> filters;
    046
    047        private CompositeFilter() {
    048            this.filters = new ArrayList<Filter>();
    049        }
    050
    051        private CompositeFilter(final List<Filter> filters) {
    052            if (filters == null) {
    053                this.filters = Collections.unmodifiableList(new ArrayList<Filter>());
    054                return;
    055            }
    056            this.filters = Collections.unmodifiableList(filters);
    057        }
    058
    059        public CompositeFilter addFilter(final Filter filter) {
    060            if (filter == null) {
    061                // null does nothing
    062                return this;
    063            }
    064            final List<Filter> filterList = new ArrayList<Filter>(this.filters);
    065            filterList.add(filter);
    066            return new CompositeFilter(Collections.unmodifiableList(filterList));
    067        }
    068
    069        public CompositeFilter removeFilter(final Filter filter) {
    070            if (filter == null) {
    071                // null does nothing
    072                return this;
    073            }
    074            final List<Filter> filterList = new ArrayList<Filter>(this.filters);
    075            filterList.remove(filter);
    076            return new CompositeFilter(Collections.unmodifiableList(filterList));
    077        }
    078
    079        @Override
    080        public Iterator<Filter> iterator() {
    081            return filters.iterator();
    082        }
    083
    084        public List<Filter> getFilters() {
    085            return filters;
    086        }
    087
    088        /**
    089         * Returns whether this composite contains any filters.
    090         *
    091         * @return whether this composite contains any filters.
    092         */
    093        public boolean isEmpty() {
    094            return this.filters.isEmpty();
    095        }
    096
    097        public int size() {
    098            return filters.size();
    099        }
    100
    101        @Override
    102        public void start() {
    103            this.setStarting();
    104            for (final Filter filter : filters) {
    105                filter.start();
    106            }
    107            this.setStarted();
    108        }
    109
    110        @Override
    111        public void stop() {
    112            this.setStopping();
    113            for (final Filter filter : filters) {
    114                filter.stop();
    115            }
    116            this.setStopped();
    117        }
    118
    119        /**
    120         * Returns the result that should be returned when the filter does not match the event.
    121         *
    122         * @return the Result that should be returned when the filter does not match the event.
    123         */
    124        @Override
    125        public Result getOnMismatch() {
    126            return Result.NEUTRAL;
    127        }
    128
    129        /**
    130         * Returns the result that should be returned when the filter matches the event.
    131         *
    132         * @return the Result that should be returned when the filter matches the event.
    133         */
    134        @Override
    135        public Result getOnMatch() {
    136            return Result.NEUTRAL;
    137        }
    138
    139        /**
    140         * Filter an event.
    141         *
    142         * @param logger
    143         *            The Logger.
    144         * @param level
    145         *            The event logging Level.
    146         * @param marker
    147         *            The Marker for the event or null.
    148         * @param msg
    149         *            String text to filter on.
    150         * @param params
    151         *            An array of parameters or null.
    152         * @return the Result.
    153         */
    154        @Override
    155        public Result filter(final Logger logger, final Level level, final Marker marker, final String msg,
    156                             final Object... params) {
    157            Result result = Result.NEUTRAL;
    158            for (final Filter filter : filters) {
    159                result = filter.filter(logger, level, marker, msg, params);
    160                if (result == Result.ACCEPT || result == Result.DENY) {
    161                    return result;
    162                }
    163            }
    164            return result;
    165        }
    166
    167        /**
    168         * Filter an event.
    169         *
    170         * @param logger
    171         *            The Logger.
    172         * @param level
    173         *            The event logging Level.
    174         * @param marker
    175         *            The Marker for the event or null.
    176         * @param msg
    177         *            Any Object.
    178         * @param t
    179         *            A Throwable or null.
    180         * @return the Result.
    181         */
    182        @Override
    183        public Result filter(final Logger logger, final Level level, final Marker marker, final Object msg,
    184                             final Throwable t) {
    185            Result result = Result.NEUTRAL;
    186            for (final Filter filter : filters) {
    187                result = filter.filter(logger, level, marker, msg, t);
    188                if (result == Result.ACCEPT || result == Result.DENY) {
    189                    return result;
    190                }
    191            }
    192            return result;
    193        }
    194
    195        /**
    196         * Filter an event.
    197         *
    198         * @param logger
    199         *            The Logger.
    200         * @param level
    201         *            The event logging Level.
    202         * @param marker
    203         *            The Marker for the event or null.
    204         * @param msg
    205         *            The Message
    206         * @param t
    207         *            A Throwable or null.
    208         * @return the Result.
    209         */
    210        @Override
    211        public Result filter(final Logger logger, final Level level, final Marker marker, final Message msg,
    212                             final Throwable t) {
    213            Result result = Result.NEUTRAL;
    214            for (final Filter filter : filters) {
    215                result = filter.filter(logger, level, marker, msg, t);
    216                if (result == Result.ACCEPT || result == Result.DENY) {
    217                    return result;
    218                }
    219            }
    220            return result;
    221        }
    222
    223        /**
    224         * Filter an event.
    225         *
    226         * @param event
    227         *            The Event to filter on.
    228         * @return the Result.
    229         */
    230        @Override
    231        public Result filter(final LogEvent event) {
    232            Result result = Result.NEUTRAL;
    233            for (final Filter filter : filters) {
    234                result = filter.filter(event);
    235                if (result == Result.ACCEPT || result == Result.DENY) {
    236                    return result;
    237                }
    238            }
    239            return result;
    240        }
    241
    242        @Override
    243        public String toString() {
    244            final StringBuilder sb = new StringBuilder();
    245            for (final Filter filter : filters) {
    246                if (sb.length() == 0) {
    247                    sb.append('{');
    248                } else {
    249                    sb.append(", ");
    250                }
    251                sb.append(filter.toString());
    252            }
    253            if (sb.length() > 0) {
    254                sb.append('}');
    255            }
    256            return sb.toString();
    257        }
    258
    259        /**
    260         * Create a CompositeFilter.
    261         *
    262         * @param filters
    263         *            An array of Filters to call.
    264         * @return The CompositeFilter.
    265         */
    266        @PluginFactory
    267        public static CompositeFilter createFilters(@PluginElement("Filters") final Filter[] filters) {
    268            final List<Filter> filterList = filters == null || filters.length == 0 ?
    269                new ArrayList<Filter>() : Arrays.asList(filters);
    270            return new CompositeFilter(filterList);
    271        }
    272
    273    }