package lime49.lockcrypt; import java.io.File; import java.net.URL; import java.util.HashMap; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * URL which supports wildcards (*) in it's component parts * @author Harry Jennerway * @see http://leghumped.com/blog/2008/11/03/java-matching-urls-with-regex-wildcards/ * @see http://www.lime49.com/ */ public final class WildcardURL implements java.io.Serializable { private String protocol, user, password, host, directory, file, query, ref; private int port = -1; public WildcardURL(String url) { HashMap tempUri = new HashMap(14); String[] parts = {"source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","ref"}; boolean strictMode = false; Pattern pattern; if(strictMode) { pattern = Pattern.compile("^(?:([^:/?#]+):)?(?://((?:(([^:@]*):?([^:@]*))?@)?([^:/?#]*)(?::(\\d*))?))?((((?:[^?#/]*/)*)([^?#]*))(?:\\?([^#]*))?(?:#(.*))?)"); } else { pattern = Pattern.compile("^(?:(?![^:@]+:[^:@/]*@)([^:/?#.]+):)?(?://)?((?:(([^:@]*):?([^:@]*))?@)?([^:/?#]*)(?::(\\d*))?)(((/(?:[^?#](?![^?#/]*\\.[^?#/.]+(?:[?#]|$)))*/?)?([^?#/]*))(?:\\?([^#]*))?(?:#(.*))?)"); } Matcher matcher = pattern.matcher(url); String match; if(matcher.find()) { for(int i=0;i<14;i++) { try { match = matcher.group(i); } catch(Exception ex) { match = "*"; } tempUri.put(parts[i], match == null ? "*" : match); } } this.protocol = tempUri.get("protocol"); this.user = tempUri.get("user"); this.password = tempUri.get("password"); this.host = tempUri.get("host"); this.directory = tempUri.get("directory"); this.file = tempUri.get("file"); this.query = tempUri.get("query"); this.ref = tempUri.get("ref"); try { this.port = Integer.parseInt(tempUri.get("port")); } catch(NumberFormatException ignore) {} } /** * Gets the userInfo part of this URL. * Eg: user:pass * @return The userInfo part of this URL */ public String getUserInfo() { return user + (password.equals("*") ? "" : ":"+password); } /** * Gets the protocol name of this URL. * Eg: http * @return The protocol of this URL. */ public String getProtocol() { return protocol; } /** * Gets the host name of this URL. * Eg: www.lime49.com * @return The host name of this URL. */ public String getHost() { return host; } /** * Gets the authority part of this URL (the domain). * Eg: www.lime49.com OR user:pwd@domain.com * @return The authority part of this URL */ public String getAuthority() { String userInfo = getUserInfo(); StringBuffer auth = new StringBuffer(); if(!userInfo.equals("*")) { auth.append(userInfo).append("@"); } auth.append('@').append(host).append(':').append(port); return auth.toString(); } /** * Gets the port number of this URL. * @return The port number, or -1 if the port is not set */ public int getPort() { return port; } /** * Gets the directory of this URL. * Eg: /some/directory * @return The directory of this URL */ public String getDirectory() { return directory; } /** * Gets the file name of this URL. * Eg: file.php * @return The file name of this URL */ public String getFile() { return file; } /** * Gets the path part of this URL. * Eg: /some/directory/file.php * @return The path part of this URL, or an empty string if one does not exist */ public String getPath() { return directory+file; } /** * Gets the userInfo part of this URL. * Eg: var1name=val1&var2name=val2 * @return The query part of this URL */ public String getQuery() { return query; } /** * Gets the anchor (also known as the "reference") of this URL (the part after the hash). * Eg: anchor * @return The anchor (also known as the "reference") */ public String getRef() { return ref; } /** * Gets whether or not the specified URL matches this WildcardURL * @param url The URL to check. * @return True if the protocol, domain, directory and path match the specified URL, otherwise false */ public boolean matches(URL url) { boolean matches = false; if(wildcardMatches(protocol, url.getProtocol()) && wildcardMatches(host, url.getHost()) && wildcardMatches(getPath(), url.getPath())) { matches = true; } //System.out.println((wildcardMatches(protocol, url.getProtocol()) ? "t":"f") +"-"+ (wildcardMatches(host, url.getHost()) ? "t":"f") +"-" + (wildcardMatches(getPath(), url.getPath()) ? 't' : 'f')); return matches; } /** * Gets whether a string matches a wildcard pattern. The following would be considered to be matches: * *pattern somepattern * pattern* patternsome * *pattern* somepatternsome * @param pattern The pattern to check, wildcards must be at either the start, end or both, but not in the middle. * @param stringToMatch The string to check * @return True if the wildcard matches the pattern, otherwise false */ private boolean wildcardMatches(String pattern, String stringToMatch) { boolean match = false; int length = pattern.length(); if(pattern.charAt(0) == '*') { if(length == 1) { match = true; // * } else if(pattern.charAt(length-1) == '*' && length > 2 && stringToMatch.contains(pattern.substring(1, length-3).toLowerCase())) { match = true; // *match* } else if(length > 1 && stringToMatch.endsWith(pattern.substring(1).toLowerCase())) { match = true; // *match } } else if(pattern.charAt(length-1) == '*' && stringToMatch.startsWith(pattern.substring(0, length-2).toLowerCase())) { match = true; // match* } else if(pattern.equalsIgnoreCase(stringToMatch)) { // match match = true; } return match; } public String toString() { return protocol+"://"+ getUserInfo()+ //user+(password.equals("*") ? "" : ":"+password)+(!user.equals("*") && !password.equals("*") ? "@":"")+ host+ (port == -1?"":":"+port)+ getPath()+ query+ (ref.equals("*")?"":"#"+ref); } }