public String next() throws StandardException { if (initial) { // Optimization so we don't compute the closure for the current // role if unnecessary (when next is only called once). initial = false; seenSoFar.put(root, null); return root; } else if (graph == null) { // We get here the second time next is called. graph = dd.getRoleGrantGraph(tc, inverse); List outArcs = (List) graph.get(root); if (outArcs != null) { currNodeIter = outArcs.iterator(); } } RoleGrantDescriptor result = null; while (result == null) { while (currNodeIter.hasNext()) { RoleGrantDescriptor r = (RoleGrantDescriptor) currNodeIter.next(); if (seenSoFar.containsKey(inverse ? r.getRoleName() : r.getGrantee())) { continue; } else { lifo.add(r); result = r; break; } } if (result == null) { // not more candidates located outgoing from the // latest found node, pick another and continue RoleGrantDescriptor newNode = null; currNodeIter = null; while (lifo.size() > 0 && currNodeIter == null) { newNode = (RoleGrantDescriptor) lifo.remove(lifo.size() - 1); // In the example (see interface doc), the // iterator of outgoing arcs for f (grant inverse) // would contain {e,c,d}. List outArcs = (List) graph.get(inverse ? newNode.getRoleName() : newNode.getGrantee()); if (outArcs != null) { currNodeIter = outArcs.iterator(); } // else: leaf node, pop next candidate, if any } if (currNodeIter == null) { // candidate stack is empty, done currNodeIter = null; break; } } } if (result != null) { String role = inverse ? result.getRoleName() : result.getGrantee(); seenSoFar.put(role, null); return role; } else { return null; } }