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.Locale;
021 import java.util.Set;
022 import java.util.regex.Pattern;
023
024 import org.apache.camel.Exchange;
025 import org.apache.camel.spi.HeaderFilterStrategy;
026
027 /**
028 * The default header filtering strategy. Users can configure filter by
029 * setting filter set and/or setting a regular expression. Subclass can
030 * add extended filter logic in
031 * {@link #extendedFilter(org.apache.camel.spi.HeaderFilterStrategy.Direction, String, Object, org.apache.camel.Exchange)}
032 *
033 * Filters are associated with directions (in or out). "In" direction is
034 * referred to propagating headers "to" Camel message. The "out" direction
035 * is opposite which is referred to propagating headers from Camel message
036 * to a native message like JMS and CXF message. You can see example of
037 * DefaultHeaderFilterStrategy are being extended and invoked in camel-jms
038 * and camel-cxf components.
039 *
040 * @version
041 */
042 public class DefaultHeaderFilterStrategy implements HeaderFilterStrategy {
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, Exchange exchange) {
054 return doFiltering(Direction.OUT, headerName, headerValue, exchange);
055 }
056
057 public boolean applyFilterToExternalHeaders(String headerName, Object headerValue, Exchange exchange) {
058 return doFiltering(Direction.IN, headerName, headerValue, exchange);
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 * 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 determine
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 determine
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 isAllowNullValues() {
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(Locale.ENGLISH))) {
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
239 }