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 java.util.Iterator; 020import java.util.concurrent.TimeUnit; 021 022import org.apache.logging.log4j.core.AbstractLifeCycle; 023import org.apache.logging.log4j.core.Filter; 024import org.apache.logging.log4j.core.LifeCycle2; 025import org.apache.logging.log4j.core.LogEvent; 026import org.apache.logging.log4j.core.config.Property; 027import org.apache.logging.log4j.core.config.plugins.PluginElement; 028 029/** 030 * Enhances a Class by allowing it to contain Filters. 031 */ 032public abstract class AbstractFilterable extends AbstractLifeCycle implements Filterable { 033 034 /** 035 * Subclasses can extend this abstract Builder. 036 * 037 * @param <B> The type to build. 038 */ 039 public abstract static class Builder<B extends Builder<B>> { 040 041 @PluginElement("Filter") 042 private Filter filter; 043 044 // We are calling this attribute propertyArray because we use the more generic "properties" in several places 045 // with different types: Array, Map and List. 046 @PluginElement("Properties") 047 private Property[] propertyArray; 048 049 @SuppressWarnings("unchecked") 050 public B asBuilder() { 051 return (B) this; 052 } 053 054 public Filter getFilter() { 055 return filter; 056 } 057 058 public Property[] getPropertyArray() { 059 return propertyArray; 060 } 061 062 public B setFilter(final Filter filter) { 063 this.filter = filter; 064 return asBuilder(); 065 } 066 067 public B setPropertyArray(final Property[] properties) { 068 this.propertyArray = properties; 069 return asBuilder(); 070 } 071 072 /** 073 * Sets the filter. 074 * 075 * @param filter The filter 076 * @return this 077 * @deprecated Use {@link #setFilter(Filter)}. 078 */ 079 @Deprecated 080 public B withFilter(final Filter filter) { 081 return setFilter(filter); 082 } 083 084 } 085 086 /** 087 * May be null. 088 */ 089 private volatile Filter filter; 090 091 @PluginElement("Properties") 092 private final Property[] propertyArray; 093 094 protected AbstractFilterable() { 095 this(null, Property.EMPTY_ARRAY); 096 } 097 098 protected AbstractFilterable(final Filter filter) { 099 this(filter, Property.EMPTY_ARRAY); 100 } 101 102 /** 103 * @since 2.11.2 104 */ 105 protected AbstractFilterable(final Filter filter, final Property[] propertyArray) { 106 this.filter = filter; 107 this.propertyArray = propertyArray == null ? Property.EMPTY_ARRAY : propertyArray; 108 } 109 110 /** 111 * Adds a filter. 112 * @param filter The Filter to add. 113 */ 114 @Override 115 public synchronized void addFilter(final Filter filter) { 116 if (filter == null) { 117 return; 118 } 119 if (this.filter == null) { 120 this.filter = filter; 121 } else if (this.filter instanceof CompositeFilter) { 122 this.filter = ((CompositeFilter) this.filter).addFilter(filter); 123 } else { 124 final Filter[] filters = new Filter[] {this.filter, filter}; 125 this.filter = CompositeFilter.createFilters(filters); 126 } 127 } 128 129 /** 130 * Returns the Filter. 131 * @return the Filter or null. 132 */ 133 @Override 134 public Filter getFilter() { 135 return filter; 136 } 137 138 /** 139 * Determines if a Filter is present. 140 * @return false if no Filter is present. 141 */ 142 @Override 143 public boolean hasFilter() { 144 return filter != null; 145 } 146 147 /** 148 * Determine if the LogEvent should be processed or ignored. 149 * @param event The LogEvent. 150 * @return true if the LogEvent should be processed. 151 */ 152 @Override 153 public boolean isFiltered(final LogEvent event) { 154 return filter != null && filter.filter(event) == Filter.Result.DENY; 155 } 156 157 /** 158 * Removes a Filter. 159 * @param filter The Filter to remove. 160 */ 161 @Override 162 public synchronized void removeFilter(final Filter filter) { 163 if (this.filter == null || filter == null) { 164 return; 165 } 166 if (this.filter == filter || this.filter.equals(filter)) { 167 this.filter = null; 168 } else if (this.filter instanceof CompositeFilter) { 169 CompositeFilter composite = (CompositeFilter) this.filter; 170 composite = composite.removeFilter(filter); 171 if (composite.size() > 1) { 172 this.filter = composite; 173 } else if (composite.size() == 1) { 174 final Iterator<Filter> iter = composite.iterator(); 175 this.filter = iter.next(); 176 } else { 177 this.filter = null; 178 } 179 } 180 } 181 182 /** 183 * Make the Filter available for use. 184 */ 185 @Override 186 public void start() { 187 this.setStarting(); 188 if (filter != null) { 189 filter.start(); 190 } 191 this.setStarted(); 192 } 193 194 /** 195 * Cleanup the Filter. 196 */ 197 @Override 198 public boolean stop(final long timeout, final TimeUnit timeUnit) { 199 return stop(timeout, timeUnit, true); 200 } 201 202 /** 203 * Cleanup the Filter. 204 */ 205 protected boolean stop(final long timeout, final TimeUnit timeUnit, final boolean changeLifeCycleState) { 206 if (changeLifeCycleState) { 207 this.setStopping(); 208 } 209 boolean stopped = true; 210 if (filter != null) { 211 if (filter instanceof LifeCycle2) { 212 stopped = ((LifeCycle2) filter).stop(timeout, timeUnit); 213 } else { 214 filter.stop(); 215 stopped = true; 216 } 217 } 218 if (changeLifeCycleState) { 219 this.setStopped(); 220 } 221 return stopped; 222 } 223 224 public Property[] getPropertyArray() { 225 return propertyArray; 226 } 227 228}