The Permission Class Permissions

static private int VIEW = 0x01; static private int UPDATE = 0x02; public XYZPayrollPermissionString name { Our permission must always have an action, so we choose a default one here. thisname, view; } public XYZPayrollPermissionString name, String action { Our superclass, however, does not support actions so we dont provide one to that. supername; parseaction; } private void parseString action { Look in the action string for the words view and update, separated by white space or by a comma StringTokenizer st = new StringTokenizeraction, ,\t ; mask = 0; while st.hasMoreTokens { String tok = st.nextToken ; if tok.equalsview mask |= VIEW; else if tok.equalsupdate mask |= UPDATE; else throw new IllegalArgumentException Unknown action + tok; } } public boolean impliesPermission permission { if permission instanceof XYZPayrollPermission return false; XYZPayrollPermission p = XYZPayrollPermission permission; String name = getName ; The name must be either the wildcard , which signifies all possible names, or the name must match our name if name.equals name.equalsp.getName return false; Similarly, the requested actions must all match actions that weve been constructed with. if mask p.mask = p.mask return false; Only if both the action and name match do we return true. return true; } public boolean equalsObject o { if o instanceof XYZPayrollPermission return false; For equality, we check the name and action mask. We must provide a method definition like this, since the security system expects us to do a deep check for equality rather than relying on object reference equality. XYZPayrollPermission p = XYZPayrollPermission o; return p.getName.equalsgetName p.mask == mask; } public int hashCode { We must always provide a hash code for permissions, because the hashes must match if the permissions compare as equals. The default implementation of this method wouldnt provide that. return getName.hashCode mask; } public String getActions { This method must return the same string, no matter how the action list was passed to the constructor. if mask == 0 return ; else if mask == VIEW return view; else if mask == UPDATE return update; else if mask == VIEW | UPDATE return view, update; else throw new IllegalArgumentExceptionUnknown mask; } public PermissionCollection newPermissionsCollection { More about this in a later example. return new XYZPayrollPermissionCollection ; } public static void mainString[] args { XYZPayrollPermission p1 = new XYZPayrollPermissionsdo, view; XYZPayrollPermission p2 = new XYZPayrollPermissionargs[0], args[1]; System.out.printlnP1 is + p1; System.out.printlnP2 is + p2; System.out.printlnP1 − P2 is + p1.impliesp2; System.out.printlnP2 − P1 is + p2.impliesp1; } } The instance variables in this class are required to hold the information about the actions −− even though our superclass makes references to actions, it doesnt provide a manner in which to store them or process them, so we have to provide that logic. That logic is provided in the parse method; weve chosen the common convention of having the action string treated as a list of actions that are separated by commas and whitespace. Note also that weve stored the actual actions as bits in a single integer −− this simplifies some of the later logic. As required, weve implemented the equals and hashCode methods −− and we have done so rather simply. We consider objects equal if their names are equal and their masks that is, their actions are equal, and construct a hash code accordingly. Our implementation of the getActions method is typical: were required to return the same action string for a permission object that was constructed with an action list of view, update as for one that was constructed with an action list of update, view . This requirement is one of the prime reasons why the actions are stored as a mask −− because it allows us to construct this action string in the proper format. Finally, the implies method is responsible for determining how wildcard and other implied permissions are handled. If the name passed to construct our object is an asterisk, then we match any other name; hence, an object to represent the permissions of the HR department might be constructed as: