private void buildAccessMap() {
    Map actionMap = null;
    SecurityAccess accessElement = null;

    synchronized (accessMapSync) {
      if (accessMap == null) {
        accessMap = new HashMap();
      }

      accessMap.clear();
    }
    // Build allow map
    for (Iterator accessIterator = getAccesses().iterator(); accessIterator.hasNext(); ) {
      accessElement = (SecurityAccess) accessIterator.next();

      // Get action map of the action.  Create one if none exists
      String action = accessElement.getAction();

      if (action == null) {
        action = ALL_ACTIONS;
      }

      actionMap = (Map) accessMap.get(action);
      if (actionMap == null) {
        actionMap = new HashMap();
        accessMap.put(action, actionMap);
      }
      addAllows(actionMap, accessElement);
    }
  }
  /**
   * Removes a group role's access to a specific action.
   *
   * @param action Action to remove access from.
   * @param group The group whose access we are revoking.
   * @param role The role whose access we are revoking.
   * @return boolean Whether or not the access existed and was removed.
   */
  public boolean revokeGroupRoleAccess(String action, String group, String role) {
    if (allowsSpecificGroupRole(action, group, role)) {
      SecurityAccess access = getAccess(action);
      List allows = access.getAllows();
      if (allows == null || allows.isEmpty()) {
        revokeAccess(action);
        return false;
      }

      for (int i = 0; i < allows.size(); i++) {
        BaseSecurityAllow allow = (BaseSecurityAllow) allows.get(i);
        if (allow.getGroup() != null
            && allow.getGroup().equals(group)
            && allow.getRole() != null
            && allow.getRole().equals(role)) {
          allows.remove(i);
          if (allows.isEmpty() && access.getOwnerAllows().isEmpty()) {
            revokeAccess(action);
          }

          return true;
        }
      }
    }
    return false;
  }
 /**
  * Checks whether a group is specifically allowed to access the request action This method ignores
  * the "*" action and is here to play a maintenance role.
  */
 public boolean allowsSpecificGroup(String action, String group) {
   SecurityAccess access = (SecurityAccess) getAccess(action);
   if (access.getAllAllows() != null) {
     Iterator allAllows = access.getAllows().iterator();
     while (allAllows.hasNext()) {
       SecurityAllow allow = (SecurityAllow) allAllows.next();
       if (allow.getGroup() != null && allow.getGroup().equals(group)) {
         return true;
       }
     }
   }
   return false;
 }
  /**
   * Grants access for a specific action to a specific user for this SecurityEntry. This grants
   * specific access ignores "*" action, if it exists.
   *
   * @param String action The action we are granting access to.
   * @param String user The user that will receive access to this action.
   * @return boolean Whether or not the access was granted. Basically, a <code>false</code> means
   *     that this role already has specific access.
   */
  public boolean grantUserAccess(String action, String user) {
    if (!allowsSpecificUser(action, user)) {
      SecurityAccess access = getAccess(action);
      List allows = access.getAllows();
      if (allows == null) {
        allows = new Vector();
      }

      BaseSecurityAllow allow = new BaseSecurityAllow();
      allow.setUser(user);
      allows.add(allow);

      buildAccessMap();

      return true;
    }

    return false;
  }
  /**
   * Grants access for a specific action to a specific group for this SecurityEntry. This grants
   * specific access ignores "*" action, if it exists.
   *
   * @param String action The action we are granting access to.
   * @param String group The group that will receive access to this action.
   * @return boolean Whether or not the access was granted. Basically, a <code>false</code> means
   *     that this group already has specific access.
   */
  public boolean grantGroupAccess(String action, String group) {
    if (!allowsSpecificGroup(action, role)) {
      SecurityAccess access = getAccess(action);
      List allows = access.getAllows();
      if (allows == null) {
        allows = new Vector();
      }

      BaseSecurityAllow allow = new BaseSecurityAllow();
      allow.setGroup(group);
      allows.add(allow);

      buildAccessMap();

      return true;
    }

    return false;
  }
  /**
   * Removes a user's access to a specific action.
   *
   * @param action Action to remove access from.
   * @param role The role whose access we are revoking.
   * @return boolean Whehter or not the access existed and was removed.
   */
  public boolean revokeUserAccess(String action, String user) {
    if (allowsSpecificUser(action, user)) {
      SecurityAccess access = getAccess(action);
      List allows = access.getAllows();
      if (allows == null || allows.isEmpty()) {
        revokeAccess(action);
        return false;
      }

      for (int i = 0; i < allows.size(); i++) {
        BaseSecurityAllow allow = (BaseSecurityAllow) allows.get(i);
        if (allow.getUser() != null && allow.getUser().equals(user)) {
          allows.remove(i);
          if (allows.isEmpty() && access.getOwnerAllows().isEmpty()) {
            revokeAccess(action);
          }

          return true;
        }
      }
    }
    return false;
  }
  /**
   * Add access elements to the access map. The elements will be appened to the appropiate map.
   *
   * @param accessMap to receive accessElements
   * @param accessElement to copy to access map
   */
  private void addAllows(Map accessMap, SecurityAccess accessElement) {
    SecurityAllow allowElement = null;
    String role = null;
    String group = null;
    Map ownerMap = null; // Map of owner allowed
    Map roleMap = null; // Map of roles allowed
    Map groupMap = null; // Map of groups allowed
    Map groupRoleMap = null; // Map of group role allowed	
    Map userMap = null; // Map of users allowed
    String userName = null;

    if (accessElement.getAllAllows() == null) {
      return;
    }

    // Add allows to the action Map
    for (Iterator allowIterator = accessElement.getAllAllows().iterator();
        allowIterator.hasNext(); ) {
      allowElement = (SecurityAllow) allowIterator.next();
      role = null;
      userName = null;
      group = null;

      // Add Owner
      if (allowElement.isOwner() == true) {
        ownerMap = (Map) accessMap.get(OWNER_MAP);
        if (ownerMap == null) {
          ownerMap = new HashMap();
          accessMap.put(OWNER_MAP, ownerMap);
        }
        ownerMap.put(null, null);
      }

      // Add Role
      role = allowElement.getRole();
      if (role != null) {
        // Role map
        roleMap = (Map) accessMap.get(ROLE_MAP);
        if (roleMap == null) {
          roleMap = new HashMap();
          accessMap.put(ROLE_MAP, roleMap);
        }
        roleMap.put(role, null);

        // Group role map
        groupRoleMap = (Map) accessMap.get(GROUP_ROLE_MAP);
        if (groupRoleMap == null) {
          groupRoleMap = new HashMap();
          accessMap.put(GROUP_ROLE_MAP, groupRoleMap);
        }
        if (group == null) {
          group = GroupManagement.DEFAULT_GROUP_NAME;
        }
        groupRoleMap.put(group + role, null);
      }

      // Add Group
      group = allowElement.getGroup();
      if (group != null) {
        // Group map
        groupMap = (Map) accessMap.get(GROUP_MAP);
        if (groupMap == null) {
          groupMap = new HashMap();
          accessMap.put(GROUP_MAP, groupMap);
        }
        groupMap.put(group, null);

        // Group role map
        groupRoleMap = (Map) accessMap.get(GROUP_ROLE_MAP);
        if (groupRoleMap == null) {
          groupRoleMap = new HashMap();
          accessMap.put(GROUP_ROLE_MAP, groupRoleMap);
        }
        if (role == null) {
          role = RoleManagement.DEFAULT_ROLE_NAME;
        }
        groupRoleMap.put(group + role, null);
      }

      // Add User
      userName = allowElement.getUser();
      if (userName != null) {
        userMap = (Map) accessMap.get(USER_MAP);
        if (userMap == null) {
          userMap = new HashMap();
          accessMap.put(USER_MAP, userMap);
        }
        userMap.put(userName, null);
      }
    }
  }