package com.netifera.platform.util.patternmatching; public final class HostnameMatcher implements ITextMatcher { /** * RFC 2181 section 11: * The length of any one label is limited to between 1 and 63 octets. */ private static final int MAX_LABEL_CHARS = 63; /** regex matching a host name. */ static final String HOSTNAME_REGEX = // TODO document (james) ALNUMLATIN1 + "+" + "(?:" + CHARLATIN1 + "*" + ALNUMLATIN1 + ")*"; /** The value is used for string storage. */ private final String value; /** * @param text * the string to be matched */ public HostnameMatcher(final String text) { value = text; } @Override public String toString() { return value; } /** * Test if the input text matches a host name. * * @return <tt>true</tt> if, and only if, this string matches a host name. */ public boolean matches() { if (value == null || value.contains(":")) { // no ipv6 return false; } String ctext = value; if (value.endsWith(".")) { // allow 1 optional trailing dot '.' ctext = value.substring(0, value.length() - 1); } String[] parts = ctext.split("\\."); if (parts == null || parts.length == 0) { return false; } // TLD must contains letter (else is probably an IP address) if (parts[parts.length - 1].matches("\\d+")) { return false; } for (String part : parts) { if (part.length() == 0 // illegal: 2 consecutives dots || part.length() >= MAX_LABEL_CHARS || !part.matches(HOSTNAME_REGEX)) { return false; } } return true; } /** * Test if the input text matches a host name. * * @param text The string to match. * @return <tt>true</tt> if, and only if, this string matches a host name. */ public static boolean matches(final String text) { return new HostnameMatcher(text).matches(); } }