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