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 org.apache.logging.log4j.Level;
020    import org.apache.logging.log4j.Marker;
021    import org.apache.logging.log4j.core.Filter;
022    import org.apache.logging.log4j.core.LifeCycle;
023    import org.apache.logging.log4j.core.LogEvent;
024    import org.apache.logging.log4j.core.Logger;
025    import org.apache.logging.log4j.core.config.plugins.Plugin;
026    import org.apache.logging.log4j.core.config.plugins.PluginElement;
027    import org.apache.logging.log4j.core.config.plugins.PluginFactory;
028    import org.apache.logging.log4j.message.Message;
029    
030    import java.util.ArrayList;
031    import java.util.Arrays;
032    import java.util.Collections;
033    import java.util.Iterator;
034    import java.util.List;
035    
036    /**
037     * Composes and invokes one or more filters.
038     */
039    @Plugin(name = "filters", type = "Core", printObject = true)
040    public final class CompositeFilter implements Iterable<Filter>, Filter, LifeCycle {
041    
042        private final List<Filter> filters;
043        private final boolean hasFilters;
044    
045        private boolean isStarted;
046    
047        private CompositeFilter() {
048            this.filters = new ArrayList<Filter>();
049            this.hasFilters = false;
050        }
051    
052        private CompositeFilter(final List<Filter> filters) {
053            if (filters == null) {
054                this.filters = Collections.unmodifiableList(new ArrayList<Filter>());
055                this.hasFilters = false;
056                return;
057            }
058            this.filters = Collections.unmodifiableList(filters);
059            this.hasFilters = this.filters.size() > 0;
060        }
061    
062        public CompositeFilter addFilter(final Filter filter) {
063            final List<Filter> filters = new ArrayList<Filter>(this.filters);
064            filters.add(filter);
065            return new CompositeFilter(Collections.unmodifiableList(filters));
066        }
067    
068        public CompositeFilter removeFilter(final Filter filter) {
069            final List<Filter> filters = new ArrayList<Filter>(this.filters);
070            filters.remove(filter);
071            return new CompositeFilter(Collections.unmodifiableList(filters));
072        }
073    
074        public Iterator<Filter> iterator() {
075            return filters.iterator();
076        }
077    
078        public List<Filter> getFilters() {
079            return filters;
080        }
081    
082        public boolean hasFilters() {
083            return hasFilters;
084        }
085    
086        public int size() {
087            return filters.size();
088        }
089    
090        public void start() {
091            for (final Filter filter : filters) {
092                if (filter instanceof LifeCycle) {
093                    ((LifeCycle) filter).start();
094                }
095            }
096            isStarted = true;
097        }
098    
099        public void stop() {
100            for (final Filter filter : filters) {
101                if (filter instanceof LifeCycle) {
102                    ((LifeCycle) filter).stop();
103                }
104            }
105            isStarted = false;
106        }
107    
108        public boolean isStarted() {
109            return isStarted;
110        }
111    
112        /**
113         * Returns the result that should be returned when the filter does not match the event.
114         *
115         * @return the Result that should be returned when the filter does not match the event.
116         */
117        public Result getOnMismatch() {
118            return Result.NEUTRAL;
119        }
120    
121        /**
122         * Returns the result that should be returned when the filter matches the event.
123         *
124         * @return the Result that should be returned when the filter matches the event.
125         */
126        public Result getOnMatch() {
127            return Result.NEUTRAL;
128        }
129    
130        /**
131         * Filter an event.
132         *
133         * @param logger
134         *            The Logger.
135         * @param level
136         *            The event logging Level.
137         * @param marker
138         *            The Marker for the event or null.
139         * @param msg
140         *            String text to filter on.
141         * @param params
142         *            An array of parameters or null.
143         * @return the Result.
144         */
145        public Result filter(final Logger logger, final Level level, final Marker marker, final String msg,
146                             final Object... params) {
147            Result result = Result.NEUTRAL;
148            for (final Filter filter : filters) {
149                result = filter.filter(logger, level, marker, msg, params);
150                if (result == Result.ACCEPT || result == Result.DENY) {
151                    return result;
152                }
153            }
154            return result;
155        }
156    
157        /**
158         * Filter an event.
159         *
160         * @param logger
161         *            The Logger.
162         * @param level
163         *            The event logging Level.
164         * @param marker
165         *            The Marker for the event or null.
166         * @param msg
167         *            Any Object.
168         * @param t
169         *            A Throwable or null.
170         * @return the Result.
171         */
172        public Result filter(final Logger logger, final Level level, final Marker marker, final Object msg,
173                             final Throwable t) {
174            Result result = Result.NEUTRAL;
175            for (final Filter filter : filters) {
176                result = filter.filter(logger, level, marker, msg, t);
177                if (result == Result.ACCEPT || result == Result.DENY) {
178                    return result;
179                }
180            }
181            return result;
182        }
183    
184        /**
185         * Filter an event.
186         *
187         * @param logger
188         *            The Logger.
189         * @param level
190         *            The event logging Level.
191         * @param marker
192         *            The Marker for the event or null.
193         * @param msg
194         *            The Message
195         * @param t
196         *            A Throwable or null.
197         * @return the Result.
198         */
199        public Result filter(final Logger logger, final Level level, final Marker marker, final Message msg,
200                             final Throwable t) {
201            Result result = Result.NEUTRAL;
202            for (final Filter filter : filters) {
203                result = filter.filter(logger, level, marker, msg, t);
204                if (result == Result.ACCEPT || result == Result.DENY) {
205                    return result;
206                }
207            }
208            return result;
209        }
210    
211        /**
212         * Filter an event.
213         *
214         * @param event
215         *            The Event to filter on.
216         * @return the Result.
217         */
218        public Result filter(final LogEvent event) {
219            Result result = Result.NEUTRAL;
220            for (final Filter filter : filters) {
221                result = filter.filter(event);
222                if (result == Result.ACCEPT || result == Result.DENY) {
223                    return result;
224                }
225            }
226            return result;
227        }
228    
229        @Override
230        public String toString() {
231            final StringBuilder sb = new StringBuilder();
232            for (final Filter filter : filters) {
233                if (sb.length() == 0) {
234                    sb.append("{");
235                } else {
236                    sb.append(", ");
237                }
238                sb.append(filter.toString());
239            }
240            if (sb.length() > 0) {
241                sb.append("}");
242            }
243            return sb.toString();
244        }
245    
246        /**
247         * Create a CompositeFilter.
248         *
249         * @param filters
250         *            An array of Filters to call.
251         * @return The CompositeFilter.
252         */
253        @PluginFactory
254        public static CompositeFilter createFilters(@PluginElement("filters") final Filter[] filters) {
255            final List<Filter> f = filters == null || filters.length == 0 ?
256                new ArrayList<Filter>() : Arrays.asList(filters);
257            return new CompositeFilter(f);
258        }
259    
260    }