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.camel.impl;
018
019 import java.util.HashSet;
020 import java.util.Set;
021 import java.util.regex.Pattern;
022
023 import org.apache.camel.Exchange;
024 import org.apache.camel.spi.HeaderFilterStrategy;
025
026 /**
027 * The default header filtering strategy. Users can configure filter by
028 * setting filter set and/or setting a regular expression. Subclass can
029 * add extended filter logic in
030 * {@link #extendedFilter(Direction, String, Object, Exchange)}
031 *
032 * Filters are associated with directions (in or out). "In" direction is
033 * referred to propagating headers "to" Camel message. The "out" direction
034 * is opposite which is referred to propagating headers from Camel message
035 * to a native message like JMS and CXF message. You can see example of
036 * DefaultHeaderFilterStrategy are being extended and invoked in camel-jms
037 * and camel-cxf components.
038 *
039 * @version $Revision: 758505 $
040 */
041 public class DefaultHeaderFilterStrategy implements HeaderFilterStrategy {
042
043 private Set<String> inFilter;
044 private Pattern inFilterPattern;
045
046 private Set<String> outFilter;
047 private Pattern outFilterPattern;
048
049 private boolean lowerCase;
050 private boolean allowNullValues;
051
052 public boolean applyFilterToCamelHeaders(String headerName, Object headerValue, Exchange exchange) {
053 return doFiltering(Direction.OUT, headerName, headerValue, exchange);
054 }
055
056 public boolean applyFilterToExternalHeaders(String headerName, Object headerValue, Exchange exchange) {
057 return doFiltering(Direction.IN, headerName, headerValue, exchange);
058 }
059
060 /**
061 * Gets the "out" direction filter set. The "out" direction is referred to
062 * copying headers from a Camel message to an external message.
063 *
064 * @return a set that contains header names that should be excluded.
065 */
066 public Set<String> getOutFilter() {
067 if (outFilter == null) {
068 outFilter = new HashSet<String>();
069 }
070
071 return outFilter;
072 }
073
074 /**
075 * Sets the "out" direction filter set. The "out" direction is referred to
076 * copying headers from a Camel message to an external message.
077 *
078 * @param value the filter
079 */
080 public void setOutFilter(Set<String> value) {
081 outFilter = value;
082 }
083
084 /**
085 * Gets the "out" direction filter regular expression {@link Pattern}. The
086 * "out" direction is referred to copying headers from Camel message to
087 * an external message. If the pattern matches a header, the header will
088 * be filtered out.
089 *
090 * @return regular expression filter pattern
091 */
092 public String getOutFilterPattern() {
093 return outFilterPattern == null ? null : outFilterPattern.pattern();
094 }
095
096
097 /**
098 * Sets the "out" direction filter regular expression {@link Pattern}. The
099 * "out" direction is referred to copying headers from Camel message to
100 * an external message. If the pattern matches a header, the header will
101 * be filtered out.
102 *
103 * @param value regular expression filter pattern
104 */
105 public void setOutFilterPattern(String value) {
106 if (value == null) {
107 outFilterPattern = null;
108 } else {
109 outFilterPattern = Pattern.compile(value);
110 }
111 }
112
113 /**
114 * Gets the "in" direction filter set. The "in" direction is referred to
115 * copying headers from an external message to a Camel message.
116 *
117 * @return a set that contains header names that should be excluded.
118 */
119 public Set<String> getInFilter() {
120 if (inFilter == null) {
121 inFilter = new HashSet<String>();
122 }
123 return inFilter;
124 }
125
126 /**
127 * Sets the "in" direction filter set. The "in" direction is referred to
128 * copying headers from an external message to a Camel message.
129 *
130 * @param value the filter
131 */
132 public void setInFilter(Set<String> value) {
133 inFilter = value;
134 }
135
136 /**
137 * Gets the "in" direction filter regular expression {@link Pattern}. The
138 * "in" direction is referred to copying headers from an external message
139 * to a Camel message. If the pattern matches a header, the header will
140 * be filtered out.
141 *
142 * @return regular expression filter pattern
143 */
144 public String getInFilterPattern() {
145 return inFilterPattern == null ? null : inFilterPattern.pattern();
146 }
147
148 /**
149 * Sets the "in" direction filter regular expression {@link Pattern}. The
150 * "in" direction is referred to copying headers from an external message
151 * to a Camel message. If the pattern matches a header, the header will
152 * be filtered out.
153 *
154 * @param value regular expression filter pattern
155 */
156 public void setInFilterPattern(String value) {
157 if (value == null) {
158 inFilterPattern = null;
159 } else {
160 inFilterPattern = Pattern.compile(value);
161 }
162 }
163
164 /**
165 * Gets the isLowercase property which is a boolean to determinte
166 * whether header names should be converted to lowercase before
167 * checking it the filter Set. It does not affect filtering using
168 * regular expression pattern.
169 */
170 public boolean isLowerCase() {
171 return lowerCase;
172 }
173
174 /**
175 * Sets the isLowercase property which is a boolean to determinte
176 * whether header names should be converted to lowercase before
177 * checking it the filter Set. It does not affect filtering using
178 * regular expression pattern.
179 */
180 public void setLowerCase(boolean value) {
181 lowerCase = value;
182 }
183
184 public boolean getAllowNullValues() {
185 return allowNullValues;
186 }
187
188 public void setAllowNullValues(boolean value) {
189 allowNullValues = value;
190 }
191
192 protected boolean extendedFilter(Direction direction, String key, Object value, Exchange exchange) {
193 return false;
194 }
195
196 private boolean doFiltering(Direction direction, String headerName, Object headerValue, Exchange exchange) {
197 if (headerName == null) {
198 return true;
199 }
200
201 if (headerValue == null && !allowNullValues) {
202 return true;
203 }
204
205 Pattern pattern = null;
206 Set<String> filter = null;
207
208 if (Direction.OUT == direction) {
209 pattern = outFilterPattern;
210 filter = outFilter;
211 } else if (Direction.IN == direction) {
212 pattern = inFilterPattern;
213 filter = inFilter;
214 }
215
216 if (pattern != null && pattern.matcher(headerName).matches()) {
217 return true;
218 }
219
220 if (filter != null) {
221 if (isLowerCase()) {
222 if (filter.contains(headerName.toLowerCase())) {
223 return true;
224 }
225 } else {
226 if (filter.contains(headerName)) {
227 return true;
228 }
229 }
230 }
231
232 if (extendedFilter(direction, headerName, headerValue, exchange)) {
233 return true;
234 }
235
236 return false;
237 }
238 }