package rocks.inspectit.shared.all.pattern; import java.util.ArrayList; import java.util.List; import org.apache.commons.lang.StringUtils; /** * Pattern matcher for simple strings with '*' wildcard characters. The supplied template may take * the form "xxx" for an exact match, "xxx*" for a match on leading characters only, "*xxx" to match * on trailing characters only, or "xxx*yyy" to match on both leading and trailing. It can also * include multiple '*' characters when more than one part of the match is wildcarded. * <p> * <b>IMPORTANT:</b> The class code is copied/taken from * <a href="http://www.ibm.com/developerworks/java/library/j-dyn0203.html">IBM developers Works</a>. * Original author is Dennis Sosnoski. License info can be found * <a href="http://www.ibm.com/developerworks/apps/download/index.jsp * ?contentid=10908&filename=j-dyn0203-source.zip&method=http&locale=">here</a>. * * @author Dennis Sosnoski */ public class WildcardMatchPattern implements IMatchPattern { /** * Text components to be matched. */ private String[] components; /** * Flag for leading text to be matched. */ private boolean isLeadText; /** * Flag for trailing text to be matched. */ private boolean isTrailText; /** * The template string used for matching. */ private String template; /** * Is set to true if the template equals '*'. As this matches everything, we skip the whole * compare process. */ private boolean everything = false; /** * No-arg constructor for serialization. */ public WildcardMatchPattern() { } /** * Constructor. * * @param template * match text template */ public WildcardMatchPattern(final String template) { if (null == template) { throw new IllegalArgumentException("Template for the matching can not be null."); } this.template = template; if ("*".equals(template)) { everything = true; isLeadText = false; isTrailText = false; return; } int mark = template.indexOf('*'); List<String> comps = new ArrayList<String>(); if (mark < 0) { // set up for exact match comps.add(template); isLeadText = true; isTrailText = true; } else { // handle leading wildcard int base = 0; if (mark == 0) { isLeadText = false; base = 1; mark = template.indexOf('*', 1); } else { isLeadText = true; } // loop for all text components to be matched int limit = template.length() - 1; while (mark > 0) { comps.add(template.substring(base, mark)); base = mark + 1; if (mark == limit) { break; } mark = template.indexOf('*', base); } comps.add(template.substring(base)); isTrailText = mark != limit; } // save array of text components to be matched components = comps.toArray(new String[comps.size()]); } /** * {@inheritDoc} */ @Override public final boolean match(String match) { if (everything) { return true; } // first check for required leading text int start = 0; int end = match.length(); int index = 0; if (isLeadText) { if (match.startsWith(components[0])) { start = components[0].length(); index = 1; } else { return false; } } // next check for required trailing text int limit = components.length; if (isTrailText) { limit--; if (match.endsWith(components[limit])) { end -= components[limit].length(); } else { return false; } } // finally match all floating comparison components while (index < limit) { String comp = components[index++]; start = match.indexOf(comp, start); if (start >= 0) { start += comp.length(); if (start > end) { return false; } } else { return false; } } return true; } /** * {@inheritDoc} */ @Override public String getPattern() { return template; } /** * Checks if the supplied {@link String} is a pattern. * * @param txt * The text to check for. * @return Returns if the supplied String is a pattern. */ public static boolean isPattern(String txt) { return StringUtils.isNotBlank(txt) && (txt.indexOf('*') > -1); } /** * {@inheritDoc} */ @Override public int hashCode() { final int prime = 31; int result = 1; result = (prime * result) + ((template == null) ? 0 : template.hashCode()); return result; } /** * {@inheritDoc} */ @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } WildcardMatchPattern other = (WildcardMatchPattern) obj; if (template == null) { if (other.template != null) { return false; } } else if (!template.equals(other.template)) { return false; } return true; } }