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 }