Clover Coverage Report
Coverage timestamp: Sun Mar 23 2008 08:24:39 GMT
636   2,653   167   6.17
284   1,133   0.42   5.72
103     2.61  
18    
 
 
  XMLPolicyParser       Line # 88 116 25 76.7% 0.76666665
  XMLPolicyParser.ActionPolicyNode       Line # 730 31 8 96% 0.96
  XMLPolicyParser.DomainPolicyNode       Line # 870 11 2 100% 1.0
  XMLPolicyParser.SubjectDomainPolicyNode       Line # 952 2 1 100% 1.0
  XMLPolicyParser.TargetDomainPolicyNode       Line # 965 2 1 100% 1.0
  XMLPolicyParser.DomainSpecNode       Line # 980 59 20 82% 0.82
  XMLPolicyParser.SubjectDomainSpecNode       Line # 1167 1 1 100% 1.0
  XMLPolicyParser.TargetDomainSpecNode       Line # 1177 1 1 100% 1.0
  XMLPolicyParser.RoleAssignmentPolicyNode       Line # 1191 85 22 86.3% 0.86290324
  XMLPolicyParser.RoleHierarchyNode       Line # 1449 44 18 82.7% 0.8271605
  XMLPolicyParser.RoleHierarchyPolicyNode       Line # 1659 21 4 85.7% 0.85714287
  XMLPolicyParser.RoleListNode       Line # 1794 28 8 82% 0.82
  XMLPolicyParser.RoleSpecNode       Line # 1925 17 4 90% 0.9
  XMLPolicyParser.SOAPolicyNode       Line # 2027 25 10 75.6% 0.75609756
  XMLPolicyParser.TargetAccessPolicyNode       Line # 2115 105 34 79.6% 0.7962963
  XMLPolicyParser.PMIXMLPolicyNode       Line # 2441 3 1 100% 1.0
  XMLPolicyParser.RepositoryPolicyNode       Line # 2457 9 3 87.5% 0.875
  XMLPolicyParser.MSoDPolicySetNode       Line # 2499 76 21 81.7% 0.8173913
 
  (1)
 
1    /*
2    * Copyright (c) 2000-2005, University of Salford
3    * All rights reserved.
4    *
5    * Redistribution and use in source and binary forms, with or without
6    * modification, are permitted provided that the following conditions are met:
7    *
8    * Redistributions of source code must retain the above copyright notice, this
9    * list of conditions and the following disclaimer.
10    *
11    * Redistributions in binary form must reproduce the above copyright notice,
12    * this list of conditions and the following disclaimer in the documentation
13    * and/or other materials provided with the distribution.
14    *
15    * Neither the name of the University of Salford nor the names of its
16    * contributors may be used to endorse or promote products derived from this
17    * software without specific prior written permission.
18    *
19    * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20    * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21    * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22    * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23    * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24    * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25    * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26    * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27    * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28    * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29    * POSSIBILITY OF SUCH DAMAGE.
30    */
31   
32    package issrg.pba.rbac.xmlpolicy;
33   
34    import issrg.pba.rbac.policies.*; // added for MSoD
35    import issrg.pba.rbac.*;
36    import issrg.pba.Obligations;
37    import issrg.pba.SimpleObligations;
38   
39    import org.xml.sax.Attributes;
40    import javax.xml.parsers.SAXParserFactory;
41   
42    import issrg.pba.rbac.policies.DITSubtree;
43    import issrg.pba.rbac.policies.Subtree;
44   
45    import issrg.pba.rbac.PolicyParsingException;
46    import issrg.pba.rbac.LDAPDNPrincipal;
47    import issrg.pba.rbac.BadURLException;
48    import issrg.pba.rbac.URLHandler;
49   
50   
51    import java.security.Principal;
52   
53    import java.util.ArrayList;
54    import java.util.Vector;
55    import java.util.Map;
56    import java.util.Enumeration; //added for MSoD
57   
58    /**
59    * This class parses the given XML into an internal representation.
60    * It creates rules for the DelegationPolicy and AccessPolicy objects.
61    *
62    * <p>The parser was written in 2000 when XML DOM3 parsers were not readily
63    * available with JDK, so we went for a (lightweight) SAX API. Effectively,
64    * this parser converts XML into a tree of PolicyXMLNode objects or its
65    * subclasses, very much like modern DOM3 parsers convert XML into a tree of
66    * Nodes.
67    *
68    * <p>To extend the set of XML elements understood by XML Parser, you need to
69    * extend the PolicyXMLNode class and provide a special constructor that
70    * contains two arguments: XMLPolicyParser and org.xml.sax.Attributes. Note
71    * that the inner classes will have an additional implied argument that is of
72    * the type
73    * of the containing class (for example, this is why the extensions of the
74    * PolicyXMLNode internal to this class do not have
75    * XMLPolicyParser as one of their parameters to the constructor - it is there
76    * implicitly).
77    *
78    * <p>This is a Role based implementation, so it constructs the RoleHierarchy
79    * along with Role based rules for the Delegation and Access policy objects.
80    *
81    * <p>Note that if the XML complies to a different syntax, the results are
82    * unpredictable.
83    *
84    * @author A Otenko
85    * @version 1.0
86    */
87   
 
