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