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.Locale; 021import java.util.Set; 022import java.util.regex.Pattern; 023 024import org.apache.camel.Exchange; 025import 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 */ 042public 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 private boolean caseInsensitive; 053 054 public boolean applyFilterToCamelHeaders(String headerName, Object headerValue, Exchange exchange) { 055 return doFiltering(Direction.OUT, headerName, headerValue, exchange); 056 } 057 058 public boolean applyFilterToExternalHeaders(String headerName, Object headerValue, Exchange exchange) { 059 return doFiltering(Direction.IN, headerName, headerValue, exchange); 060 } 061 062 /** 063 * Gets the "out" direction filter set. The "out" direction is referred to 064 * copying headers from a Camel message to an external message. 065 * 066 * @return a set that contains header names that should be excluded. 067 */ 068 public Set<String> getOutFilter() { 069 if (outFilter == null) { 070 outFilter = new HashSet<String>(); 071 } 072 073 return outFilter; 074 } 075 076 /** 077 * Sets the "out" direction filter set. The "out" direction is referred to 078 * copying headers from a Camel message to an external message. 079 * 080 * @param value the filter 081 */ 082 public void setOutFilter(Set<String> value) { 083 outFilter = value; 084 } 085 086 /** 087 * Gets the "out" direction filter regular expression {@link Pattern}. The 088 * "out" direction is referred to copying headers from Camel message to 089 * an external message. If the pattern matches a header, the header will 090 * be filtered out. 091 * 092 * @return regular expression filter pattern 093 */ 094 public String getOutFilterPattern() { 095 return outFilterPattern == null ? null : outFilterPattern.pattern(); 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 determine 167 * whether header names should be converted to lower case before 168 * checking it with 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 determine 177 * whether header names should be converted to lower case before 178 * checking it with 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 /** 186 * Gets the caseInsensitive property which is a boolean to determine 187 * whether header names should be case insensitive when checking it 188 * with the filter set. 189 * It does not affect filtering using regular expression pattern. 190 * 191 * @return <tt>true</tt> if header names is case insensitive. 192 */ 193 public boolean isCaseInsensitive() { 194 return caseInsensitive; 195 } 196 197 /** 198 * Sets the caseInsensitive property which is a boolean to determine 199 * whether header names should be case insensitive when checking it 200 * with the filter set. 201 * It does not affect filtering using regular expression pattern, 202 * 203 * @param caseInsensitive <tt>true</tt> if header names is case insensitive. 204 */ 205 public void setCaseInsensitive(boolean caseInsensitive) { 206 this.caseInsensitive = caseInsensitive; 207 } 208 209 public boolean isAllowNullValues() { 210 return allowNullValues; 211 } 212 213 public void setAllowNullValues(boolean value) { 214 allowNullValues = value; 215 } 216 217 protected boolean extendedFilter(Direction direction, String key, Object value, Exchange exchange) { 218 return false; 219 } 220 221 private boolean doFiltering(Direction direction, String headerName, Object headerValue, Exchange exchange) { 222 if (headerName == null) { 223 return true; 224 } 225 226 if (headerValue == null && !allowNullValues) { 227 return true; 228 } 229 230 Pattern pattern = null; 231 Set<String> filter = null; 232 233 if (Direction.OUT == direction) { 234 pattern = outFilterPattern; 235 filter = outFilter; 236 } else if (Direction.IN == direction) { 237 pattern = inFilterPattern; 238 filter = inFilter; 239 } 240 241 if (pattern != null && pattern.matcher(headerName).matches()) { 242 return true; 243 } 244 245 if (filter != null) { 246 if (isCaseInsensitive()) { 247 for (String filterString : filter) { 248 if (filterString.equalsIgnoreCase(headerName)) { 249 return true; 250 } 251 } 252 } else if (isLowerCase()) { 253 if (filter.contains(headerName.toLowerCase(Locale.ENGLISH))) { 254 return true; 255 } 256 } else { 257 if (filter.contains(headerName)) { 258 return true; 259 } 260 } 261 } 262 263 return extendedFilter(direction, headerName, headerValue, exchange); 264 } 265 266}