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.Iterator;
020    
021    import org.apache.logging.log4j.core.AbstractLifeCycle;
022    import org.apache.logging.log4j.core.Filter;
023    import org.apache.logging.log4j.core.LogEvent;
024    
025    /**
026     * Enhances a Class by allowing it to contain Filters.
027     */
028    public abstract class AbstractFilterable extends AbstractLifeCycle implements Filterable {
029    
030        /**
031         * May be null.
032         */
033        private volatile Filter filter;
034    
035        protected AbstractFilterable(final Filter filter) {
036            this.filter = filter;
037        }
038    
039        protected AbstractFilterable() {
040        }
041    
042        /**
043         * Returns the Filter.
044         * @return the Filter or null.
045         */
046        @Override
047        public Filter getFilter() {
048            return filter;
049        }
050    
051        /**
052         * Adds a filter.
053         * @param filter The Filter to add.
054         */
055        @Override
056        public synchronized void addFilter(final Filter filter) {
057            if (this.filter == null) {
058                this.filter = filter;
059            } else if (filter instanceof CompositeFilter) {
060                this.filter = ((CompositeFilter) this.filter).addFilter(filter);
061            } else {
062                final Filter[] filters = new Filter[] {this.filter, filter};
063                this.filter = CompositeFilter.createFilters(filters);
064            }
065        }
066    
067        /**
068         * Removes a Filter.
069         * @param filter The Filter to remove.
070         */
071        @Override
072        public synchronized void removeFilter(final Filter filter) {
073            if (this.filter == filter) {
074                this.filter = null;
075            } else if (filter instanceof CompositeFilter) {
076                CompositeFilter composite = (CompositeFilter) filter;
077                composite = composite.removeFilter(filter);
078                if (composite.size() > 1) {
079                    this.filter = composite;
080                } else if (composite.size() == 1) {
081                    final Iterator<Filter> iter = composite.iterator();
082                    this.filter = iter.next();
083                } else {
084                    this.filter = null;
085                }
086            }
087        }
088    
089        /**
090         * Determines if a Filter is present.
091         * @return false if no Filter is present.
092         */
093        @Override
094        public boolean hasFilter() {
095            return filter != null;
096        }
097    
098        /**
099         * Make the Filter available for use.
100         */
101        @Override
102        public void start() {
103            this.setStarting();
104            if (filter != null) {
105                filter.start();
106            }
107            this.setStarted();
108        }
109    
110        /**
111         * Cleanup the Filter.
112         */
113        @Override
114        public void stop() {
115            this.setStopping();
116           if (filter != null) {
117               filter.stop();
118           }
119           this.setStopped();
120        }
121    
122        /**
123         * Determine if the LogEvent should be processed or ignored.
124         * @param event The LogEvent.
125         * @return true if the LogEvent should be processed.
126         */
127        @Override
128        public boolean isFiltered(final LogEvent event) {
129            return filter != null && filter.filter(event) == Filter.Result.DENY;
130        }
131    
132    }