/* * FQAN.java * * Created on October 4, 2007, 2:59 PM * * To change this template, choose Tools | Template Manager * and open the template in the editor. */ package org.dcache.auth; import java.io.Serializable; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * * @author timur */ public class FQAN implements Serializable { private static final long serialVersionUID = -2212735007788920585L; private static final String NULL_CAPABILITY = "/Capability=NULL"; private static final String NULL_ROLE = "/Role=NULL"; /* In general, the regular expressions (REs) are taken from: * * http://edg-wp2.web.cern.ch/edg-wp2/security/voms/edg-voms-credential.pdf * * Changes and clarification from that document: * * 1. The document states that the RE for RFC 1035 is: * * ^([a-z]([a-z0-9-]*[a-z0-9])*\.)*[a-z]{2,4}$ * * However, this is at odds with RFC 1035 section 2.3.1, which describes * a simpler format. Here we use: * * <label>(\.<label>)* * * where <label> is: * * [a-z]([a-z0-9-]*[a-z0-9])? * * 2. In the document, the RE for a valid capability value is written as * * [\w_-] * * where \w is defined as: * * [a-zA-Z0-9_] * * which is in keeping with Java Pattern definition for \w. Note that * [\w_-] is equivalent to [\w-]. */ private static final String RE_VALID_LABEL = "[a-z]([a-z0-9-]*[a-z0-9])?"; private static final String RE_RFC_1035_VALUE = RE_VALID_LABEL + "(\\." + RE_VALID_LABEL + ")*"; private static final String RE_VALID_VO_VALUE = '/' + RE_RFC_1035_VALUE; private static final String RE_VALID_GROUP_VALUE = "(/[\\w-]+)*"; private static final String RE_VALID_ROLE_VALUE = "[\\w-]+"; private static final String RE_VALID_CAPABILITY_VALUE = "[\\w-]+"; private static final String RE_VALID_FQAN = '^' + RE_VALID_VO_VALUE + '(' + RE_VALID_GROUP_VALUE + ")?" + "(/Role=" + RE_VALID_ROLE_VALUE + ")?" + "(/Capability=" + RE_VALID_CAPABILITY_VALUE + ")?$"; private static final Pattern VALID_FQAN = Pattern.compile( RE_VALID_FQAN); private static final Pattern p1 = Pattern.compile("(.*)/Role=(.*)/Capability=(.*)"); private static final Pattern p2 = Pattern.compile("(.*)/Role=(.*)(.*)"); private static final Pattern p3 = Pattern.compile("(.*)()/Capability=(.*)"); private static final Pattern p4 = Pattern.compile("(.*)(.*)(.*)"); private transient Matcher m; //immutable private final String fqan; /** Identify if given String is a valid FQAN */ public static boolean isValid( String fqan) { if( fqan == null) { return false; } Matcher fqanMatcher = VALID_FQAN.matcher( fqan); return fqanMatcher.matches(); } /** Creates a new instance of FQAN */ public FQAN(String fqan) { if(fqan ==null ){ throw new IllegalArgumentException("fqan is null"); } fqan = filterOutNullCapability(fqan); fqan = filterOutNullRole( fqan); this.fqan = fqan; } private static String filterOutNullCapability( String originalFqan) { String filteredFqan; if( originalFqan.endsWith( NULL_CAPABILITY)) { int newLength = originalFqan.length() - NULL_CAPABILITY.length(); filteredFqan = originalFqan.substring( 0, newLength); } else { filteredFqan = originalFqan; } return filteredFqan; } private static String filterOutNullRole( String originalFqan) { int index = originalFqan.indexOf( NULL_ROLE); if( index == -1) { return originalFqan; } String filteredFqan = originalFqan.substring(0, index) + originalFqan.substring(index + NULL_ROLE.length()); return filteredFqan; } @Override public String toString() { return fqan; } private Matcher getMatcher() { if (m!=null) { return m; } m = p1.matcher(fqan); if(!m.matches()) { m = p2.matcher(fqan); if(!m.matches()) { m = p3.matcher(fqan); if(!m.matches()) { m = p4.matcher(fqan); m.matches(); } } } return m; } public String getGroup() { return getMatcher().group(1); } public String getRole() { return getMatcher().group(2); } public boolean hasRole() { String role = getRole(); return !role.isEmpty(); } public String getCapability() { return getMatcher().group(3); } public boolean hasCapability() { String capability = getCapability(); return !capability.isEmpty(); } public FQAN getParent() { int i = fqan.lastIndexOf('/'); return (i > 1) ? new FQAN(fqan.substring(0, i)) : null; } @Override public int hashCode() { return fqan.hashCode(); } @Override public boolean equals(Object testFQAN) { if (testFQAN == this) { return true; } if (!(testFQAN instanceof FQAN)){ return false; } FQAN otherFQAN = (FQAN) testFQAN; return this.fqan.equals(otherFQAN.fqan); } /** * @param args the command line arguments */ public static void main(String[] args) { // TODO code application logic here FQAN fqan = new FQAN(args[0]); System.out.println("FQAN = "+fqan); System.out.println("Group = "+fqan.getGroup()); System.out.println("Role = "+fqan.getRole()); System.out.println("Capacity = "+fqan.getGroup()); } }