88    public class XMLPolicyParser implements issrg.pba.PolicyParser,
89    org.xml.sax.ContentHandler,
90    org.xml.sax.ErrorHandler {
91   
92    /**
93    * This method registers a set of default XML Nodes understood by XML
94    * Parser. The general XML syntax does not need to be extensible, but
95    * the IF-statement is extensible through this mechanism. You do not have
96    * to call this method, if you have registered other classes to handle
97    * the nodes that appear in the IF-statement; otherwise, you need to
98    * call this method to use the default implementation.
99    *
100    * @see #registerXMLNode
101    */
 
102  21 toggle public static void registerDefaultNodes(){
103  21 issrg.pba.rbac.xmlpolicy.ifstatement.ArgNode.register();
104  21 issrg.pba.rbac.xmlpolicy.ifstatement.ConstantNode.register();
105  21 issrg.pba.rbac.xmlpolicy.ifstatement.EnvironmentNode.register();
106   
107  21 issrg.pba.rbac.xmlpolicy.ifstatement.OperatorNode.register();
108   
109  21 issrg.pba.rbac.xmlpolicy.ifstatement.PresentNode.register(); // this one registers a default interpreter as well
110  21 issrg.pba.rbac.xmlpolicy.ifstatement.NotNode.register(); // this one registers a default interpreter as well
111   
112  21 issrg.pba.rbac.xmlpolicy.ifstatement.AndNode.register(); // this one registers a default interpreter as well
113  21 issrg.pba.rbac.xmlpolicy.ifstatement.OrNode.register(); // this one registers a default interpreter as well
114   
115  21 issrg.pba.rbac.xmlpolicy.ifstatement.EqNode.register(); // this node also has a default interpreter
116  21 issrg.pba.rbac.xmlpolicy.ifstatement.GeNode.register();
117  21 issrg.pba.rbac.xmlpolicy.ifstatement.LeNode.register();
118  21 issrg.pba.rbac.xmlpolicy.ifstatement.GtNode.register();
119  21 issrg.pba.rbac.xmlpolicy.ifstatement.LtNode.register();
120  21 issrg.pba.rbac.xmlpolicy.ifstatement.SubstringsNode.register();
121   
122  21 issrg.pba.rbac.xmlpolicy.ifstatement.IntegerInterpreter.register();
123  21 issrg.pba.rbac.xmlpolicy.ifstatement.StringInterpreter.register();
124   
125  21 issrg.pba.rbac.Time.register();
126  21 issrg.pba.rbac.TimeInterpreter.register();
127    }
128   
129    /**
130    * This is a utility method that parses the policy provided as a String.
131    *
132    * @param policy - the XML text of the PERMIS XML Policy
133    *
134    * @return XMLPolicyParser that has successfully parsed the policy; use its
135    * methods to retrieve the subpolicies and other rules
136    * @throws PbaException, if there was a problem parsing the policy
137    */
 
138  0 toggle public static XMLPolicyParser getXMLPolicyParser(String policy) throws issrg.pba.PbaException{
139  0 return new XMLPolicyParser(policy);
140    }
141   
142   
143    /**
144    * This is a utility method that parses the policy provided as a
145    * InputStream.
146    *
147    * @param is - the InputStream with the XML text of the PERMIS XML Policy
148    *
149    * @return XMLPolicyParser that has successfully parsed the policy; use its
150    * methods to retrieve the subpolicies and other rules
151    */
 
152  1 toggle public static XMLPolicyParser getXMLPolicyParser(java.io.InputStream is) throws issrg.pba.PbaException{
153  1 return new XMLPolicyParser(new org.xml.sax.InputSource(is));
154    }
155   
156    /**
157    * This is a collection of all known nodes. It is useful for quick lookup of
158    * the needed node to create for a given node name.
159    */
160    protected final static java.util.Map knownNodes = new java.util.Hashtable();
161    private static Class [] defaultConstr = new Class[]{XMLPolicyParser.class, org.xml.sax.Attributes.class};
 
162  21 toggle static{
163  21 try{
164  21 registerXMLNode(XMLTags.ROLE_HIERARCHY_POLICY_NODE, RoleHierarchyPolicyNode.class);
165  21 registerXMLNode(XMLTags.ROLE_SPEC_NODE, RoleSpecNode.class);
166  21 registerXMLNode(XMLTags.SUP_ROLE_NODE, RoleHierarchyNode.class);
167  21 registerXMLNode(XMLTags.SUBJECT_POLICY_NODE, SubjectDomainPolicyNode.class);
168  21 registerXMLNode(XMLTags.SUBJECT_DOMAIN_SPEC_NODE, SubjectDomainSpecNode.class);
169  21 registerXMLNode(XMLTags.SOA_POLICY_NODE, SOAPolicyNode.class);
170  21 registerXMLNode(XMLTags.REPOSITORY_POLICY_NODE, RepositoryPolicyNode.class);
171  21 registerXMLNode(XMLTags.TARGET_ACCESS_POLICY_NODE, TargetAccessPolicyNode.class);
172  21 registerXMLNode(XMLTags.TARGET_POLICY_NODE, TargetDomainPolicyNode.class);
173  21 registerXMLNode(XMLTags.TARGET_DOMAIN_SPEC_NODE, TargetDomainSpecNode.class);
174  21 registerXMLNode(XMLTags.ACTION_POLICY_NODE, ActionPolicyNode.class);
175  21 registerXMLNode(XMLTags.ROLE_ASSIGNMENT_POLICY_NODE, RoleAssignmentPolicyNode.class);
176  21 registerXMLNode(XMLTags.ROLE_LIST_NODE, RoleListNode.class);
177  21 registerXMLNode(XMLTags.X_509_PMI_RBAC_POLICY_NODE, PMIXMLPolicyNode.class);
178    // registerXMLNode(XMLTags.ROLE_MAPPING_POLICY_NODE, RoleMappingPolicyNode.class);
179  21 registerXMLNode(XMLTags.MSoD_POLICY_SET_NODE, MSoDPolicySetNode.class); // added for MSoD
180   
181    }catch (NoSuchMethodException nsme){
182  0 nsme.printStackTrace(); // this shouldn't happen
183    }
184    }
185   
186    /**
187    * For debugging purposes. It prints out the names of all known nodes to
188    * System.out.
189    */
 
190  0 toggle public static void printNodes(){
191  0 System.out.println("The nodes registered with the XML Policy parser:");
192  0 Object [] keys = knownNodes.keySet().toArray();
193   
194  0 for (int i=0; i<keys.length; i++){
195  0 System.out.println(keys[i]);
196    }
197  0 System.out.println();
198    }
199   
200    /**
201    * This method can register any PolicyXMLNode constructor with parameters
202    * XMLPolicyParser and org.xml.sax.Attributes
203    * to it.
204    *
205    * @param nodeName is the name of the XML element the provided class can
206    * parse
207    * @param nodeClass is the class of the parser; it must have a constructor
208    * with the first parameter
209    * being XMLPolicyParser and the other being org.xml.sax.Attributes,
210    * where XMLPolicyParser will be the reference to the XMLPolicyParser
211    * that performs parsing, and the Attributes is the set of attributes of
212    * the element being parsed
213    */
 
214  609 toggle public static void registerXMLNode(String nodeName, Class nodeClass) throws NoSuchMethodException {
215  609 knownNodes.put(nodeName, nodeClass.getConstructor(defaultConstr));
216    }
217   
218    /**
219    * This is the whole Policy as a parsed tree of XML nodes.
220    */
221    protected PMIXMLPolicyNode pmiXMLPolicy;
222   
223    /**
224    * The node stack represents the current state of the parsing tree. The
225    * nodes
226    * are inserted at the beginning, its parent is the object number 1, etc.
227    */
228    protected java.util.Vector nodeStack;
229   
230    /**
231    * This is a reference to a &lt;RoleHierarchyPolicy&gt; XML node. However,
232    * it is functional on its own.
233    */
234    protected RoleHierarchyPolicyNode roleHierarchyPolicy; // this is just a bunch of Roles we know
235    // they are linked into a hierarchy when parsing
236   
237    /**
238    * This variable is used by the RoleList node to assign the correct
239    * validity period to the
240    * roles in the role list. This value is changed by the
241    * RoleAssignmentPolicy and by the
242    * TargetAccessPolicy.
243    */
244    protected issrg.pba.rbac.ValidityPeriod validityForRoleList;
245   
246    /**
247    * This is used when parsing the RoleSpec entity. It holds the collection of
248    * roles, defined within one RoleSpec. Note that embedded RoleSpecs are not
249    * allowed: there can be only one open RoleSpec at a time.
250    */
251    private java.util.Map rolespec;
252   
253    /**
254    * This is used when parsing the SubjectPolicy entry. It holds the
255    * SubjectPolicy
256    * object until the Assignment Policy has been created.
257    */
258    private DomainPolicyNode subjectPolicy;
259   
260    /**
261    * This is used when parsing the SOAPolicy entry. It holds a collection of all
262    * known SOAs and their DNs. Note that it is used in AssignmentPolicy only.
263    */
264    private SOAPolicyNode soaPolicy;
265   
266    /**
267    * This is used when parsing the Target policy
268    */
269    private DomainPolicyNode targetPolicy;
270   
271    /**
272    * This is used when parsing the Action policy, and later will be referred
273    * by
274    * the Target Access policy.
275    */
276    private ActionPolicyNode actionPolicy;
277   
278    /**
279    * This is used when parsing the Target Access policy
280    */
281    private TargetAccessPolicyNode targetAccessPolicy;
282   
283    /**
284    * This is where MSoDPolicy goes, added for MSoD
285    */
286    private MSoDPolicySetNode msodPolicySetNode;
287   
288    /**
289    * This is where Repository Policy goes
290    */
291    private RepositoryPolicyNode repositoryPolicy;
292   
293    /**
294    * This is a parsing-specific variable. It is used to locate the error
295    * point.
296    */
297    protected org.xml.sax.Locator locator; // this is for parsing
298   
299    /**
300    * This is the reference to the object, containing the rules for role
301    * assignment
302    */
303    protected RoleAssignmentPolicyNode delegationPolicy;
304   
305    /**
306    * This is used when creating new nodes
307    */
308    protected org.xml.sax.Attributes attrs;
309   
310   
 
311  0 toggle protected XMLPolicyParser(){}
312   
313    /**
314    * This constructor can build a policy out of an InputSource, containing an
315    * XML Policy.
316    *
317    * @param xmlSource is the source, containing the XML Policy to parse
318    */
 
319  1 toggle public XMLPolicyParser(org.xml.sax.InputSource xmlSource) throws issrg.pba.PbaException{
320  1 _init_(xmlSource);
321    }
322   
323    /**
324    * This constructor can build a policy out of the string representation of
325    * the XML.
326    *
327    * @param xml is the XML text of the policy
328    */
 
329  24 toggle public XMLPolicyParser(String xml) throws issrg.pba.PbaException {
330  24 org.xml.sax.InputSource xmlSource = new org.xml.sax.InputSource(new java.io.StringReader(xml));
331  24 _init_(xmlSource);
332    }
333   
334    /**
335    * This is the method that does the actual initialisation of the object. It
336    * accepts parameters in the same meaning as the constructor with the same
337    * parameter.
338    *
339    * @param xmlSource is the source, containing the XML Policy to parse
340    */
 
341  25 toggle private void _init_(org.xml.sax.InputSource xmlSource) throws issrg.pba.PbaException {
342  25 SAXParserFactory sf = SAXParserFactory.newInstance(); //new SAXParserFactoryImpl();//newInstance();
343    // perhaps, I'll remove this?..
344  25 sf.setValidating(false);
345  25 sf.setNamespaceAware(false);
346   
347  25 try{
348  25 org.xml.sax.XMLReader parser = sf.newSAXParser().getXMLReader();
349    /*parser.setEntityResolver(new org.xml.sax.EntityResolver(){
350    * //private final org.xml.sax.InputSource is = new org.xml.sax.InputSource(new java.io.FileReader("policy.dtd"));
351    * public org.xml.sax.InputSource resolveEntity(String id0, String id1){
352    * try{
353    * return new org.xml.sax.InputSource(new java.io.FileReader(id0==null?id1:id0)); // always return an empty Input Source
354    * }catch(java.io.FileNotFoundException fnfe){
355    * return null;
356    * }
357    * }
358    * });
359    */
360    //parser.setErrorHandler(this);
361  25 parser.setContentHandler(this);
362  25 parser.parse(xmlSource);
363    //sf.newSAXParser().parse(xmlSource, new org.xml.sax.helpers.DefaultHandler());
364    }catch (org.xml.sax.SAXParseException se){
365  0 if (se.getException()!=null){
366    //String cause=se.getCause().getMessage();
367  0 throw new issrg.pba.PbaException("Could not initialise; parse error @ line "+se.getLineNumber(), se.getException());
368   
369    }else{
370    //String cause=se.getMessage();
371  0 throw new issrg.pba.PbaException("Could not initialise; parse error @ line "+se.getLineNumber(), se);
372    //String cause=se.getCause().getMessage();
373    }
374    }catch (org.xml.sax.SAXException sae){
375  0 throw new issrg.pba.PbaException("Policy parse failed: "+sae.getMessage(), sae);
376    }catch (javax.xml.parsers.ParserConfigurationException pce){
377  0 throw new issrg.pba.PbaException("Policy parse failed: "+pce.getMessage(), pce);
378    }catch (java.io.IOException io){
379  0 throw new issrg.pba.PbaException("IO failure: "+io.getMessage(), io);
380    }
381    }
382   
383    /**
384    * VOID
385    */
 
386  0 toggle public void skippedEntity(String what){
387    }
388   
389    /**
390    * VOID
391    */
 
392  0 toggle public void processingInstruction(String target, String data){
393    }
394   
395    /**
396    * VOID
397    */
 
398  0 toggle public void ignorableWhitespace(char [] arr, int start, int len){
399    }
400   
401    /**
402    * This is a callback function that is invoked by the SAX parsing process.
403    * It will be
404    * invoked when the parse encounter string text in the xml file.
405    *
406    * <p>For the details of the parameters please refer to the XML SAX API
407    * documentation.
408    *
409    * @Gansen: I changed this implementation to allow the system to get the strings of obligations.
410    * before I do this, the system only get the attributes of obligation.
411    *
412    * @Sassa: Why don't you create a String out of a char array and trim it,
413    * if you want to get rid of whitespace?
414    */
415   
 
416  10141 toggle public void characters(char [] arr, int start, int len){
417  10141 if (len>0 && nodeStack.size()>0) // that's your test if it is inside a node - should always be true, because this method is called so; just a sanity check
418  7094 ((PolicyXMLNode)nodeStack.get(0)).addString(new String(arr, start, len).trim());
419    }
420   
421    /**
422    * This is the start of the recursion body of the parser; it is called any
423    * time
424    * the opening tag of an element is encountered: <b>You should not invoke
425    * it manually</b>. It creates a proper
426    * PolicyXMLNode implementation object and maintains a stack of nodes for
427    * the
428    * current branch.
429    *
430    * @see PolicyXMLNode
431    */
 
432  2668 toggle public void startElement(String URI, String localName, String qName, org.xml.sax.Attributes attrs) throws org.xml.sax.SAXParseException{
433    // System.out.println("getting in: <"+localName+"("+qName+")"+"> @ "+locator.getLineNumber()+"..." ); //****
434    //System.out.println("Attrs:" + attrs.getIndex(qName)+":" + attrs.getLocalName(0) + ":" + attrs.getQName(0) + ":" + attrs.getType(0) + ":" + attrs.getValue(0));
435    // int num = attrs.getLength();
436    // System.out.println(num);
437    // for (int i = 0; i < num; i++) {
438    // System.out.println("LocalName: " + attrs.getLocalName(i) + "Qname: " + attrs.getQName(i) + "Type: " + attrs.getType(i) + "URI: " + attrs.getURI(i) + "Value: " + attrs.getValue(i));
439    // }
440   
441    //localName = localName.intern();
442  2668 if (localName.intern()==""){
443  0 localName=qName;//.intern();
444    }
445    // from now on it is safe (and quick) to just compare localName to one of the *_NODE variables
446    //System.out.print(localName+"..."); //****
447   
448  2668 this.attrs=attrs;
449   
450  2668 PolicyXMLNode node=null;
451  2668 try{
452  2668 java.lang.reflect.Constructor co = (java.lang.reflect.Constructor)knownNodes.get(localName);
453  2668 if (co!=null){ // if there is such node defined; otherwise it must be some node that does not have a corresponding class, so the PolicyXMLNode class should be used instead
454  926 node=(PolicyXMLNode)(co.newInstance(new Object[]{this, this.attrs}));
455    }
456    }catch(Exception iae){
457  0 throw new org.xml.sax.SAXParseException(iae.getMessage(), locator, iae);
458    //iae.printStackTrace(); //****
459    //node=null;
460    }/*catch(InstantiationException ie){
461    //ie.printStackTrace(); //****
462    //node=null;
463    }catch(java.lang.reflect.InvocationTargetException ite){
464    //ite.printStackTrace(); //****
465    }*/
466   
467  2668 if (node==null){
468  1742 node = new PolicyXMLNode(localName, attrs);
469    }
470  2668 nodeStack.insertElementAt(node, 0);
471   
472    //System.out.println("instantiated "+node.getClass().getName()+" ok"); //*****
473    }
474   
475    /**
476    * This is the end of the recursion body; it is called each time the element
477    * closing tag is encountered: <b>You should not invoke
478    * it manually</b>. This method simply maintains the node stack and
479    * constructs
480    * the XML node tree, and invokes the <code>{@link PolicyXMLNode#construct()
481    * construct}</code> method of the closing element.
482    */
 
483  2668 toggle public void endElement(String URI, String localName, String qName) throws org.xml.sax.SAXException {
484    //System.out.print("getting out: </"+localName+"("+qName+")"+"> @ "+locator.getLineNumber()+"..."); //****
485   
486  2668 try{
487  2668 PolicyXMLNode node = (PolicyXMLNode)nodeStack.remove(0);
488   
489  2668 if (nodeStack.size()==0){ // we are there at last! :-)
490  25 pmiXMLPolicy=(PMIXMLPolicyNode)node;
491    }else{
492  2643 ((PolicyXMLNode)nodeStack.get(0)).addChild(node);
493    }
494   
495    // now let the node know it finished and is ready to prepare its data now
496    //System.out.print("entering the construct..."); //*******
497  2668 node.construct();
498    //System.out.println("ok"); //*******
499    }catch (Exception e){
500  0 throw new org.xml.sax.SAXParseException(e.getMessage(), locator, e);
501    }catch (Throwable th){
502  0 throw new org.xml.sax.SAXParseException(th.getMessage(), locator);
503    }
504    }
505   
 
506  25 toggle public void startDocument(){
507  25 pmiXMLPolicy = null;
508  25 roleHierarchyPolicy = null;
509  25 nodeStack = new java.util.Vector();
510    }
511   
512    /**
513    * VOID
514    */
 
515  25 toggle public void endDocument(){
516    }
517   
518    /**
519    * This method sets a source locator, which is used when sending error
520    * messages: <b>You should not invoke this method manually</b>.
521    */
 
522  25 toggle public void setDocumentLocator(org.xml.sax.Locator l){
523  25 this.locator=l;
524    }
525   
526    /**
527    * VOID
528    */
 
529  0 toggle public void startPrefixMapping(String prefix, String URI){
530    }
531   
532    /**
533    * VOID
534    */
 
535  0 toggle public void endPrefixMapping(String prefix){
536    }
537   
538   
539    /*
540    * PARSER FUNCTIONS ENDED.
541    */
542   
543    /*
544    * ERROR HANDLER FUNCTIONS
545    */
 
546  0 toggle public void warning(org.xml.sax.SAXParseException spe){
547    }
548   
 
549  0 toggle public void fatalError(org.xml.sax.SAXParseException spe){
550    }
551   
 
552  0 toggle public void error(org.xml.sax.SAXParseException spe){
553    }
554   
555    /**
556    * Does the same as expect with boolean parameter optional=false.
557    *
558    * @see expect(java.util.Vector, int, String, boolean)
559    */
560   
 
561  770 toggle private static PolicyXMLNode expect(java.util.Vector where, int pos, String what) throws PolicyParsingException{
562  770 return expect(where, pos, what, false);
563    }
564   
565    /**
566    * This is a tiny service function that just checks if the given vector of
567    * child
568    * nodes contains the needed node at the given position. If not, an
569    * exception
570    * is thrown. It may be marked optional, in which case null is returned if
571    * the
572    * node at that position is not what is expected.
573    *
574    * @param where is the vector of child nodes
575    * @param pos is the position in the vector where the sought node is
576    * expected to be
577    * @param what is the string name of the node
578    * @param optional says whether the sought node is optional or not; if true,
579    * no
580    * exception is thrown if the node is not what was expected, or the
581    * vector
582    * is too short
583    *
584    * @return the reference to the node
585    *
586    * @throws PolicyParsingException if the vector is too short or the node in
587    * that
588    * position is not the expected one
589    */
590   
 
591  1439 toggle private static PolicyXMLNode expect(java.util.Vector where, int pos, String what, boolean optional) throws PolicyParsingException{
592  1439 try{
593  1439 if (where.size()<=pos){
594  0 if (!optional) throw new PolicyParsingException("Cannot access an expected child node: "+what);
595  416 return null; // if optional, then just return null
596    }
597  1023 PolicyXMLNode c2 = (PolicyXMLNode)where.get(pos);
598  1023 if (c2.getName().intern()!=what.intern()){
599  0 if (!optional) throw new PolicyParsingException(what+" node has been exected, but "+c2.getName()+" was found");
600  11 c2=null;
601    }
602   
603  1023 return c2;
604    }catch (PolicyParsingException ppe){
605  0 throw ppe; // don't embed the PPE.
606    }catch (Throwable th){
607    // could be a class cast exception, for example
608  0 throw new PolicyParsingException("Parse error", th);
609    }
610    }
611   
612   
613    /*
614    * POLICY FUNCTIONS
615    */
616   
617    /**
618    * Returns the role with the given value from the RoleHierarchy.
619    *
620    * @param roleType - the type of the role, as defined in the
621    * RoleHierarchyPolicy; if there is no RoleSpec with this type, null is
622    * returned
623    * @param roleValue - the value of the role of the given type, as defined
624    * in the RoleSpec defining the role hierarchy of the given type
625    *
626    * @return RoleHierarchyNode representing the role, or null, if there is
627    * no such type defined in the policy, or no such value for the given
628    * type
629    */
 
630  89 toggle public RoleHierarchyNode getRole(String roleType, String roleValue){
631  89 RoleSpecNode rsn = roleHierarchyPolicy.getByType(roleType);
632  89 return rsn==null?null:rsn.getRole(roleValue);
633    }
634   
635   
636    /**
637    * This method returns a Map of Target Access Rules, indexed by action name.
638    * There are other entries as well, as explained in TargetAccessPolicyNode
639    * documentation.
640    *
641    * @return Map of Target Access Rules
642    */
 
643  24 toggle public java.util.Map getAccessRules(){
644    //System.out.println("target access policy: "+targetAccessPolicy);//****
645  24 return targetAccessPolicy.getRules();
646    }
647   
648    /**
649    * This method returns the set of delegation and assignment rules, as
650    * specified by RoleHierarchyPolicy.
651    *
652    * @see AssignmentRule
653    */
 
654  25 toggle public java.util.Map getAssignmentRules(){
655  25 return delegationPolicy.getRules();
656    }
657   
658    /**
659    * This method returns a Role Hierarchy Policy as the only rule. The key in
660    * the map is
661    * issrg.pba.rbac.RoleHierarchyPolicy.class, and the object is the
662    * RoleHierarchyPolicy. These rules are used by AuthTokenParsers to extract
663    * valid roles from Authorisation Tokens.
664    */
 
665  28 toggle public java.util.Map getAuthTokenParsingRules(){
666  28 java.util.Map h = new java.util.Hashtable();
667  28 h.put(issrg.pba.rbac.RoleHierarchyPolicy.class, roleHierarchyPolicy);
668  28 return h;
669    }
670   
671    /**
672    * This method returns the ID of the parsed Policy.
673    *
674    * @return the String identifier of the policy (the string representation of
675    * the OID in the dotted form for PERMIS XML policies)
676    */
 
677  14 toggle public String getPolicyID(){
678  14 return pmiXMLPolicy.getOID();
679    }
680   
681    /**
682    * This method returns the URLs of the repositories specified in the
683    * RepositoryPolicy.
684    *
685    * @return array of Strings, each being a non-null URL; may return an empty
686    * array or null, if no repositories are defined in the policy
687    */
 
688  25 toggle public String [] getRepositoryURLs(){
689  25 if (repositoryPolicy==null) return null;
690   
691  2 return repositoryPolicy.getURLs();
692    }
693   
694    /**
695    * This method returns the domain covering all the allowed subjects. This
696    * is a union of all Subject Domains declared in the policy.
697    *
698    * @return Subtree that is a union of all Subject Domains.
699    */
 
700  0 toggle public Subtree getSubjectDomains() {
701  0 return subjectPolicy.getCoverageDomain();
702    }
703   
704    /**
705    *This method returns the SOA policy of the current XML policy
706    *@return the soa policy
707    */
708   
 
709  1 toggle public java.util.Map getSOAs() {
710  1 return soaPolicy.getSOAs();
711    }
712   
713   
714   
715    /*
716    * POLICY XML NODE CLASSES
717    */
718   
719   
720    /**
721    * The class representing an ActionPolicy XML node. It holds a collection of
722    * action definitions, indexed by the action name. The definitions include
723    * parameter names and order, and the return type name.
724    *
725    * @see #getActionDefinition(String)
726    * @author A Otenko
727    * @version 1.0
728    */
729   
 
730    public class ActionPolicyNode extends PolicyXMLNode{
731    /**
732    * This is the string, containing all the delimiter characters between
733    * arguments in NMTOKENS.
734    */
735    public final static String ARGS_SEPARATORS = ",";
736   
737    /**
738    * This is the storage of the defined actions
739    */
740    private java.util.Map actions = new java.util.Hashtable();
741   
742    /**
743    * This is the storage of targets an action applies to
744    */
745    private java.util.Map targets = new java.util.Hashtable();
746   
747    /**
748    * This is the default constructor used by the XMLPolicyParser.
749    */
 
750  25 toggle public ActionPolicyNode(Attributes attrs) {
751  25 super(XMLTags.ACTION_POLICY_NODE, attrs);
752   
753  25 actionPolicy = this;
754    }
755   
756    /**
757    * This method gets information from the child nodes and sticks them in
758    * the
759    * actions map. The definitions are created as specified in <code>{@link
760    * #getActionDefinition(String) getActionDefinition}</code>
761    */
 
762  25 toggle public void construct(){
763    /**
764    * TODO: treat no children case
765    */
766  134 for (int i=children.size(); i-->0;){
767  109 PolicyXMLNode c = (PolicyXMLNode)children.get(i);
768  109 if (c.getName().intern()!=XMLTags.ACTION_NODE){
769    /**
770    * TODO: signal a syntax error
771    */
772    }
773   
774  109 java.util.Map m = c.getAttributes();
775  109 String n = (String)m.get(XMLTags.NAME_ATTRIBUTE);
776  109 String ret = (String)m.get(XMLTags.RETURN_TYPE_ATTRIBUTE);
777   
778  109 String args = (String)m.get(XMLTags.ARGS_ATTRIBUTE);
779  109 String [] def = new String [] {ret};
780  109 if (args!=null){
781  68 java.util.Vector v = split(args);
782  68 def = new String[1+v.size()];
783  68 def[0]=ret;
784   
785  68 if (def.length>1){
786  13 System.arraycopy(v.toArray(), 0, def, 1, def.length-1);
787    }
788    }
789   
790  109 actions.put(n, def);
791   
792  109 String targetAttribute = (String)m.get(XMLTags.TARGET_ATTRIBUTE);
793  109 if(targetAttribute != null)
794    {
795  1 java.util.Vector targetVector = split(targetAttribute);
796  1 String[] tars = new String[targetVector.size()];
797  1 System.arraycopy(targetVector.toArray(), 0, tars, 0, targetVector.size());
798  1 targets.put(n, tars);
799    }
800    }
801    }
802   
803    /**
804    * Returns the action definition as an array of strings. Can be null,
805    * if no
806    * such method has been defined. The definition is as follows: the 0-th
807    * element
808    * is the return type name, or null, if no return type has been
809    * specified; the
810    * rest of the array elements name the parameters in the order they
811    * appeared
812    * in the XML.
813    *
814    * TODO: check for duplicate parameter identifiers, when constructing?
815    *
816    * @param name - the action name
817    *
818    * @return an array of String, where the 0-th element is the return type
819    * and the others are types of the action parameters
820    */
 
821  1250 toggle public String [] getActionDefinition(String name){
822  1250 return (String [])actions.get(name);
823    }
824   
825    /**
826    * Returns an array of String of the targets this action applies to.
827    *
828    * @param name - the action name
829    *
830    * @return an array of String target names
831    */
 
832  197 toggle public String[] getApplyToTargets(String name)
833    {
834  197 return (String [])targets.get(name);
835    }
836   
837    /**
838    * This method just splits an NMTOKENS string into a Vector of strings.
839    *
840    * @param args - a comma- and/or space-separated list of arguments
841    *
842    * @return Vector of arguments; each element is a String
843    */
 
844  69 toggle private java.util.Vector split(String args){
845  69 java.util.Vector v = new java.util.Vector();
846   
847  69 if (args!=null){
848  69 java.util.Enumeration st = new java.util.StringTokenizer(args, ARGS_SEPARATORS);
849   
850  85 while (st.hasMoreElements()){
851  16 v.add(st.nextElement());
852    }
853    }
854   
855  69 return v;
856    }
857    }
858   
859   
860    /**
861    * This class represents the object that can store many Subject or Target
862    * Domain specifications. As part of its operation it also constructs a
863    * collective domain of all Subjects or all Targets, so that it will be easy
864    * to determine whether an arbitrary entity is part of any domain declared
865    * in the policy.
866    *
867    * @author A Otenko
868    * @version 1.0
869    */
 
870    public class DomainPolicyNode extends PolicyXMLNode{
871   
872    /**
873    * This is the end of the name of a Policy XML node.
874    */
875    public final static String NODE_NAME = "Policy";
876   
877    protected java.util.Map domains;
878    protected issrg.pba.rbac.policies.Subtree coverageDomain;
879   
880    /**
881    * This constructor builds a DomainPolicyNode given the prefix of
882    * nodes to look for ("Subject" or "Target") and the set of attributes.
883    *
884    * @param prefix - the prefix to use before "Policy"; meaningful values
885    * are "Subject" and "Target"
886    * @param attrs - the attributes of the XML element
887    */
 
888  50 toggle public DomainPolicyNode(String prefix, Attributes attrs) {
889  50 super(prefix+NODE_NAME, attrs);
890    }
891   
892    /**
893    * This method constructs a table of domains indexed by their ID and an
894    * aggregated domain that is a union of all domains. The latter is used
895    * to see if a particular entity matches any of the domains in the
896    * policy (to tell if the policy is applicable at all).
897    */
 
898  50 toggle public void construct(){
899    /**
900    * TODO: if a ClassCast exception is thrown,then a Syntax error must have
901    * occurred
902    */
903  50 DomainSpecNode [] s = new DomainSpecNode[children.size()];
904  50 System.arraycopy(children.toArray(), 0, s, 0, s.length);
905   
906  50 domains = new java.util.Hashtable();
907  50 java.util.Vector coverage = new java.util.Vector();
908   
909    //System.out.println("\t\t*** BUILDING A DOMAIN POLICY ***"); //*******
910  166 for (int i=0; i<s.length; i++){
911    //System.out.println("\t"+s[i].getID()+" "+s[i].getSubtree()); //*******
912  116 domains.put(s[i].getID(), s[i].getSubtree());
913  116 coverage.add(s[i].getSubtree());
914    }
915   
916  50 coverageDomain = new issrg.pba.rbac.policies.ComplexSubtree(coverage, null);
917   
918    //System.out.println("\t***"+domains); //*******
919    }
920   
921    /**
922    * Returns the given domain; can be null, if no such domain has been
923    * specified.
924    *
925    * @param id is the domain id
926    *
927    * @return the Subtree object with this ID; can be null, if no such
928    * domain has been defined
929    */
 
930  233 toggle public issrg.pba.rbac.policies.Subtree getDomain(String id){
931    //System.out.println("\t*** getting domain: "+id); //*******
932  233 return (issrg.pba.rbac.policies.Subtree)domains.get(id);
933    }
934   
935    /**
936    * Returns the domain covering all domains declared in this policy.
937    * Subject and Target domains are treated separately, so there are
938    * two coverage domains available: one for Subjects, one for Targets
939    * (query the corresponding policies).
940    */
 
941  1384 toggle public issrg.pba.rbac.policies.Subtree getCoverageDomain(){
942  1384 return coverageDomain;
943    }
944   
945    }
946   
947    /**
948    * This is a simple extension of DomainPolicyNode that makes sure that
949    * SubjectPolicy is constructed correctly. When an instance of this object
950    * is created, subjectPolicy is set in XMLPolicyParser.
951    */
 
952    public class SubjectDomainPolicyNode extends DomainPolicyNode{
 
953  25 toggle public SubjectDomainPolicyNode(Attributes attrs){
954  25 super(XMLTags.SUBJECT_PREFIX, attrs);
955  25 subjectPolicy = this;
956    }
957    }
958   
959   
960    /**
961    * This is a simple extension of DomainPolicyNode that makes sure that
962    * TargetPolicy is constructed correctly. When an instance of this object
963    * is created, targetPolicy is set in XMLPolicyParser.
964    */
 
965    public class TargetDomainPolicyNode extends DomainPolicyNode{
 
966  25 toggle public TargetDomainPolicyNode(Attributes attrs){
967  25 super(XMLTags.TARGET_PREFIX, attrs);
968  25 targetPolicy = this;
969    }
970    }
971   
972    /**
973    * This class represents the abstract DomainSpec, of which there are two
974    * extensions: SubjectDomainSpec and TargetDomainSpec.
975    * It simply creates a ComplexSubtree object and gives it a name.
976    *
977    * @author A Otenko
978    * @version 1.0
979    */
 
980    public class DomainSpecNode extends PolicyXMLNode {
981   
982    /**
983    * This is the end of the name of the DomainSpec node.
984    */
985    public static final String NODE_NAME = "DomainSpec";
986   
987    private String domainID;
988   
989    private issrg.pba.rbac.policies.Subtree subTree;
990   
991    /**
992    * This variable says whether or not the Object Class statements should
993    * follow.
994    */
995    private boolean expectObjClasses;
996   
997    /**
998    * This constructor builds a DomainSpecNode, given the prefix in the
999    * node name ("Subject" or "Target"), the flag whether Object Classes
1000    * should be expected, and the other attributes of the XML element.
1001    *
1002    * @param prefix - the prefix of the DomainSpec XML elements; the only
1003    * meaningful values are "Subject" and "Target", but this is not
1004    * checked
1005    * @param objClass - the flag indicating whether ObjectClass elements
1006    * are allowed in this DomainSpec; if true, they are allowed;
1007    * otherwise a signal error is signaled, when such elements are
1008    * encountered in XML
1009    * @param attrs - the attributes of the XML element
1010    */
 
1011  116 toggle public DomainSpecNode(String prefix, boolean objClass, Attributes attrs) {
1012  116 super(prefix+NODE_NAME, attrs);
1013   
1014  116 expectObjClasses = objClass;
1015    }
1016   
1017    /**
1018    * This method uses gatherSubtrees method to construct a ComplexSubtree
1019    * representing the Domain Specification.
1020    */
 
1021  116 toggle public void construct() throws PolicyParsingException{
1022  116 try{
1023  116 subTree = new issrg.pba.rbac.policies.ComplexSubtree(gatherSubtrees(children, true), null);
1024  116 domainID = (String)this.attributes.get(XMLTags.ID_ATTRIBUTE);
1025    //System.out.println("\t"+attributes); //*******
1026   
1027    }catch(issrg.utils.RFC2253ParsingException rpe){
1028  0 throw new PolicyParsingException(rpe.getMessage(), rpe);
1029    }catch(BadURLException bue){
1030  0 throw new PolicyParsingException(bue.getMessage(), bue);
1031    }catch(java.lang.NumberFormatException nfe){
1032  0 throw new PolicyParsingException("Error parsing integer", nfe);
1033    }
1034    }
1035   
1036    /**
1037    * This method gathers all subtrees defined by the vector of nodes.
1038    * It supports both nested Excludes and sequences of Include and
1039    * Exclude nodes.
1040    * As the result, the following construct is supported:
1041    * &lt;Include ...>&lt;Exclude .../>..&lt;/Include>&lt;Exclude .../>,
1042    * where both Excludes are excluded from the same Include. The nested
1043    * Excludes is the preferred method, whilst the other is kept for
1044    * historic reasons.
1045    *
1046    * @param children the Vector of Include and Exclude nodes
1047    * @param includes the boolean value telling whether Includes should be
1048    * expected; if true, it is the first level of nodes and Includes
1049    * are allowed (as well as the Excludes); otherwise, it is the second
1050    * level of nodes (inside the Includes) and Includes are not allowed
1051    * (whilst the Excludes are still allowed)
1052    */
 
1053  118 toggle protected java.util.Vector gatherSubtrees(java.util.Vector children, boolean includes) throws PolicyParsingException, issrg.utils.RFC2253ParsingException, BadURLException {
1054  118 java.util.Vector subtrees = new java.util.Vector();
1055   
1056  118 java.util.Vector excl = includes?new java.util.Vector():subtrees; // if includes are not expected, collect the excludes into the subtrees - that's what should be returned
1057  118 java.util.Vector classes = null;
1058  118 int i=children.size();
1059  118 boolean objClasses = includes && expectObjClasses; //true; only if includes is true, i.e. it is the first level of nodes, objClasses can be expected
1060   
1061    //System.out.println("\t\t*** BUILDING A DOMAIN SPEC ***"); //*******
1062  303 while(i-->0){ // start from tail - gather ObjectClasses first
1063  185 PolicyXMLNode child = (PolicyXMLNode)children.get(i);
1064  185 String s = child.getName().intern();
1065    // the attributes are collected without checking the name
1066    // of the XML element - that's fine, they can be null
1067  185 String minmax = (String)child.getAttributes().get(XMLTags.MIN_ATTRIBUTE);
1068  185 int min=minmax==null?0:Integer.parseInt(minmax);
1069   
1070  185 minmax = (String)child.getAttributes().get(XMLTags.MAX_ATTRIBUTE);
1071  185 int max=minmax==null?-1:Integer.parseInt(minmax);
1072   
1073    //System.out.println("\t"+s); //*******
1074   
1075  185 String dn = (String)child.getAttributes().get(XMLTags.LDAPDN_ATTRIBUTE);
1076  185 String url = (String)child.getAttributes().get(XMLTags.URL_ATTRIBUTE);
1077   
1078  185 if (dn!=null && url!=null){
1079  0 throw new PolicyParsingException("Invalid subtree specification: cannot have "+XMLTags.LDAPDN_ATTRIBUTE+" and "+XMLTags.URL_ATTRIBUTE+" attributes at the same time.");
1080    }
1081   
1082  185 if (dn==null && url==null){ // if both were not specified, imply "world" LDAPDN (DN="")
1083  1 dn="";
1084    }
1085   
1086  185 Subtree sub=null;
1087   
1088  185 objClasses &= s==XMLTags.OBJECT_CLASS_NODE; // as soon as no more ObjectClasses are there, let no more appear
1089   
1090  185 if (s==XMLTags.INCLUDE_NODE){
1091  0 if (!includes) throw new PolicyParsingException(s+" nodes cannot be nested"); // !includes => second level of nodes, inside an Include
1092   
1093    //System.out.println("\t\tchildren: "+child.getChildren()); //*********
1094  172 if (child.getChildren().size()!=0){ // if include node has children, all of them should be Exclude nodes - add them all to the list of already collected Exclude nodes
1095  2 excl.addAll(0, gatherSubtrees(child.getChildren(), false));
1096    }
1097   
1098  172 Subtree [] exclude = (Subtree[])excl.toArray(new Subtree[0]);
1099  172 excl = new java.util.Vector(); // reset the list of Excludes once it has been used
1100   
1101  172 if (dn==null){ // URL is not null then! if dn==null and url==null, then dn="";
1102    //System.out.print("\t\t\turl: "+url); //*********
1103  42 sub=issrg.pba.rbac.URLHandler.getSubtreeByURL(url, min, max, exclude);
1104    }else{
1105  130 sub=new DITSubtree(new LDAPDNPrincipal(dn), min, max, classes==null?null:(String[])classes.toArray(new String[0]), exclude);
1106    }
1107   
1108    //System.out.println("\tsubtree: "+sub); //*********
1109    // this should never happen - just a sanity check
1110  0 if (sub==null) throw new PolicyParsingException("Invalid subtree specification: DN="+dn+", URL="+url);
1111   
1112    // adding from before, so the array will look as a copy of the actual
1113    // XML: note, that the XML child nodes are passed in the reverse order
1114   
1115  172 subtrees.add(0, sub);
1116  13 }else if (s==XMLTags.EXCLUDE_NODE){
1117  12 if (dn==null){ // URL is not null then! if dn==null and url==null, then dn="";
1118  2 sub=issrg.pba.rbac.URLHandler.getSubtreeByURL(url, min, max, null);
1119    }else{
1120  10 sub=new DITSubtree(new LDAPDNPrincipal(dn), min, max, null, null);
1121    }
1122   
1123    // this should never happen - just a sanity check
1124  0 if (sub==null) throw new PolicyParsingException("Invalid subtree specification: DN="+dn+", URL="+url);
1125   
1126  12 excl.add(0, sub);
1127  1 }else if (objClasses){// && s==OBJECT_CLASS_NODE){ -- this comparison is superficial, when objClasses is already tracking this
1128  1 if (classes==null){
1129  1 classes = new java.util.Vector();
1130    }
1131   
1132  1 s=(String)child.getAttributes().get(XMLTags.NAME_ATTRIBUTE);
1133  1 if (s==null){
1134  0 throw new PolicyParsingException(XMLTags.NAME_ATTRIBUTE+" is required, but not found");
1135    }
1136  1 classes.add(s);
1137    }else{
1138  0 throw new PolicyParsingException(s+" node was found, but was not expected");
1139    }
1140    }
1141    // TODO: check that includes==true and excl.size()==0? i.e. unused Excludes were found - they should never go before Includes?
1142    // and complain?
1143   
1144  118 return subtrees;
1145    }
1146   
1147    /**
1148    * Returns the ID of the Domain.
1149    */
 
1150  116 toggle public String getID(){
1151  116 return domainID;
1152    }
1153   
1154    /**
1155    * Returns the Subtree of this Domain specification.
1156    */
 
1157  232 toggle public Subtree getSubtree(){
1158  232 return subTree;
1159    }
1160   
1161    }
1162   
1163    /**
1164    * This is a simple extension of DomainSpecNode that makes sure that only
1165    * SubjectDomainSpecs are interpreted, and no ObjectClasses are allowed.
1166    */
 
1167    public class SubjectDomainSpecNode extends DomainSpecNode{
 
1168  50 toggle public SubjectDomainSpecNode(Attributes attrs){
1169  50 super(XMLTags.SUBJECT_PREFIX, false, attrs);
1170    }
1171    }
1172   
1173    /**
1174    * This is a simple extension of DomainSpecNode that makes sure that only
1175    * TargetDomainSpecs are interpreted, and ObjectClasses are allowed.
1176    */
 
1177    public class TargetDomainSpecNode extends DomainSpecNode{
 
1178  66 toggle public TargetDomainSpecNode(Attributes attrs){
1179  66 super(XMLTags.TARGET_PREFIX, true, attrs);
1180    }
1181    }
1182   
1183    /**
1184    * This node implements the RoleAssignmentPolicy XML node. It is intelligent
1185    * enough to walk through its children and retrieve all the information to
1186    * build an index of AssignmentRule vectors by SOA DNs.
1187    *
1188    * @author A Otenko
1189    * @version 1.0
1190    */
 
1191    public class RoleAssignmentPolicyNode extends PolicyXMLNode{
1192    /**
1193    * These numbers are the position of the nodes under the RoleAssignment node.
1194    */
1195    public static final int SUBJECT_DOMAIN_NODE_SEQUENCE = 0;
1196    public static final int ROLE_LIST_NODE_SEQUENCE = 1;
1197    public static final int DELEGATE_NODE_SEQUENCE = 2;
1198    public static final int SOA_NODE_SEQUENCE = 3;
1199    public static final int VALIDITY_NODE_SEQUENCE = 4;
1200   
1201    public static final int ABSOLUTE_VALIDITY_NODE_SEQUENCE = 0;
1202    public static final int AGE_VALIDITY_NODE_SEQUENCE = 1;
1203    public static final int MAXIMUM_VALIDITY_NODE_SEQUENCE = 2;
1204    public static final int MINIMUM_VALIDITY_NODE_SEQUENCE = 3;
1205   
1206    /**
1207    * Temporary storage for different policies.
1208    */
1209    private DomainPolicyNode subjectPol;
1210    private SOAPolicyNode soas;
1211   
1212    /**
1213    * This is where the final rules are stored, indexed by SOA DN.
1214    */
1215    protected java.util.Map rules;
1216   
1217    /**
1218    * This constructor builds a RoleAssingmentPolicyNode, given the
1219    * attributes of the XML element. It uses the Subject Policy and
1220    * SOA Policy constructed by XMLPolicyParser, so these must already be
1221    * known at the time of constructing the object.
1222    *
1223    * @param attrs - the attributes of this XML element
1224    */
 
1225  25 toggle public RoleAssignmentPolicyNode(Attributes attrs){
1226  25 this(subjectPolicy, soaPolicy, attrs);
1227    }
1228   
1229    /**
1230    * This constructor builds the object from explicitly specified
1231    * Subject Policy, SOA Policy and the attributes of the XML element.
1232    *
1233    * @param subjectPolicy - the Subject Policy to be used
1234    * @param soaPolicy - the SOA Policy to be used
1235    * @param attrs - the attributes of this XML element
1236    */
 
1237  25 toggle public RoleAssignmentPolicyNode(DomainPolicyNode subjectPolicy,
1238    SOAPolicyNode soaPolicy, Attributes attrs) {
1239  25 super(XMLTags.ROLE_ASSIGNMENT_POLICY_NODE, attrs);
1240   
1241  25 this.subjectPol = subjectPolicy;
1242  25 soas = soaPolicy;
1243  25 delegationPolicy = this;
1244    }
1245   
1246    /**
1247    * This method finishes the construction of the Role Assignment Policy.
1248    * During this process it checks that the right XML statements appear
1249    * in the policy and in the correct sequence. It checks that the SOA
1250    * and the Subject domain with the specified IDs have been declared in
1251    * the corresponding policies.
1252    */
 
1253  25 toggle public void construct() throws PolicyParsingException{
1254  25 rules = new java.util.Hashtable();
1255   
1256  25 rules.put(issrg.pba.rbac.policies.Subtree.class, subjectPol.getCoverageDomain());
1257   
1258    //System.out.println("\t\t*** BUILDING ROLE ASSIGNMENT POLICY ***"); //********
1259  77 for (int i=children.size(); i-->0; ){
1260  52 PolicyXMLNode c = (PolicyXMLNode)children.get(i);
1261  52 String s = c.getName().intern();
1262  52 if (s!=XMLTags.ROLE_ASSIGNMENT_NODE){
1263  0 throw new PolicyParsingException("Only "+XMLTags.ROLE_ASSIGNMENT_NODE+" nodes are allowed under this node");
1264    }
1265   
1266  52 java.util.Vector v = c.getChildren();
1267    //System.out.println("\t"+i+": "+c.getName()+" children:"+v.size()); //********
1268   
1269  52 String subjId = (String)expect(v, SUBJECT_DOMAIN_NODE_SEQUENCE, XMLTags.SUBJECT_DOMAIN_NODE).getAttributes().get(XMLTags.ID_ATTRIBUTE);
1270    //System.out.print("subjId: "+subjId); //********
1271   
1272  52 RoleListNode roleList = (RoleListNode)expect(v, ROLE_LIST_NODE_SEQUENCE, XMLTags.ROLE_LIST_NODE);
1273   
1274  52 String delegationDepth = (String)expect(v, DELEGATE_NODE_SEQUENCE, XMLTags.DELEGATE_NODE).getAttributes().get(XMLTags.DEPTH_ATTRIBUTE);
1275    //System.out.print(" delegationDepth: "+delegationDepth); //********
1276  52 int delegation;
1277   
1278  52 try{
1279  52 delegation=delegationDepth==null? -1 : Integer.parseInt(delegationDepth);
1280  0 if (delegation<-1) throw new NumberFormatException();
1281    }catch(java.lang.NumberFormatException ex){
1282  0 throw new PolicyParsingException("Delegation Depth should be a valid non-negative integer number, or be missing", ex);
1283    }
1284   
1285   
1286  52 String soaId = (String)expect(v, SOA_NODE_SEQUENCE, XMLTags.SOA_NODE).getAttributes().get(XMLTags.ID_ATTRIBUTE);
1287    //System.out.print(" soaId: "+soaId); //********
1288   
1289  52 Vector validity = expect(v, VALIDITY_NODE_SEQUENCE, XMLTags.VALIDITY_NODE).getChildren();
1290   
1291  52 validityForRoleList = new issrg.pba.rbac.AnyTimeValidityPeriod(); // the default validity period
1292  52 int missingnodes=0;
1293  52 PolicyXMLNode val_node = expect(validity, ABSOLUTE_VALIDITY_NODE_SEQUENCE, XMLTags.ABSOLUTE_NODE, true);
1294  52 issrg.pba.rbac.RelativeDate rd;
1295   
1296  52 if (val_node==null){
1297  33 missingnodes++;
1298    }else{
1299  19 java.util.Date nb = null;
1300  19 java.util.Date na = null;
1301  19 s = (String)val_node.getAttributes().get(XMLTags.START_ATTRIBUTE);
1302  19 if (s!=null && s.intern()!=""){
1303  19 rd = parseDateTime(s);
1304  19 rd.months--;
1305  19 nb = rd.getDate();
1306    }
1307   
1308  19 s = (String)val_node.getAttributes().get(XMLTags.END_ATTRIBUTE);
1309  19 if (s!=null && s.intern()!=""){
1310  19 rd = parseDateTime(s);
1311  19 rd.months--;
1312  19 na = rd.getDate();
1313    }
1314   
1315  19 validityForRoleList=new issrg.pba.rbac.AbsoluteValidityPeriod(nb, na);
1316    }
1317   
1318  52 issrg.pba.rbac.RelativeDate age=null;
1319  52 issrg.pba.rbac.RelativeDate min=null;
1320  52 issrg.pba.rbac.RelativeDate max=null;
1321   
1322  52 val_node = expect(validity, AGE_VALIDITY_NODE_SEQUENCE-missingnodes, XMLTags.AGE_NODE, true);
1323  52 if (val_node==null){
1324  50 missingnodes++;
1325    }else{
1326  2 s = (String)val_node.getAttributes().get(XMLTags.TIME_ATTRIBUTE);
1327  2 if (s==null){
1328  0 throw new PolicyParsingException(XMLTags.TIME_ATTRIBUTE+" attribute is missing in "+XMLTags.AGE_NODE);
1329    }
1330   
1331  2 age=parseDateTime(s);
1332    }
1333   
1334  52 val_node = expect(validity, MAXIMUM_VALIDITY_NODE_SEQUENCE-missingnodes, XMLTags.MAXIMUM_NODE, true);
1335  52 if (val_node==null){
1336  50 missingnodes++;
1337    }else{
1338  2 s = (String)val_node.getAttributes().get(XMLTags.TIME_ATTRIBUTE);
1339  2 if (s==null){
1340  0 throw new PolicyParsingException(XMLTags.TIME_ATTRIBUTE+" attribute is missing in "+XMLTags.MAXIMUM_NODE);
1341    }
1342   
1343  2 max=parseDateTime(s);
1344    }
1345   
1346  52 val_node = expect(validity, MINIMUM_VALIDITY_NODE_SEQUENCE-missingnodes, XMLTags.MINIMUM_NODE, true);
1347  52 if (val_node==null){
1348  51 missingnodes++;
1349    }else{
1350  1 s = (String)val_node.getAttributes().get(XMLTags.TIME_ATTRIBUTE);
1351  1 if (s==null){
1352  0 throw new PolicyParsingException(XMLTags.TIME_ATTRIBUTE+" attribute is missing in "+XMLTags.MINIMUM_NODE);
1353    }
1354   
1355  1 min=parseDateTime(s);
1356    }
1357   
1358  52 if (age!=null || min!=null || max!=null){
1359  5 validityForRoleList = new issrg.pba.rbac.AdjustedPeriodCollection(
1360    validityForRoleList,
1361    new issrg.pba.rbac.AdjustedValidityPeriod(age, min, max)
1362    );
1363    }
1364   
1365  52 roleList.construct(); // this is a bit clumsy - the roleList has already constructed the list of roles
1366    // but the Validity could not be defined properly at that time
1367    // so I have to call construct again. this is only due to the syntax of the policy (that the nodes appear in this sequence)
1368  52 issrg.pba.Credentials soaCreds = roleList.getCredential();
1369    //System.out.print(" soaCreds: "+soaCreds); //********
1370   
1371  52 java.security.Principal soa = soas.getSOA(soaId);
1372    //System.out.println("\nsoa: "+soa); //********
1373  52 if (soa==null){
1374  0 throw new PolicyParsingException("No SOA with "+soaId+" has been defined");
1375    }
1376   
1377    //System.out.print("getting subject domain:..."); //********
1378  52 Subtree subj = subjectPol.getDomain(subjId);
1379    //System.out.println("ok : "+subj); //********
1380  52 if (subj==null){
1381  0 throw new PolicyParsingException("No Subject Domain with "+subjId+" has been defined");
1382    }
1383   
1384  52 java.util.Vector v2 = (java.util.Vector)rules.get(soa.getName());
1385  52 if (v2==null){ // a rule for a new SOA
1386  40 v2 = new java.util.Vector();
1387  40 rules.put(soa.getName(), v2);
1388    }
1389   
1390    //System.out.println("creating an assignment rule:..."); //********
1391  52 v2.add(new issrg.pba.rbac.policies.AssignmentRule(subj, delegation, soaCreds));
1392    //System.out.println("ok"); //********
1393    }
1394    }
1395   
1396    /**
1397    * This method returns the rules defined by the appropriate XML node.
1398    * The rules contain Vectors of issrg.pba.rbac.policies.AssignmentRule
1399    * objects, indexed by the SOA name. There also is a special entry
1400    * with the key issrg.pba.rbac.policies.Subtree.class: its value is
1401    * a issrg.pba.rbac.policies.Subtree of the coverage domain of the
1402    * Subject Policy.
1403    */
 
1404  25 toggle public java.util.Map getRules(){
1405  25 return rules;
1406    }
1407   
1408    /**
1409    * This routine parses the string in format ccyy-mm-ddThh:mm:ss and
1410    * separates it into
1411    * the integers. The syntax is not strict, so any nymber of subsequent
1412    * digits is allowed,
1413    * and any non-digit characters can be used as separators (the parser
1414    * does not ensure the
1415    * separators are "-", "T", ":", and that they are used in that order).
1416    *
1417    * <p>Examples:
1418    * <p>"00000002~73|1" is parsed as year 2, month 73, day 1. Note that
1419    * the actual meaning
1420    * depends on where this statement is used. If it is the Absolute date
1421    * specification, then
1422    * it is equal to "8-1-1" (73 months is the same as 6 more years and 1
1423    * month).
1424    * <p>"2002-12-31T12:00:21:567" - the last term ":567" is ignored.
1425    *
1426    * @param s is the string of format "ccyy-mm-ddThh:mm:ss" to parse
1427    *
1428    * @return a RelativeDate object with appropriate integers assigned
1429    */
 
1430  43 toggle protected issrg.pba.rbac.RelativeDate parseDateTime(String s){
1431  43 int [] d = new issrg.pba.rbac.Time(s).getEvaluationTime(); // use the existing parser
1432   
1433  43 return new issrg.pba.rbac.RelativeDate(d[0], d[1], d[2], d[3], d[4], d[5]);
1434    }
1435    }
1436   
1437   
1438   
1439   
1440   
1441    /**
1442    * This is the class representing SupRole nodes. It knows its value and its
1443    * direct subordinates. However, it can always tell you whether a given Role
1444    * is subordinate to it or not.
1445    *
1446    * @author A Otenko
1447    * @version 1.0
1448    */
 
1449    public class RoleHierarchyNode extends PolicyXMLNode implements issrg.pba.rbac.RoleHierarchyNode {
1450    /**
1451    * This is a number, representing how high in the hierarchy this node is
1452    * located. It helps to optimise calculations of who is superior to who.
1453    *
1454    * <p>Its property is that hierarchy level of the most superior roles is
1455    * 0,
1456    * and that any child role hierarchy level is a bigger integer (not
1457    * always
1458    * greater just by one, because this is not a tree). So if this role
1459    * has bigger integer than another, then the former definitely cannot be
1460    * superior to the latter.
1461    */
1462    protected int hierarchyLevel = -1;
1463   
1464    protected String type;
1465    protected String value;
1466   
1467    protected RoleHierarchyNode [] subordinates=null;
1468   
1469    /**
1470    * This is a flag that indicates how many loops include this node. There
1471    * always
1472    * should be zero loops.
1473    */
1474    private int loops = 0;
1475   
 
1476  101 toggle public RoleHierarchyNode(org.xml.sax.Attributes attrs) {
1477  101 super(XMLTags.SUP_ROLE_NODE, attrs);
1478   
1479  101 _init_();
1480    }
1481   
 
1482  101 toggle private void _init_(){
1483  101 value = attrs.getValue(XMLTags.VALUE_ATTRIBUTE);
1484    }
1485   
1486    /**
1487    * This method links the roles together, using the given Map as a
1488    * reference to
1489    * other Roles. Before calling this method, it is useless to call
1490    * getLevel or
1491    * isSuperiorTo, as they will not be able to determine hierarchical
1492    * relationships between two roles.
1493    *
1494    * @param roleHierarchy - the Map of roles, where the key is the role
1495    * value, and the value is the RoleHierarchyNode
1496    */
 
1497  101 toggle public void optimise(java.util.Map roleHierarchy) throws PolicyParsingException{
1498  101 try{
1499  101 if (subordinates!=null){ // optimised already
1500  0 return;
1501    }
1502   
1503  101 Object [] childs = children.toArray();
1504  101 subordinates = new RoleHierarchyNode[childs.length];
1505   
1506  149 for (int i=0; i<childs.length; i++){
1507  48 String s = (String)(((PolicyXMLNode)childs[i]).getAttributes().get(XMLTags.VALUE_ATTRIBUTE));
1508   
1509  48 RoleHierarchyNode sub = (RoleHierarchyNode)roleHierarchy.get(s);
1510   
1511  48 if (sub==null){
1512  0 throw new PolicyParsingException("Could not find Role "+s+" in this hierarchy");
1513    }
1514   
1515  48 subordinates[i]=sub;
1516  48 sub.setLevel(getLevel()+1); // not the suggested level, but the one,
1517    // that is set now
1518    }
1519    }catch(Throwable th){
1520  0 throw new PolicyParsingException(th.getMessage());
1521    }
1522   
1523  101 if (loops!=0){
1524  0 throw new PolicyParsingException("Role Hierarchy directed graph contains loops");
1525    }
1526    }
1527   
1528    /**
1529    * This method returns the hierarchy level of the node.
1530    */
 
1531  24231 toggle public int getLevel(){
1532  24231 return hierarchyLevel;
1533    }
1534   
1535    /**
1536    * This method sets the hierarchy level of the node. It is set only if
1537    * the
1538    * given level is greater (lower position) than the current. It also
1539    * updates
1540    * the counter of loops in the hierarchy that appeared by adding this
1541    * node.
1542    * Note that the latter counter depends on the sequence of updating the
1543    * hierarchy.
1544    *
1545    * @param level - the least new level of the node; if the node already
1546    * has a higher level, the level won't be updated; otherwise its
1547    * level and the level of all of its subordinates will be updated
1548    */
 
1549  113 toggle public void setLevel(int level){
1550  113 loops++; // update always; it will be restored to zero, if no loops encountered
1551  113 if (loops!=1){
1552  0 return;
1553    }
1554   
1555  113 if (level>=getLevel()){
1556    // updating ok: no loops encountered
1557  108 hierarchyLevel = level;
1558  108 if (subordinates!=null)
1559  173 for(int i=0; i<subordinates.length; i++){
1560  65 subordinates[i].setLevel(level+1);
1561    }
1562    }
1563  113 loops--;
1564    }
1565   
1566    /**
1567    * This method returns the Role Value as String.
1568    */
 
1569  45595 toggle public String getValue(){
1570  45595 return value;
1571    }
1572   
1573    /**
1574    * This method returns the Role Value as Object (required by
1575    * issrg.pba.rbac.Role interface).
1576    */
 
1577  17244 toggle public Object getRoleValue(){
1578  17244 return getValue();
1579    }
1580   
1581    /**
1582    * This method returns the Role Type.
1583    */
 
1584  2711 toggle public String getRoleType(){
1585  2711 return type;
1586    }
1587   
1588    /**
1589    * This method sets the type of the role; for use by the Role Spec
1590    * Policy only at the object
1591    * initialisation time.
1592    */
 
1593  101 toggle protected void setRoleType(String t){
1594  101 type=t;
1595    }
1596   
1597    /**
1598    * This method returns whether or not the given role's privileges should
1599    * be
1600    * inherited or not. The node is equal to the current one only if they
1601    * refer
1602    * to the same node, or their values are equal.
1603    *
1604    * <p>TODO: do i remove String equality of their values?
1605    *
1606    * @return true, if rhn is equal to, or is subordinate to this node
1607    */
 
1608  17641 toggle public boolean isSuperiorTo(issrg.pba.rbac.RoleHierarchyNode rhn){
1609    //System.out.println("checking if "+this+" is superior to "+rhn);//*************
1610   
1611  17641 if (rhn==null || !(rhn instanceof RoleHierarchyNode)){
1612    //System.out.println(rhn+": is not an instance of RoleHierarchyNode");//*************
1613  0 return false;
1614    }
1615   
1616  17641 RoleHierarchyNode rhn1 = (RoleHierarchyNode)rhn;
1617   
1618  17641 if (rhn1==this || rhn1.getValue().intern()==getValue().intern()){
1619    //System.out.println(this+" is superior to "+rhn1);//*************
1620  5606 return true;
1621    }
1622   
1623    // this is why I invented that hierarchy level thing: now I can stop
1624    // if I am definitely on the wrong branch.
1625  12035 if (rhn1.getLevel()<=getLevel() || subordinates==null){
1626    //System.out.println(this+" is not superior to "+rhn1+": this level="+getLevel()+">="+rhn1.getLevel()+", "+(subordinates==null));//*************
1627  6715 return false;
1628    }
1629   
1630  6029 for (int i=0; i<subordinates.length; i++){
1631    //System.out.println(": lets check if "+subordinates[i]+" is superior to "+rhn);//*************
1632  5963 if (subordinates[i].isSuperiorTo(rhn)){
1633    //System.out.println(subordinates[i]+" is superior to "+rhn);//*************
1634  5254 return true;
1635    }
1636    //System.out.println(": no, "+subordinates[i]+" is not superior to "+rhn);//*************
1637    }
1638   
1639    //System.out.println(this+" is not superior to "+rhn+": no subordinate is superior to it");//*************
1640  66 return false;
1641    }
1642   
1643    /**
1644    * The string representation of this node is the role value.
1645    */
 
1646  0 toggle public String toString(){
1647  0 return getValue();
1648    }
1649    }
1650   
1651   
1652    /**
1653    * This is the class that represents the RoleHierarchyPolicy node. It knows
1654    * all the types and OIDs of all Role hierarchies declared in the policy.
1655    *
1656    * @author A Otenko
1657    * @version 1.0
1658    */
 
1659    public class RoleHierarchyPolicyNode extends PolicyXMLNode implements issrg.pba.rbac.RoleHierarchyPolicy {
1660    /**
1661    * This is a Map of Role hierarchies, indexed by their type.
1662    */
1663    protected java.util.Map byType = new java.util.Hashtable();
1664   
1665    /**
1666    * This is a Map of Role hierarchies, indexed by their OID.
1667    */
1668    protected java.util.Map byOID = new java.util.Hashtable();
1669    protected java.util.Map typeOid = new java.util.Hashtable();
1670   
1671    /**
1672    * This is the only constructor, and it simply creates a PolicyXMLNode
1673    * of this type.
1674    */
 
1675  25 toggle public RoleHierarchyPolicyNode(Attributes attrs) {
1676  25 super(XMLTags.ROLE_HIERARCHY_POLICY_NODE, attrs);
1677   
1678  25 roleHierarchyPolicy = this;
1679    }
1680   
1681    /**
1682    * This method looks through its children and rearranges them into maps
1683    * of
1684    * role hierarchies by type and by OID.
1685    *
1686    * @throws PolicyParsingException if a semantic error is encountered
1687    * (for
1688    * example, two role hierarchies of the same type)
1689    */
 
1690  25 toggle public void construct() throws PolicyParsingException{
1691  25 Object [] childs = children.toArray();
1692   
1693  55 for (int i=0; i<childs.length; i++){
1694  30 RoleSpecNode rsn = (RoleSpecNode)childs[i];
1695   
1696  30 String s = rsn.getType();
1697  30 String oid = rsn.getOID();
1698  30 if (byType.get(s)!=null){ // such a type exists
1699  0 throw new PolicyParsingException("Role Type "+s+" defined more than once");
1700    }
1701   
1702  30 if (byOID.get(oid)!=null){ // such an OID is defined
1703  0 throw new PolicyParsingException("Role OID "+oid+" defined more than once");
1704    }
1705   
1706  30 byType.put(s, rsn);
1707  30 byOID.put(oid, rsn); // the Type and OID should not be the same anyway?.. so it could be the same Hashtable, couldn't it?
1708  30 typeOid.put(s,oid);
1709    }
1710    }
1711   
1712    /**
1713    * This method returns a RoleSpecNode (a role hierarchy) of the given
1714    * type.
1715    *
1716    * @param roleType is the String name of the role type to return
1717    *
1718    * @return the RoleSpecNode representing the hierarchy of roles of the
1719    * given
1720    * type, or null, if no such type has been defined
1721    */
 
1722  2919 toggle public RoleSpecNode getByType(String roleType){
1723  2919 return roleType==null ? null : (RoleSpecNode)byType.get(roleType);
1724    }
1725   
1726   
1727    /**
1728    * This method returns a RoleSpecNode (a role hierarchy) of the given
1729    * OID.
1730    *
1731    * @param roleOID is the dotted representation of the OID of the role
1732    * hierarchy to return
1733    *
1734    * @return the RoleSpecNode representing the hierarchy of roles of the
1735    * given
1736    * OID, or null, if no such type has been defined
1737    */
 
1738  1803 toggle public RoleSpecNode getByOID(String roleOID){
1739  1803 return roleOID==null ? null : (RoleSpecNode)byOID.get(roleOID);
1740    }
1741   
1742    /**
1743    * This method returns the role type defined for a specific OID.
1744    *
1745    * @param roleOID - the OID in dotted form of the role type
1746    *
1747    * @return the role type, as declared in the policy, or null, if no
1748    * role type for this OID has been declared
1749    */
 
1750  1803 toggle public String getTypeByOID(String roleOID){
1751  1803 RoleSpecNode rsn = getByOID(roleOID);
1752   
1753  1803 return rsn==null ? null : rsn.getType();
1754    }
1755   
1756    /**
1757    * This method returns a reference to a hierarchy node for the role of
1758    * the given type and value.
1759    *
1760    * @param type - the type of the role, as declared in the policy
1761    * @param value - the value of the role, as declared in the policy
1762    *
1763    * @return issrg.pba.rbac.RoleHierarchyNode that represents the role
1764    * with the given value of the given type, or null, if no such type
1765    * has been declared, or if there is no such value for the existing
1766    * type
1767    */
 
1768  2589 toggle public issrg.pba.rbac.RoleHierarchyNode getRole(String type, String value){
1769  2589 RoleSpecNode rsn = getByType(type);
1770  2589 return rsn==null ? null : rsn.getRole(value);
1771    }
1772   
1773    /**
1774    * This method returns a Map of types into OIDs. The keys in the Map
1775    * are the role types, as defined in the policy, and the values in the
1776    * Map are the OIDs of these roles.
1777    */
 
1778  1 toggle public Map getTypeOid() {
1779  1 return typeOid;
1780    }
1781    }
1782   
1783   
1784   
1785    /**
1786    * This is an implementation of Role List. The object constructs the
1787    * credential
1788    * the Role List represents. It uses a RoleHierarchyPolicyNode to identify
1789    * the roles listed.
1790    *
1791    * @author A Otenko
1792    * @version 1.0
1793    */
 
1794    public class RoleListNode extends PolicyXMLNode {
1795    /**
1796    * This is the reference to the Role Hierarchy Policy
1797    */
1798    protected RoleHierarchyPolicyNode policy;
1799   
1800    /**
1801    * This is the credential, represented by the Role List.
1802    */
1803    protected issrg.pba.Credentials credential;
1804   
1805    /**
1806    * This constructor builds a RoleListNode given the set of attributes.
1807    * It uses the default RoleHierarchyPolicy that must be discovered by
1808    * XMLPolicyParser by the time of constructing this Role List.
1809    *
1810    * <p>This is a shortcut to calling new RoleListNode(null, attrs).
1811    *
1812    * @param attrs - the attributes of this XML element
1813    */
 
1814  151 toggle public RoleListNode(Attributes attrs){
1815  151 this(null, attrs);
1816    }
1817   
1818    /**
1819    * This constructor builds a RoleListNode given the RoleHierarchyPolicy
1820    * and the attributes of the XML element.
1821    *
1822    * @param rhpn - RoleHierarchyPolicyNode representing the role hierarchy
1823    * policy to be used by this Role List; if null, the default
1824    * RoleHierarchyPolicy discovered by XMLPolicyParser will be used
1825    * @param attrs - the attributes of the XML element
1826    */
 
1827  151 toggle public RoleListNode(RoleHierarchyPolicyNode rhpn, Attributes attrs){
1828  151 super(XMLTags.ROLE_LIST_NODE, attrs);
1829   
1830  151 policy = rhpn==null?roleHierarchyPolicy:rhpn;