package de.malkusch.whoisServerList.publicSuffixList.rule; import javax.annotation.concurrent.Immutable; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; import de.malkusch.whoisServerList.publicSuffixList.util.DomainUtil; /** * The rule matcher. * * The matcher is case insensitive. * * @author [email protected] * @see <a href="bitcoin:1335STSwu9hST4vcMRppEPgENMHD2r1REK">Donations</a> */ @Immutable final class RuleMatcher { /** * Rule labels in reversed order. */ private final String[] reversedLabels; /** * Sets the rule labels. * * The labels are stored as a reversed copy in {@link #reversedLabels}. * * @param labels the rule labels, not null */ RuleMatcher(final String[] labels) { this.reversedLabels = labels.clone(); ArrayUtils.reverse(reversedLabels); } /** * Sets the rule labels. * * The labels are stored as a reversed copy in {@link #reversedLabels}. * * @param pattern the rule pattern, not null */ RuleMatcher(final String pattern) { this(DomainUtil.splitLabels(pattern)); } /** * Returns the matched public suffix. * * Matching is case insensitive. * * @param domain the domain name, may be null * @return the matched public suffix or null */ String match(final String domain) { if (domain == null) { return null; } String[] reversedDomainLabels = DomainUtil.splitLabels(domain); ArrayUtils.reverse(reversedDomainLabels); if (reversedDomainLabels.length < reversedLabels.length) { return null; } String[] reversedMatchedLabels = new String[reversedLabels.length]; for (int i = 0; i < reversedLabels.length; i++) { if (i > reversedDomainLabels.length) { return null; } String matchLabel = reversedLabels[i]; String domainLabel = reversedDomainLabels[i]; LabelMatcher matcher = new LabelMatcher(matchLabel); if (!matcher.isMatch(domainLabel)) { return null; } reversedMatchedLabels[i] = domainLabel; } ArrayUtils.reverse(reversedMatchedLabels); return DomainUtil.joinLabels(reversedMatchedLabels); } /** * Returns the rule pattern. * * @return the rule pattern, not null */ String getPattern() { String[] labels = reversedLabels.clone(); ArrayUtils.reverse(labels); return DomainUtil.joinLabels(labels); } @Override public String toString() { return getPattern(); } @Override public boolean equals(final Object obj) { return EqualsBuilder.reflectionEquals(this, obj); } @Override public int hashCode() { return HashCodeBuilder.reflectionHashCode(this); } }