View Javadoc

1   /*
2    * FQAN.java
3    *
4    * Created on September 10, 2004, 12:14 PM
5    */
6   
7   package gov.bnl.gums;
8   
9   import java.util.StringTokenizer;
10  import java.util.regex.Matcher;
11  import java.util.regex.Pattern;
12  
13  /** 
14   * Represent a VOMS extended proxy credential as defined in
15   * http://edg-wp2.web.cern.ch/edg-wp2/security/voms/edg-voms-credential.pdf.
16   * <p>
17   * A Fully Qualified Attribute Name consists of a VO, a group, a role and
18   * a capability. Only the VO is mandatory. The syntax is
19   * /VO[/group[/subgroup(s)]][/Role=role][/Capability=cap].
20   * <p>
21   * The class will always check that every modification matches the regex
22   * /[\w-\.]+(/[\w-\.]+)*(/Role=[\w-\.]+)?(/Capability=[\w-\.]+)?
23   * which fully defines all the characters allowed. This differs slightly from
24   * the one contained in the specification, as it cointained some small errors.
25   * It matches the description of the syntax of the document.
26   *
27   * @author  Gabriele Carcassi, Jay Packard
28   */
29  public class FQAN {
30  	static private Pattern fqanPattern = Pattern.compile("/[\\w-\\.]+(/[\\w-\\.]+)*(/Role=[\\w-\\.]+)?(/Capability=[\\w-\\.]+)?");
31      private String fqan;
32      private String vo;
33      private String group;
34      private String role;
35      private String capability;
36      
37      /**
38       * Creates a FQAN based on String representation. If the parsing fails, it will
39       * throw an exception.
40       * @param fqan A VOMS FQAN (i.e. "/atlas/production/Role=Leader")
41       */
42      public FQAN(String fqan) {
43          setFqan(fqan);
44          parseFqan(fqan);
45          generateFqan();
46      }
47      
48      /** Creates a FQAN based on the different pieces of information.
49       * 
50       * @param vo The VO name, which cannot be null (i.e. "atlas")
51       * @param group A group path, including subgroups (i.e. "/production")
52       * @param role The role (i.e. "Leader")
53       * @param capability A capability (i.e. "capability"). Note capabilities are
54       * being deprecated in VOMS.
55       */
56      public FQAN(String vo, String group, String role, String capability) {
57          if (vo == null)
58              throw new IllegalArgumentException("The vo for a FQAN can't be null");
59          setVo(vo);
60          setGroup(group);
61          setRole(role);
62          setCapability(capability);
63          generateFqan();
64      }
65      
66      /** FQANs are equals to each other if their vo, group, role and capability
67       * are the same.
68       * 
69       * @param obj Another object.
70       * @return True if the object was a FQAN with equal information. False otherwise.
71       */
72      public boolean equals(Object obj) {
73          if (obj == null) return false;
74          FQAN fqan2 = (FQAN) obj;
75          return (fqan2.fqan == null) ? fqan == null : fqan2.fqan.equalsIgnoreCase(fqan);
76      }
77  
78      /**
79       *  The capability used within the FQAN.
80       *  
81       * @return The capability or null if none was specified.
82       */
83      public String getCapability() {
84          return this.capability;
85      }
86  
87      /** A full String representation of the FQAN.
88       * 
89       * @return The Fully Qualified Attribute name String representation (i.e. "/atlas/production/Role=Leader")
90       */
91      public String getFqan() {
92          return this.fqan;
93      }
94      
95      /** The path which includes the groups and subgroups within the FQAN.
96       * 
97       * @return The group path (i.e. "/production")
98       */
99      public String getGroup() {
100         return this.group;
101     }
102     
103     /** The role used within the FQAN.
104      * 
105      * @return The role or null if no role was specified
106      */
107     public String getRole() {
108         return this.role;
109     }
110     
111     /** Returns the VO corresponding to the FQAN.
112      * 
113      * @return The VO name (i.e. "atlas")
114      */
115     public String getVo() {
116         return this.vo;
117     }
118     
119     /** A hashcode generated from the string representation.
120      * 
121      * @return A hashcode.
122      */
123     public int hashCode() {
124         if (fqan == null) return 0;
125         return fqan.hashCode();
126     }
127     
128     /** Returns the full string representation of the FQAN.
129      * 
130      * @return The full FQAN (i.e. "/atlas/production/Role=Leader")
131      */
132     public String toString() {
133         return fqan;
134     }
135     
136     private void generateFqan() {
137         if (vo == null) {
138             fqan = null;
139             return;
140         }
141         StringBuffer bf = new StringBuffer();
142         bf.append('/');
143         bf.append(vo);
144         if (group != null)
145             bf.append(group);
146         if (role != null) {
147             bf.append("/Role=");
148             bf.append(role);
149         }
150         if (capability != null) {
151             bf.append("/Capability=");
152             bf.append(capability);
153         }
154         fqan = bf.toString();
155     }
156     
157     private void parseFqan(String fqan) {
158         // Matches to the specification.
159         Matcher m = fqanPattern.matcher(fqan);
160         if (!m.matches())
161             throw new IllegalArgumentException("FQAN '" + fqan + "' is malformed (syntax: /VO[/group[/subgroup(s)]][/Role=role][/Capability=cap])");
162         
163         StringTokenizer stk = new StringTokenizer(fqan, "/");
164         vo = stk.nextToken();
165         if (!stk.hasMoreTokens()) {
166             group = null;
167             role = null;
168             capability = null;
169             return;
170         }
171         String tempGroup = "";
172         String token = stk.nextToken();
173         while ((!token.startsWith("Role=") && !token.startsWith("Capability="))) {
174             tempGroup = tempGroup + "/" + token;
175             group = tempGroup;
176             if (!stk.hasMoreTokens()) {
177                 role = null;
178                 capability = null;
179                 return;
180             }
181             token =  stk.nextToken();
182         }
183         if (token.startsWith("Role=")) {
184             setRole(token.substring(5));
185             if (!stk.hasMoreTokens()) {
186                 capability = null;
187                 return;
188             }
189             token = stk.nextToken();
190         }
191         if (token.startsWith("Capability=")) {
192             setCapability(token.substring(11));
193         }
194     }
195     
196     private void setCapability(String capability) {
197         if ((capability != null) && (!capability.matches("[\\w-\\.]+"))) {
198             throw new IllegalArgumentException("The capability '" + capability + "' is malformed");
199         }
200         this.capability = capability;
201         if ("NULL".equalsIgnoreCase(capability)) {
202             this.capability = null;
203         }
204     }
205     
206     private void setFqan(String fqan) {
207         this.fqan = fqan;
208     }
209     
210     private void setGroup(String group) {
211         if ((group != null) && (!group.matches("(/[\\w-\\.]+)+"))) {
212             throw new IllegalArgumentException("The group '" + group + "' is malformed");
213         }
214         this.group = group;
215     }
216     
217     private void setRole(String role) {
218         if ((role != null) && (!role.matches("[\\w-\\.]+"))) {
219             throw new IllegalArgumentException("The role '" + role + "' is malformed");
220         }
221         this.role = role;
222         if ("NULL".equalsIgnoreCase(role)) {
223             this.role = null;
224         }
225     }
226     
227     private void setVo(String vo) {
228         if ((vo != null) && (!vo.matches("[\\w-\\.]+"))) {
229             throw new IllegalArgumentException("The vo '" + vo + "' is malformed");
230         }
231         this.vo = vo;
232     }
233     
234 }