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