/* * Copyright (c) MuleSoft, Inc. All rights reserved. http://www.mulesoft.com * The software in this package is published under the terms of the CPAL v1.0 * license, a copy of which has been included with this distribution in the * LICENSE.txt file. */ package org.mule.runtime.core.routing.filters; import static org.mule.runtime.core.util.ClassUtils.equal; import static org.mule.runtime.core.util.ClassUtils.hash; import org.mule.runtime.api.message.Message; import org.mule.runtime.api.metadata.DataType; import org.mule.runtime.core.api.MuleContext; import org.mule.runtime.core.api.Event; import org.mule.runtime.core.api.context.MuleContextAware; import org.mule.runtime.core.api.routing.filter.Filter; import org.mule.runtime.core.api.routing.filter.ObjectFilter; import org.mule.runtime.core.util.ClassUtils; import org.mule.runtime.core.util.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * <code>WildcardFilter</code> is used to match Strings against wildcards. It performs matches with "*", i.e. "jms.events.*" would * catch "jms.events.customer" and "jms.events.receipts". This filter accepts a comma-separated list of patterns, so more than one * filter pattern can be matched for a given argument: "jms.events.*, jms.actions.*" will match "jms.events.system" and * "jms.actions" but not "jms.queue". */ public class WildcardFilter implements Filter, ObjectFilter, MuleContextAware { protected final Logger logger = LoggerFactory.getLogger(this.getClass()); protected volatile String pattern; protected volatile String[] patterns; private volatile boolean caseSensitive = true; private MuleContext muleContext; public WildcardFilter() { super(); } public WildcardFilter(String pattern) { this.setPattern(pattern); } @Override public boolean accept(Message message, Event.Builder builder) { try { return accept(muleContext.getTransformationService().transform(message, DataType.STRING).getPayload().getValue()); } catch (Exception e) { logger.warn("An exception occurred while filtering", e); return false; } } @Override public boolean accept(Object object) { if (object == null || pattern == null) { return false; } if (this.pattern.equals(object)) { return true; } String[] currentPatterns = this.patterns; if (currentPatterns != null) { for (String pattern : currentPatterns) { boolean foundMatch; if ("*".equals(pattern) || "**".equals(pattern)) { return true; } String candidate = object.toString(); if (!isCaseSensitive()) { pattern = pattern.toLowerCase(); candidate = candidate.toLowerCase(); } int i = pattern.indexOf('*'); if (i == -1) { foundMatch = pattern.equals(candidate); } else { int i2 = pattern.indexOf('*', i + 1); if (i2 > 1) { foundMatch = candidate.indexOf(pattern.substring(1, i2)) > -1; } else if (i == 0) { foundMatch = candidate.endsWith(pattern.substring(1)); } else { foundMatch = candidate.startsWith(pattern.substring(0, i)); } } if (foundMatch) { return true; } else if (pattern.endsWith("+") && pattern.length() > 1) { logger.warn("wildcard-filter for payload based filtering is deprecated. Use expression" + "-filter or payload-type-filter instead"); return filterByClassName(object, pattern); } } } return false; } @Deprecated private boolean filterByClassName(Object object, String pattern) { String className = pattern.substring(0, pattern.length() - 1); try { Class<?> theClass = ClassUtils.loadClass(className, this.getClass()); if (!(object instanceof String)) { if (theClass.isInstance(object)) { return true; } } else if (theClass.isAssignableFrom(ClassUtils.loadClass(object.toString(), this.getClass()))) { return true; } } catch (ClassNotFoundException e) { } return false; } public String getPattern() { return pattern; } public void setPattern(String pattern) { this.pattern = pattern; this.patterns = StringUtils.splitAndTrim(pattern, ","); } public boolean isCaseSensitive() { return caseSensitive; } public void setCaseSensitive(boolean caseSensitive) { this.caseSensitive = caseSensitive; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null || getClass() != obj.getClass()) return false; final WildcardFilter other = (WildcardFilter) obj; return equal(pattern, other.pattern) && equal(patterns, other.patterns) && caseSensitive == other.caseSensitive; } @Override public int hashCode() { return hash(new Object[] {this.getClass(), pattern, patterns, caseSensitive}); } @Override public void setMuleContext(MuleContext context) { this.muleContext = context; } }