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: 45301 $ 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 * @return a set that contains headers names that should be excluded. 102 */ 103 public void setOutFilter(Set<String> value) { 104 outFilter = value; 105 } 106 107 /** 108 * Gets the "out" direction filter regular expression {@link Pattern}. The 109 * "out" direction is referred to copying headers from Camel message to 110 * an external message. If the pattern matches a header, the header will 111 * be filtered out. 112 * 113 * @return regular expression filter pattern 114 */ 115 public String getOutFilterPattern() { 116 return outFilterPattern == null ? null : outFilterPattern.pattern(); 117 } 118 119 120 /** 121 * Sets the "out" direction filter regular expression {@link Pattern}. The 122 * "out" direction is referred to copying headers from Camel message to 123 * an external message. If the pattern matches a header, the header will 124 * be filtered out. 125 * 126 * @param value regular expression filter pattern 127 */ 128 public void setOutFilterPattern(String value) { 129 if (value == null) { 130 outFilterPattern = null; 131 } else { 132 outFilterPattern = Pattern.compile(value); 133 } 134 } 135 136 /** 137 * Gets the "in" direction filter set. The "in" direction is referred to 138 * copying headers from an external message to a Camel message. 139 * 140 * @return a set that contains header names that should be excluded. 141 */ 142 public Set<String> getInFilter() { 143 if (inFilter == null) { 144 inFilter = new HashSet<String>(); 145 } 146 return inFilter; 147 } 148 149 /** 150 * Sets the "in" direction filter set. The "in" direction is referred to 151 * copying headers from an external message to a Camel message. 152 * 153 * @return a set that contains headers names that should be excluded. 154 */ 155 public void setInFilter(Set<String> value) { 156 inFilter = value; 157 } 158 159 /** 160 * Gets the "in" direction filter regular expression {@link Pattern}. The 161 * "in" direction is referred to copying headers from an external message 162 * to a Camel message. If the pattern matches a header, the header will 163 * be filtered out. 164 * 165 * @return regular expression filter pattern 166 */ 167 public String getInFilterPattern() { 168 return inFilterPattern == null ? null : inFilterPattern.pattern(); 169 } 170 171 /** 172 * Sets the "in" direction filter regular expression {@link Pattern}. The 173 * "in" direction is referred to copying headers from an external message 174 * to a Camel message. If the pattern matches a header, the header will 175 * be filtered out. 176 * 177 * @param value regular expression filter pattern 178 */ 179 public void setInFilterPattern(String value) { 180 if (value == null) { 181 inFilterPattern = null; 182 } else { 183 inFilterPattern = Pattern.compile(value); 184 } 185 } 186 187 /** 188 * Gets the isLowercase property which is a boolean to determinte 189 * whether header names should be converted to lowercase before 190 * checking it the filter Set. It does not affect filtering using 191 * regular expression pattern. 192 */ 193 public boolean getIsLowercase() { 194 return isLowercase; 195 } 196 197 /** 198 * Sets the isLowercase property which is a boolean to determinte 199 * whether header names should be converted to lowercase before 200 * checking it the filter Set. It does not affect filtering using 201 * regular expression pattern. 202 */ 203 public void setIsLowercase(boolean value) { 204 isLowercase = value; 205 } 206 207 public boolean getAllowNullValues() { 208 return allowNullValues; 209 } 210 211 public void setAllowNullValues(boolean value) { 212 allowNullValues = value; 213 } 214 215 protected boolean extendedFilter(Direction direction, String key, Object value) { 216 return false; 217 } 218 219 private boolean doFiltering(Direction direction, String headerName, Object headerValue) { 220 221 if (headerName == null) { 222 return true; 223 } 224 225 if (headerValue == null && !allowNullValues) { 226 return true; 227 } 228 229 Pattern pattern = null; 230 Set<String> filter = null; 231 232 if (Direction.OUT == direction) { 233 pattern = outFilterPattern; 234 filter = outFilter; 235 } else if (Direction.IN == direction) { 236 pattern = inFilterPattern; 237 filter = inFilter; 238 } 239 240 if (pattern != null && pattern.matcher(headerName).matches()) { 241 return true; 242 } 243 244 if (filter != null) { 245 if (isLowercase) { 246 if (filter.contains(headerName.toLowerCase())) { 247 return true; 248 } 249 } else { 250 if (filter.contains(headerName)) { 251 return true; 252 } 253 } 254 } 255 256 if (extendedFilter(direction, headerName, headerValue)) { 257 return true; 258 } 259 260 return false; 261 } 262 }