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 */
017package org.apache.logging.log4j.core.filter;
018
019import org.apache.logging.log4j.Level;
020import org.apache.logging.log4j.Marker;
021import org.apache.logging.log4j.core.AbstractLifeCycle;
022import org.apache.logging.log4j.core.Filter;
023import org.apache.logging.log4j.core.LogEvent;
024import org.apache.logging.log4j.core.Logger;
025import org.apache.logging.log4j.core.config.plugins.PluginBuilderAttribute;
026import org.apache.logging.log4j.message.Message;
027
028/**
029 * Users should extend this class to implement filters. Filters can be either context wide or attached to
030 * an appender. A filter may choose to support being called only from the context or only from an appender in
031 * which case it will only implement the required method(s). The rest will default to return {@link org.apache.logging.log4j.core.Filter.Result#NEUTRAL}.
032 * <p>
033 * Garbage-free note: the methods with unrolled varargs by default delegate to the
034 * {@link #filter(Logger, Level, Marker, String, Object...) filter method with vararg parameters}.
035 * Subclasses that want to be garbage-free should override these methods to implement the appropriate filtering
036 * without creating a vararg array.
037 * </p>
038 */
039public abstract class AbstractFilter extends AbstractLifeCycle implements Filter {
040
041    public static abstract class AbstractFilterBuilder<B extends AbstractFilterBuilder<B>>  {
042
043        public static final String ATTR_ON_MISMATCH = "onMismatch";
044        public static final String ATTR_ON_MATCH = "onMatch";
045
046        @PluginBuilderAttribute(ATTR_ON_MATCH)
047        private Result onMatch = Result.NEUTRAL;
048
049        @PluginBuilderAttribute(ATTR_ON_MISMATCH)
050        private Result onMismatch = Result.DENY;
051
052        public Result getOnMatch() {
053            return onMatch;
054        }
055
056        public Result getOnMismatch() {
057            return onMismatch;
058        }
059
060        /**
061         * Sets the Result to return when the filter matches. Defaults to Result.NEUTRAL.
062         * @param onMatch the Result to return when the filter matches.
063         * @return this
064         */
065        public B setOnMatch(final Result onMatch) {
066            this.onMatch = onMatch;
067            return asBuilder();
068        }
069
070        /**
071         * Sets the Result to return when the filter does not match. The default is Result.DENY.
072         * @param onMismatch the Result to return when the filter does not match. 
073         * @return this
074         */
075        public B setOnMismatch(final Result onMismatch) {
076            this.onMismatch = onMismatch;
077            return asBuilder();
078        }
079        
080        @SuppressWarnings("unchecked")
081        public B asBuilder() {
082            return (B) this;
083        }
084
085    }
086    
087    /**
088     * The onMatch Result.
089     */
090    protected final Result onMatch;
091
092    /**
093     * The onMismatch Result.
094     */
095    protected final Result onMismatch;
096
097    /**
098     * The default constructor.
099     */
100    protected AbstractFilter() {
101        this(null, null);
102    }
103
104    /**
105     * Constructor that allows the onMatch and onMismatch actions to be set.
106     * @param onMatch The result to return when a match occurs.
107     * @param onMismatch The result to return when a match dos not occur.
108     */
109    protected AbstractFilter(final Result onMatch, final Result onMismatch) {
110        this.onMatch = onMatch == null ? Result.NEUTRAL : onMatch;
111        this.onMismatch = onMismatch == null ? Result.DENY : onMismatch;
112    }
113
114    @Override
115    protected boolean equalsImpl(final Object obj) {
116        if (this == obj) {
117            return true;
118        }
119        if (!super.equalsImpl(obj)) {
120            return false;
121        }
122        if (getClass() != obj.getClass()) {
123            return false;
124        }
125        final AbstractFilter other = (AbstractFilter) obj;
126        if (onMatch != other.onMatch) {
127            return false;
128        }
129        if (onMismatch != other.onMismatch) {
130            return false;
131        }
132        return true;
133    }
134
135    /**
136     * Context Filter method. The default returns NEUTRAL.
137     * @param event The LogEvent.
138     * @return The Result of filtering.
139     */
140    @Override
141    public Result filter(final LogEvent event) {
142        return Result.NEUTRAL;
143    }
144
145    /**
146     * Appender Filter method. The default returns NEUTRAL.
147     * @param logger the Logger.
148     * @param level The logging Level.
149     * @param marker The Marker, if any.
150     * @param msg The message, if present.
151     * @param t A throwable or null.
152     * @return The Result of filtering.
153     */
154    @Override
155    public Result filter(final Logger logger, final Level level, final Marker marker, final Message msg,
156                         final Throwable t) {
157        return Result.NEUTRAL;
158    }
159
160    /**
161     * Appender Filter method. The default returns NEUTRAL.
162     * @param logger the Logger.
163     * @param level The logging Level.
164     * @param marker The Marker, if any.
165     * @param msg The message, if present.
166     * @param t A throwable or null.
167     * @return The Result of filtering.
168     */
169    @Override
170    public Result filter(final Logger logger, final Level level, final Marker marker, final Object msg,
171                         final Throwable t) {
172        return Result.NEUTRAL;
173    }
174
175    /**
176     * Appender Filter method. The default returns NEUTRAL.
177     * @param logger the Logger.
178     * @param level The logging Level.
179     * @param marker The Marker, if any.
180     * @param msg The message, if present.
181     * @param params An array of parameters or null.
182     * @return The Result of filtering.
183     */
184    @Override
185    public Result filter(final Logger logger, final Level level, final Marker marker, final String msg,
186                         final Object... params) {
187        return Result.NEUTRAL;
188    }
189
190    /**
191     * Appender Filter method. The default returns NEUTRAL.
192     * @param logger the Logger.
193     * @param level The logging Level.
194     * @param marker The Marker, if any.
195     * @param msg The message, if present.
196     * @param p0 the message parameters
197     * @return The Result of filtering.
198     * @since 2.7
199     */
200    @Override
201    public Result filter(final Logger logger, final Level level, final Marker marker, final String msg,
202            final Object p0) {
203        return filter(logger, level, marker, msg, new Object[] {p0});
204    }
205
206    /**
207     * Appender Filter method. The default returns NEUTRAL.
208     * @param logger the Logger.
209     * @param level The logging Level.
210     * @param marker The Marker, if any.
211     * @param msg The message, if present.
212     * @param p0 the message parameters
213     * @param p1 the message parameters
214     * @return The Result of filtering.
215     * @since 2.7
216     */
217    @Override
218    public Result filter(final Logger logger, final Level level, final Marker marker, final String msg,
219            final Object p0, final Object p1) {
220        return filter(logger, level, marker, msg, new Object[] {p0, p1});
221    }
222
223    /**
224     * Appender Filter method. The default returns NEUTRAL.
225     * @param logger the Logger.
226     * @param level The logging Level.
227     * @param marker The Marker, if any.
228     * @param msg The message, if present.
229     * @param p0 the message parameters
230     * @param p1 the message parameters
231     * @param p2 the message parameters
232     * @return The Result of filtering.
233     * @since 2.7
234     */
235    @Override
236    public Result filter(final Logger logger, final Level level, final Marker marker, final String msg,
237            final Object p0, final Object p1, final Object p2) {
238        return filter(logger, level, marker, msg, new Object[] {p0, p1, p2});
239    }
240
241    /**
242     * Appender Filter method. The default returns NEUTRAL.
243     * @param logger the Logger.
244     * @param level The logging Level.
245     * @param marker The Marker, if any.
246     * @param msg The message, if present.
247     * @param p0 the message parameters
248     * @param p1 the message parameters
249     * @param p2 the message parameters
250     * @param p3 the message parameters
251     * @return The Result of filtering.
252     * @since 2.7
253     */
254    @Override
255    public Result filter(final Logger logger, final Level level, final Marker marker, final String msg,
256            final Object p0, final Object p1, final Object p2, final Object p3) {
257        return filter(logger, level, marker, msg, new Object[] {p0, p1, p2, p3});
258    }
259
260    /**
261     * Appender Filter method. The default returns NEUTRAL.
262     * @param logger the Logger.
263     * @param level The logging Level.
264     * @param marker The Marker, if any.
265     * @param msg The message, if present.
266     * @param p0 the message parameters
267     * @param p1 the message parameters
268     * @param p2 the message parameters
269     * @param p3 the message parameters
270     * @param p4 the message parameters
271     * @return The Result of filtering.
272     * @since 2.7
273     */
274    @Override
275    public Result filter(final Logger logger, final Level level, final Marker marker, final String msg,
276            final Object p0, final Object p1, final Object p2, final Object p3,
277            final Object p4) {
278        return filter(logger, level, marker, msg, new Object[] {p0, p1, p2, p3, p4});
279    }
280
281    /**
282     * Appender Filter method. The default returns NEUTRAL.
283     * @param logger the Logger.
284     * @param level The logging Level.
285     * @param marker The Marker, if any.
286     * @param msg The message, if present.
287     * @param p0 the message parameters
288     * @param p1 the message parameters
289     * @param p2 the message parameters
290     * @param p3 the message parameters
291     * @param p4 the message parameters
292     * @param p5 the message parameters
293     * @return The Result of filtering.
294     * @since 2.7
295     */
296    @Override
297    public Result filter(final Logger logger, final Level level, final Marker marker, final String msg,
298            final Object p0, final Object p1, final Object p2, final Object p3,
299            final Object p4, final Object p5) {
300        return filter(logger, level, marker, msg, new Object[] {p0, p1, p2, p3, p4, p5});
301    }
302
303    /**
304     * Appender Filter method. The default returns NEUTRAL.
305     * @param logger the Logger.
306     * @param level The logging Level.
307     * @param marker The Marker, if any.
308     * @param msg The message, if present.
309     * @param p0 the message parameters
310     * @param p1 the message parameters
311     * @param p2 the message parameters
312     * @param p3 the message parameters
313     * @param p4 the message parameters
314     * @param p5 the message parameters
315     * @param p6 the message parameters
316     * @return The Result of filtering.
317     * @since 2.7
318     */
319    @Override
320    public Result filter(final Logger logger, final Level level, final Marker marker, final String msg,
321            final Object p0, final Object p1, final Object p2, final Object p3,
322            final Object p4, final Object p5, final Object p6) {
323        return filter(logger, level, marker, msg, new Object[] {p0, p1, p2, p3, p4, p5, p6});
324    }
325
326    /**
327     * Appender Filter method. The default returns NEUTRAL.
328     * @param logger the Logger.
329     * @param level The logging Level.
330     * @param marker The Marker, if any.
331     * @param msg The message, if present.
332     * @param p0 the message parameters
333     * @param p1 the message parameters
334     * @param p2 the message parameters
335     * @param p3 the message parameters
336     * @param p4 the message parameters
337     * @param p5 the message parameters
338     * @param p6 the message parameters
339     * @param p7 the message parameters
340     * @return The Result of filtering.
341     * @since 2.7
342     */
343    @Override
344    public Result filter(final Logger logger, final Level level, final Marker marker, final String msg,
345            final Object p0, final Object p1, final Object p2, final Object p3,
346            final Object p4, final Object p5, final Object p6,
347            final Object p7) {
348        return filter(logger, level, marker, msg, new Object[] {p0, p1, p2, p3, p4, p5, p6, p7});
349    }
350
351    /**
352     * Appender Filter method. The default returns NEUTRAL.
353     * @param logger the Logger.
354     * @param level The logging Level.
355     * @param marker The Marker, if any.
356     * @param msg The message, if present.
357     * @param p0 the message parameters
358     * @param p1 the message parameters
359     * @param p2 the message parameters
360     * @param p3 the message parameters
361     * @param p4 the message parameters
362     * @param p5 the message parameters
363     * @param p6 the message parameters
364     * @param p7 the message parameters
365     * @param p8 the message parameters
366     * @return The Result of filtering.
367     * @since 2.7
368     */
369    @Override
370    public Result filter(final Logger logger, final Level level, final Marker marker, final String msg,
371            final Object p0, final Object p1, final Object p2, final Object p3,
372            final Object p4, final Object p5, final Object p6,
373            final Object p7, final Object p8) {
374        return filter(logger, level, marker, msg, new Object[] {p0, p1, p2, p3, p4, p5, p6, p7, p8});
375    }
376
377    /**
378     * Appender Filter method. The default returns NEUTRAL.
379     * @param logger the Logger.
380     * @param level The logging Level.
381     * @param marker The Marker, if any.
382     * @param msg The message, if present.
383     * @param p0 the message parameters
384     * @param p1 the message parameters
385     * @param p2 the message parameters
386     * @param p3 the message parameters
387     * @param p4 the message parameters
388     * @param p5 the message parameters
389     * @param p6 the message parameters
390     * @param p7 the message parameters
391     * @param p8 the message parameters
392     * @param p9 the message parameters
393     * @return The Result of filtering.
394     * @since 2.7
395     */
396    @Override
397    public Result filter(final Logger logger, final Level level, final Marker marker, final String msg,
398            final Object p0, final Object p1, final Object p2, final Object p3,
399            final Object p4, final Object p5, final Object p6,
400            final Object p7, final Object p8, final Object p9) {
401        return filter(logger, level, marker, msg, new Object[] {p0, p1, p2, p3, p4, p5, p6, p7, p8, p9});
402    }
403
404    /**
405     * Returns the Result to be returned when a match occurs.
406     * @return the onMatch Result.
407     */
408    @Override
409    public final Result getOnMatch() {
410        return onMatch;
411    }
412
413    /**
414     * Returns the Result to be returned when a match does not occur.
415     * @return the onMismatch Result.
416     */
417    @Override
418    public final Result getOnMismatch() {
419        return onMismatch;
420    }
421
422    @Override
423    protected int hashCodeImpl() {
424        final int prime = 31;
425        int result = super.hashCodeImpl();
426        result = prime * result + ((onMatch == null) ? 0 : onMatch.hashCode());
427        result = prime * result + ((onMismatch == null) ? 0 : onMismatch.hashCode());
428        return result;
429    }
430
431    @Override
432    public String toString() {
433        return this.getClass().getSimpleName();
434    }
435}