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: 747062 $
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 lowerCase;
051 private boolean allowNullValues;
052
053 public boolean applyFilterToCamelHeaders(String headerName, Object headerValue) {
054 return doFiltering(Direction.OUT, headerName, headerValue);
055 }
056
057 public boolean applyFilterToExternalHeaders(String headerName, Object headerValue) {
058 return doFiltering(Direction.IN, headerName, headerValue);
059 }
060
061 /**
062 * Gets the "out" direction filter set. The "out" direction is referred to
063 * copying headers from a Camel message to an external message.
064 *
065 * @return a set that contains header names that should be excluded.
066 */
067 public Set<String> getOutFilter() {
068 if (outFilter == null) {
069 outFilter = new HashSet<String>();
070 }
071
072 return outFilter;
073 }
074
075 /**
076 * Sets the "out" direction filter set. The "out" direction is referred to
077 * copying headers from a Camel message to an external message.
078 *
079 * @param value the filter
080 */
081 public void setOutFilter(Set<String> value) {
082 outFilter = value;
083 }
084
085 /**
086 * Gets the "out" direction filter regular expression {@link Pattern}. The
087 * "out" direction is referred to copying headers from Camel message to
088 * an external message. If the pattern matches a header, the header will
089 * be filtered out.
090 *
091 * @return regular expression filter pattern
092 */
093 public String getOutFilterPattern() {
094 return outFilterPattern == null ? null : outFilterPattern.pattern();
095 }
096
097
098 /**
099 * Sets the "out" direction filter regular expression {@link Pattern}. The
100 * "out" direction is referred to copying headers from Camel message to
101 * an external message. If the pattern matches a header, the header will
102 * be filtered out.
103 *
104 * @param value regular expression filter pattern
105 */
106 public void setOutFilterPattern(String value) {
107 if (value == null) {
108 outFilterPattern = null;
109 } else {
110 outFilterPattern = Pattern.compile(value);
111 }
112 }
113
114 /**
115 * Gets the "in" direction filter set. The "in" direction is referred to
116 * copying headers from an external message to a Camel message.
117 *
118 * @return a set that contains header names that should be excluded.
119 */
120 public Set<String> getInFilter() {
121 if (inFilter == null) {
122 inFilter = new HashSet<String>();
123 }
124 return inFilter;
125 }
126
127 /**
128 * Sets the "in" direction filter set. The "in" direction is referred to
129 * copying headers from an external message to a Camel message.
130 *
131 * @param value the filter
132 */
133 public void setInFilter(Set<String> value) {
134 inFilter = value;
135 }
136
137 /**
138 * Gets the "in" direction filter regular expression {@link Pattern}. The
139 * "in" direction is referred to copying headers from an external message
140 * to a Camel message. If the pattern matches a header, the header will
141 * be filtered out.
142 *
143 * @return regular expression filter pattern
144 */
145 public String getInFilterPattern() {
146 return inFilterPattern == null ? null : inFilterPattern.pattern();
147 }
148
149 /**
150 * Sets the "in" direction filter regular expression {@link Pattern}. The
151 * "in" direction is referred to copying headers from an external message
152 * to a Camel message. If the pattern matches a header, the header will
153 * be filtered out.
154 *
155 * @param value regular expression filter pattern
156 */
157 public void setInFilterPattern(String value) {
158 if (value == null) {
159 inFilterPattern = null;
160 } else {
161 inFilterPattern = Pattern.compile(value);
162 }
163 }
164
165 /**
166 * Gets the isLowercase property which is a boolean to determinte
167 * whether header names should be converted to lowercase before
168 * checking it the filter Set. It does not affect filtering using
169 * regular expression pattern.
170 */
171 public boolean isLowerCase() {
172 return lowerCase;
173 }
174
175 /**
176 * Sets the isLowercase property which is a boolean to determinte
177 * whether header names should be converted to lowercase before
178 * checking it the filter Set. It does not affect filtering using
179 * regular expression pattern.
180 */
181 public void setLowerCase(boolean value) {
182 lowerCase = value;
183 }
184
185 public boolean getAllowNullValues() {
186 return allowNullValues;
187 }
188
189 public void setAllowNullValues(boolean value) {
190 allowNullValues = value;
191 }
192
193 protected boolean extendedFilter(Direction direction, String key, Object value) {
194 return false;
195 }
196
197 private boolean doFiltering(Direction direction, String headerName, Object headerValue) {
198 if (headerName == null) {
199 return true;
200 }
201
202 if (headerValue == null && !allowNullValues) {
203 return true;
204 }
205
206 Pattern pattern = null;
207 Set<String> filter = null;
208
209 if (Direction.OUT == direction) {
210 pattern = outFilterPattern;
211 filter = outFilter;
212 } else if (Direction.IN == direction) {
213 pattern = inFilterPattern;
214 filter = inFilter;
215 }
216
217 if (pattern != null && pattern.matcher(headerName).matches()) {
218 return true;
219 }
220
221 if (filter != null) {
222 if (isLowerCase()) {
223 if (filter.contains(headerName.toLowerCase())) {
224 return true;
225 }
226 } else {
227 if (filter.contains(headerName)) {
228 return true;
229 }
230 }
231 }
232
233 if (extendedFilter(direction, headerName, headerValue)) {
234 return true;
235 }
236
237 return false;
238 }
239 }